From 24b6811a6ed5c3449b6fd82dc30e5b988b76df99 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 28 Aug 2018 13:52:18 +0200 Subject: [Glitch] Implement tag auto-completion by history Port 460e380d386367b6809d319859e13d17a6a2acea to glitch-soc --- app/javascript/flavours/glitch/actions/compose.js | 74 +++++++++++++++++++++-- 1 file changed, 68 insertions(+), 6 deletions(-) (limited to 'app/javascript/flavours/glitch/actions/compose.js') 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, -- cgit