about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/actions/compose.js
diff options
context:
space:
mode:
authorThibaut Girka <thib@sitedethib.com>2018-08-28 13:52:18 +0200
committerThibG <thib@sitedethib.com>2018-08-28 19:52:28 +0200
commit24b6811a6ed5c3449b6fd82dc30e5b988b76df99 (patch)
tree179f94e6176d413bc25c976ebe0b5bc4d187cb25 /app/javascript/flavours/glitch/actions/compose.js
parente3246cd13b6ee034f5c8e969828332dc9312d449 (diff)
[Glitch] Implement tag auto-completion by history
Port 460e380d386367b6809d319859e13d17a6a2acea to glitch-soc
Diffstat (limited to 'app/javascript/flavours/glitch/actions/compose.js')
-rw-r--r--app/javascript/flavours/glitch/actions/compose.js74
1 files changed, 68 insertions, 6 deletions
diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js
index f6c8086fe..b9248169f 100644
--- a/app/javascript/flavours/glitch/actions/compose.js
+++ b/app/javascript/flavours/glitch/actions/compose.js
@@ -3,6 +3,7 @@ import { CancelToken } from 'axios';
 import { throttle } from 'lodash';
 import { search as emojiSearch } from 'flavours/glitch/util/emoji/emoji_mart_search_light';
 import { useEmoji } from './emojis';
+import { tagHistory } from 'flavours/glitch/util/settings';
 import resizeImage from 'flavours/glitch/util/resize_image';
 
 import { updateTimeline } from './timelines';
@@ -28,6 +29,9 @@ export const COMPOSE_UPLOAD_UNDO     = 'COMPOSE_UPLOAD_UNDO';
 export const COMPOSE_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR';
 export const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY';
 export const COMPOSE_SUGGESTION_SELECT = 'COMPOSE_SUGGESTION_SELECT';
+export const COMPOSE_SUGGESTION_TAGS_UPDATE = 'COMPOSE_SUGGESTION_TAGS_UPDATE';
+
+export const COMPOSE_TAG_HISTORY_UPDATE = 'COMPOSE_TAG_HISTORY_UPDATE';
 
 export const COMPOSE_MOUNT   = 'COMPOSE_MOUNT';
 export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT';
@@ -136,6 +140,7 @@ export function submitCompose() {
         'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']),
       },
     }).then(function (response) {
+      dispatch(insertIntoTagHistory(response.data.tags));
       dispatch(submitComposeSuccess({ ...response.data }));
 
       //  If the response has no data then we can't do anything else.
@@ -315,12 +320,22 @@ const fetchComposeSuggestionsEmojis = (dispatch, getState, token) => {
   dispatch(readyComposeSuggestionsEmojis(token, results));
 };
 
+const fetchComposeSuggestionsTags = (dispatch, getState, token) => {
+  dispatch(updateSuggestionTags(token));
+};
+
 export function fetchComposeSuggestions(token) {
   return (dispatch, getState) => {
-    if (token[0] === ':') {
+    switch (token[0]) {
+    case ':':
       fetchComposeSuggestionsEmojis(dispatch, getState, token);
-    } else {
+      break;
+    case '#':
+      fetchComposeSuggestionsTags(dispatch, getState, token);
+      break;
+    default:
       fetchComposeSuggestionsAccounts(dispatch, getState, token);
+      break;
     }
   };
 };
@@ -343,10 +358,15 @@ export function readyComposeSuggestionsAccounts(token, accounts) {
 
 export function selectComposeSuggestion(position, token, suggestion) {
   return (dispatch, getState) => {
-    const completion = typeof suggestion === 'object' && suggestion.id ? (
-      dispatch(useEmoji(suggestion)),
-      suggestion.native || suggestion.colons
-    ) : '@' + getState().getIn(['accounts', suggestion, 'acct']);
+    let completion;
+    if (typeof suggestion === 'object' && suggestion.id) {
+      dispatch(useEmoji(suggestion));
+      completion = suggestion.native || suggestion.colons;
+    } else if (suggestion[0] === '#') {
+      completion = suggestion;
+    } else {
+      completion = '@' + getState().getIn(['accounts', suggestion, 'acct']);
+    }
 
     dispatch({
       type: COMPOSE_SUGGESTION_SELECT,
@@ -357,6 +377,48 @@ export function selectComposeSuggestion(position, token, suggestion) {
   };
 };
 
+export function updateSuggestionTags(token) {
+  return {
+    type: COMPOSE_SUGGESTION_TAGS_UPDATE,
+    token,
+  };
+}
+
+export function updateTagHistory(tags) {
+  return {
+    type: COMPOSE_TAG_HISTORY_UPDATE,
+    tags,
+  };
+}
+
+export function hydrateCompose() {
+  return (dispatch, getState) => {
+    const me = getState().getIn(['meta', 'me']);
+    const history = tagHistory.get(me);
+
+    if (history !== null) {
+      dispatch(updateTagHistory(history));
+    }
+  };
+}
+
+function insertIntoTagHistory(tags) {
+  return (dispatch, getState) => {
+    const state = getState();
+    const oldHistory = state.getIn(['compose', 'tagHistory']);
+    const me = state.getIn(['meta', 'me']);
+    const names = tags.map(({ name }) => name);
+    const intersectedOldHistory = oldHistory.filter(name => !names.includes(name));
+
+    names.push(...intersectedOldHistory.toJS());
+
+    const newHistory = names.slice(0, 1000);
+
+    tagHistory.set(me, newHistory);
+    dispatch(updateTagHistory(newHistory));
+  };
+}
+
 export function mountCompose() {
   return {
     type: COMPOSE_MOUNT,