diff options
| -rw-r--r-- | client/Dockerfile | 2 | ||||
| -rw-r--r-- | client/html/tag_input.tpl | 2 | ||||
| -rw-r--r-- | client/js/controls/post_edit_sidebar_control.js | 4 | ||||
| -rw-r--r-- | client/js/controls/tag_input_control.js | 45 |
4 files changed, 50 insertions, 3 deletions
diff --git a/client/Dockerfile b/client/Dockerfile index dbb6659..d7091e3 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -7,7 +7,7 @@ RUN npm install COPY . ./ ARG BUILD_INFO="docker-latest" -ARG CLIENT_BUILD_ARGS="" +ARG CLIENT_BUILD_ARGS="--debug" RUN BASE_URL="__BASEURL__" node build.js --gzip ${CLIENT_BUILD_ARGS} diff --git a/client/html/tag_input.tpl b/client/html/tag_input.tpl index 2666f98..60c8969 100644 --- a/client/html/tag_input.tpl +++ b/client/html/tag_input.tpl @@ -18,4 +18,6 @@ </div> <ul class='compact-tags'></ul> + + <a class='tag-from-lookalikes'>From lookalikes...</a> </div> diff --git a/client/js/controls/post_edit_sidebar_control.js b/client/js/controls/post_edit_sidebar_control.js index c840da8..053a317 100644 --- a/client/js/controls/post_edit_sidebar_control.js +++ b/client/js/controls/post_edit_sidebar_control.js @@ -104,7 +104,9 @@ class PostEditSidebarControl extends events.EventTarget { if (this._tagInputNode) { this._tagControl = new TagInputControl( this._tagInputNode, - this._post.tags + this._post.tags, + null, + this._post, ); } diff --git a/client/js/controls/tag_input_control.js b/client/js/controls/tag_input_control.js index a0c9eee..35bbe9f 100644 --- a/client/js/controls/tag_input_control.js +++ b/client/js/controls/tag_input_control.js @@ -10,6 +10,7 @@ const settings = require("../models/settings.js"); const events = require("../events.js"); const views = require("../util/views.js"); const TagAutoCompleteControl = require("./tag_auto_complete_control.js"); +const PostList = require("../models/post_list.js"); const KEY_SPACE = 32; const KEY_RETURN = 13; @@ -83,9 +84,10 @@ class SuggestionList { } class TagInputControl extends events.EventTarget { - constructor(hostNode, tagList, placeholder) { + constructor(hostNode, tagList, placeholder, post) { super(); this.tags = tagList; + this._post = post; this._hostNode = hostNode; this._suggestions = new SuggestionList(); this._tagToListItemNode = new Map(); @@ -153,6 +155,8 @@ class TagInputControl extends events.EventTarget { const listItemNode = this._createListItemNode(tag); this._tagListNode.appendChild(listItemNode); } + + this._createSuggestionsFromLookalikes(); } addTagByText(text, source) { @@ -349,6 +353,20 @@ class TagInputControl extends events.EventTarget { return listItemNode; } + _createSuggestionsFromLookalikes() { + const node = this._editAreaNode.querySelector("a.tag-from-lookalikes"); + if (this._post === undefined) { + node.style.display = "none"; + } else { + node.addEventListener("click", (e) => { + e.preventDefault(); + this._suggestions.clear(); + this._loadSuggestionsFromLookalikes(); + this._removeSuggestionsPopupOpacity(); + }); + } + } + _deleteListItemNode(tag) { const listItemNode = this._getListItemNode(tag); if (listItemNode) { @@ -399,6 +417,31 @@ class TagInputControl extends events.EventTarget { }); } + _loadSuggestionsFromLookalikes() { + const limit = 20; + const fields = ["id", "thumbnailUrl", "tags"]; + const threshold = 1; + PostList.reverseSearch(this._post.id, limit, threshold, fields) + .then((response) => { + const tagOccurrences = {}; + for (let post of response.results) { + for (let tag of post.tags) { + const name = tag.names[0]; + let count = tagOccurrences[name] || 0; + tagOccurrences[name] = count + 1; + } + } + for (const [tagName, count] of Object.entries(tagOccurrences)) { + this._suggestions.set(tagName, count); + } + if (this._suggestions.length) { + this._openSuggestionsPopup(); + } else { + this._closeSuggestionsPopup(); + } + }); + } + _refreshSuggestionsPopup() { if (!this._suggestionsNode.classList.contains("shown")) { return; |