[Glitch] Cancel emoji search requests
Port dca7bc42d25a55351c14861ea9c68229aaf54397 to glitch-soc Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
parent
52eceb8168
commit
a3eb0b0d9d
@ -20,6 +20,8 @@ import { updateTimeline } from './timelines';
|
|||||||
let fetchComposeSuggestionsAccountsController;
|
let fetchComposeSuggestionsAccountsController;
|
||||||
/** @type {AbortController | undefined} */
|
/** @type {AbortController | undefined} */
|
||||||
let fetchComposeSuggestionsTagsController;
|
let fetchComposeSuggestionsTagsController;
|
||||||
|
/** @type {AbortController | undefined} */
|
||||||
|
let searchComposeSuggestionsEmojiController;
|
||||||
|
|
||||||
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
|
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
|
||||||
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
|
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
|
||||||
@ -531,9 +533,8 @@ export function undoUploadCompose(media_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function clearComposeSuggestions() {
|
export function clearComposeSuggestions() {
|
||||||
if (fetchComposeSuggestionsAccountsController) {
|
fetchComposeSuggestionsAccountsController?.abort();
|
||||||
fetchComposeSuggestionsAccountsController.abort();
|
searchComposeSuggestionsEmojiController?.abort();
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SUGGESTIONS_CLEAR,
|
type: COMPOSE_SUGGESTIONS_CLEAR,
|
||||||
};
|
};
|
||||||
@ -566,12 +567,25 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, token) => {
|
|||||||
});
|
});
|
||||||
}, 200, { leading: true, trailing: true });
|
}, 200, { leading: true, trailing: true });
|
||||||
|
|
||||||
const fetchComposeSuggestionsEmojis = async (dispatch, token) => {
|
const fetchComposeSuggestionsEmojis = (dispatch, token) => {
|
||||||
// Right now we are hard-coding the locale to English since the picker search only supports English.
|
dispatch(clearComposeSuggestions());
|
||||||
// Once we replace the legacy picker we can remove this and use the actual locale of the user.
|
searchComposeSuggestionsEmojiController = new AbortController();
|
||||||
const results = await emojiMartSearch(token, 'en', 5);
|
|
||||||
dispatch(readyComposeSuggestionsEmojis(token, results));
|
void emojiMartSearch({
|
||||||
};
|
token,
|
||||||
|
// Right now we are hard-coding the locale to English since the picker search only supports English.
|
||||||
|
// Once we replace the legacy picker we can remove this and use the actual locale of the user.
|
||||||
|
locale: 'en',
|
||||||
|
limit: 5,
|
||||||
|
signal: searchComposeSuggestionsEmojiController.signal,
|
||||||
|
}).then((results) => {
|
||||||
|
if (results) {
|
||||||
|
dispatch(readyComposeSuggestionsEmojis(token, results));
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
searchComposeSuggestionsEmojiController = undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const fetchComposeSuggestionsTags = throttle((dispatch, token) => {
|
const fetchComposeSuggestionsTags = throttle((dispatch, token) => {
|
||||||
if (fetchComposeSuggestionsTagsController) {
|
if (fetchComposeSuggestionsTagsController) {
|
||||||
|
|||||||
@ -22,34 +22,50 @@ type LegacyEmoji =
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Replicates the old legacy search function.
|
// Replicates the old legacy search function.
|
||||||
export async function emojiMartSearch(
|
export async function emojiMartSearch({
|
||||||
token: string,
|
token,
|
||||||
locale: string,
|
locale,
|
||||||
limit = 5,
|
limit = 5,
|
||||||
): Promise<LegacyEmoji[]> {
|
signal,
|
||||||
const query = token.replace(':', '').trim();
|
}: {
|
||||||
if (!query.length) {
|
token: string;
|
||||||
return [];
|
locale: string;
|
||||||
|
limit?: number;
|
||||||
|
signal?: AbortSignal;
|
||||||
|
}): Promise<LegacyEmoji[] | null> {
|
||||||
|
try {
|
||||||
|
const query = token.replace(':', '').trim();
|
||||||
|
if (!query.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheKey = `${query}|${locale}|${limit}`;
|
||||||
|
const cachedResult = searchCache.get(cacheKey);
|
||||||
|
if (cachedResult) {
|
||||||
|
return cachedResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = await search({
|
||||||
|
query,
|
||||||
|
locale,
|
||||||
|
limit,
|
||||||
|
signal,
|
||||||
|
});
|
||||||
|
const legacyResults = results.map((emoji) =>
|
||||||
|
'shortcode' in emoji
|
||||||
|
? ({ id: emoji.shortcode, custom: true } as const)
|
||||||
|
: {
|
||||||
|
id: emoji.label.replaceAll(' ', '_').toLowerCase(),
|
||||||
|
native: emoji.unicode,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
searchCache.set(cacheKey, legacyResults);
|
||||||
|
|
||||||
|
return legacyResults;
|
||||||
|
} catch {
|
||||||
|
log('aborted search for "%s"', token);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cacheKey = `${query}|${locale}|${limit}`;
|
|
||||||
const cachedResult = searchCache.get(cacheKey);
|
|
||||||
if (cachedResult) {
|
|
||||||
return cachedResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
const results = await search({ query, locale, limit });
|
|
||||||
const legacyResults = results.map((emoji) =>
|
|
||||||
'shortcode' in emoji
|
|
||||||
? ({ id: emoji.shortcode, custom: true } as const)
|
|
||||||
: {
|
|
||||||
id: emoji.label.replaceAll(' ', '_').toLowerCase(),
|
|
||||||
native: emoji.unicode,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
searchCache.set(cacheKey, legacyResults);
|
|
||||||
|
|
||||||
return legacyResults;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultCategories = [
|
const defaultCategories = [
|
||||||
|
|||||||
@ -56,13 +56,18 @@ export async function search({
|
|||||||
query: rawQuery,
|
query: rawQuery,
|
||||||
locale: localeString,
|
locale: localeString,
|
||||||
limit = 0,
|
limit = 0,
|
||||||
|
signal,
|
||||||
}: {
|
}: {
|
||||||
query: string;
|
query: string;
|
||||||
locale: string;
|
locale: string;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
|
signal?: AbortSignal;
|
||||||
}) {
|
}) {
|
||||||
|
log('searching for "%s"', rawQuery);
|
||||||
performance.mark('emoji-search-start');
|
performance.mark('emoji-search-start');
|
||||||
|
|
||||||
|
signal?.throwIfAborted();
|
||||||
|
|
||||||
// Get the locale, and extract tokens from the query.
|
// Get the locale, and extract tokens from the query.
|
||||||
const locale = toSupportedLocale(localeString);
|
const locale = toSupportedLocale(localeString);
|
||||||
const segmenter = localeToSegmenter(locale);
|
const segmenter = localeToSegmenter(locale);
|
||||||
@ -93,6 +98,7 @@ export async function search({
|
|||||||
locale,
|
locale,
|
||||||
i === queryTokens.length - 1,
|
i === queryTokens.length - 1,
|
||||||
);
|
);
|
||||||
|
signal?.throwIfAborted();
|
||||||
const resultMap: ScoreMap = new Map();
|
const resultMap: ScoreMap = new Map();
|
||||||
const checkedSet = new Set<string>();
|
const checkedSet = new Set<string>();
|
||||||
|
|
||||||
@ -121,6 +127,7 @@ export async function search({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Score based on legacy shortcodes, using the higher score if there's a match.
|
// Score based on legacy shortcodes, using the higher score if there's a match.
|
||||||
|
signal?.throwIfAborted();
|
||||||
for (const shortcodeResult of shortcodeResults) {
|
for (const shortcodeResult of shortcodeResults) {
|
||||||
const emoji =
|
const emoji =
|
||||||
resultMap.get(shortcodeResult.hexcode) ??
|
resultMap.get(shortcodeResult.hexcode) ??
|
||||||
@ -183,7 +190,9 @@ export async function search({
|
|||||||
|
|
||||||
// If there are no results, try a cursor-based custom emoji search instead.
|
// If there are no results, try a cursor-based custom emoji search instead.
|
||||||
if (mixedResults.length === 0 || mixedResults.length < limit) {
|
if (mixedResults.length === 0 || mixedResults.length < limit) {
|
||||||
|
signal?.throwIfAborted();
|
||||||
const customEmojisFound = await fullCustomSearch(query, allEmojiIds);
|
const customEmojisFound = await fullCustomSearch(query, allEmojiIds);
|
||||||
|
signal?.throwIfAborted();
|
||||||
if (customEmojisFound.length > 0) {
|
if (customEmojisFound.length > 0) {
|
||||||
log(
|
log(
|
||||||
'cursor search found %d results for "%s"',
|
'cursor search found %d results for "%s"',
|
||||||
@ -373,6 +382,8 @@ async function fullCustomSearch(query: string, existing = new Set<string>()) {
|
|||||||
|
|
||||||
// First iterate over chunks of 1,000 custom emoji keys and find any matches.
|
// First iterate over chunks of 1,000 custom emoji keys and find any matches.
|
||||||
const chunkSize = 1_000;
|
const chunkSize = 1_000;
|
||||||
|
const maxIterations = 10;
|
||||||
|
let index = 0;
|
||||||
let lastKey: string | null = null;
|
let lastKey: string | null = null;
|
||||||
let keys: string[] = [];
|
let keys: string[] = [];
|
||||||
do {
|
do {
|
||||||
@ -389,6 +400,10 @@ async function fullCustomSearch(query: string, existing = new Set<string>()) {
|
|||||||
foundEmojis.add(key);
|
foundEmojis.add(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
index++;
|
||||||
|
if (index >= maxIterations) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
} while (keys.length === chunkSize);
|
} while (keys.length === chunkSize);
|
||||||
|
|
||||||
// Next get the full emojis for all matches.
|
// Next get the full emojis for all matches.
|
||||||
|
|||||||
@ -518,7 +518,7 @@ body > [data-popper-placement] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.autosuggest-account .account__avatar,
|
.autosuggest-account .account__avatar,
|
||||||
.autosuggest-emoji img {
|
.autosuggest-emoji .emojione {
|
||||||
display: block;
|
display: block;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user