import api from '../api';
import { throttle } from 'lodash';
import { search as emojiSearch } from '../features/emoji/emoji_mart_search_light';
+import { tagHistory } from '../settings';
import { useEmoji } from './emojis';
import {
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';
'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']),
},
}).then(function (response) {
+ dispatch(insertIntoTagHistory(response.data.tags));
dispatch(submitComposeSuccess({ ...response.data }));
// To make the app more responsive, immediately get the status into the columns
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;
}
};
};
startPosition = position - 1;
dispatch(useEmoji(suggestion));
+ } else if (suggestion[0] === '#') {
+ completion = suggestion;
+ startPosition = position - 1;
} else {
completion = getState().getIn(['accounts', suggestion, 'acct']);
startPosition = position;
};
};
+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,
COMPOSE_SUGGESTIONS_CLEAR,
COMPOSE_SUGGESTIONS_READY,
COMPOSE_SUGGESTION_SELECT,
+ COMPOSE_SUGGESTION_TAGS_UPDATE,
+ COMPOSE_TAG_HISTORY_UPDATE,
COMPOSE_SENSITIVITY_CHANGE,
COMPOSE_SPOILERNESS_CHANGE,
COMPOSE_SPOILER_TEXT_CHANGE,
default_sensitive: false,
resetFileKey: Math.floor((Math.random() * 0x10000)),
idempotencyKey: null,
+ tagHistory: ImmutableList(),
});
function statusToTextMentions(state, status) {
});
};
+const updateSuggestionTags = (state, token) => {
+ const prefix = token.slice(1);
+
+ return state.merge({
+ suggestions: state.get('tagHistory')
+ .filter(tag => tag.startsWith(prefix))
+ .slice(0, 4)
+ .map(tag => '#' + tag),
+ suggestion_token: token,
+ });
+};
+
const insertEmoji = (state, position, emojiData) => {
const emoji = emojiData.native;
return state.set('suggestions', ImmutableList(action.accounts ? action.accounts.map(item => item.id) : action.emojis)).set('suggestion_token', action.token);
case COMPOSE_SUGGESTION_SELECT:
return insertSuggestion(state, action.position, action.token, action.completion);
+ case COMPOSE_SUGGESTION_TAGS_UPDATE:
+ return updateSuggestionTags(state, action.token);
+ case COMPOSE_TAG_HISTORY_UPDATE:
+ return state.set('tagHistory', fromJS(action.tags));
case TIMELINE_DELETE:
if (action.id === state.get('in_reply_to')) {
return state.set('in_reply_to', null);