summaryrefslogtreecommitdiff
path: root/client/js/controls
diff options
context:
space:
mode:
authorHunternif <hunternif@gmail.com>2022-10-02 04:37:48 +0100
committerHunternif <hunternif@gmail.com>2022-10-02 04:44:46 +0100
commit757d0ee8a6fc54e10d6f7c28d79b927d8eb0382d (patch)
treeab61109254f07d39edc1b0d8c1714d0f0eff5f0c /client/js/controls
parenta82fa8940158784285872434659b5cb7fb9b817a (diff)
client: suggest tags based on lookalike posts
Diffstat (limited to 'client/js/controls')
-rw-r--r--client/js/controls/post_edit_sidebar_control.js4
-rw-r--r--client/js/controls/tag_input_control.js45
2 files changed, 47 insertions, 2 deletions
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;