[Glitch] Fixes custom emoji not appearing in autocomplete
Port a47ed3104718ce6f69bca2c028b267988a28c26b to glitch-soc Co-authored-by: Copilot <copilot@github.com> Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
parent
e4fba99ab5
commit
1f0fb21039
@ -8,6 +8,7 @@ import { browserHistory } from 'flavours/glitch/components/router';
|
|||||||
import { countableText } from 'flavours/glitch/features/compose/util/counter';
|
import { countableText } from 'flavours/glitch/features/compose/util/counter';
|
||||||
import { search as emojiSearch } from 'flavours/glitch/features/emoji/emoji_mart_search_light';
|
import { search as emojiSearch } from 'flavours/glitch/features/emoji/emoji_mart_search_light';
|
||||||
import { tagHistory } from 'flavours/glitch/settings';
|
import { tagHistory } from 'flavours/glitch/settings';
|
||||||
|
import { fetchCustomEmojiData } from '@/flavours/glitch/features/emoji/picker';
|
||||||
import { recoverHashtags } from 'flavours/glitch/utils/hashtag';
|
import { recoverHashtags } from 'flavours/glitch/utils/hashtag';
|
||||||
|
|
||||||
import { showAlert, showAlertForError } from './alerts';
|
import { showAlert, showAlertForError } from './alerts';
|
||||||
@ -597,7 +598,7 @@ export function clearComposeSuggestions() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) => {
|
const fetchComposeSuggestionsAccounts = throttle((dispatch, token) => {
|
||||||
if (fetchComposeSuggestionsAccountsController) {
|
if (fetchComposeSuggestionsAccountsController) {
|
||||||
fetchComposeSuggestionsAccountsController.abort();
|
fetchComposeSuggestionsAccountsController.abort();
|
||||||
}
|
}
|
||||||
@ -624,12 +625,13 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) =>
|
|||||||
});
|
});
|
||||||
}, 200, { leading: true, trailing: true });
|
}, 200, { leading: true, trailing: true });
|
||||||
|
|
||||||
const fetchComposeSuggestionsEmojis = (dispatch, getState, token) => {
|
const fetchComposeSuggestionsEmojis = async (dispatch, token) => {
|
||||||
const results = emojiSearch(token.replace(':', ''), { maxResults: 5 });
|
const custom = await fetchCustomEmojiData();
|
||||||
|
const results = emojiSearch(token.replace(':', ''), { maxResults: 5, custom });
|
||||||
dispatch(readyComposeSuggestionsEmojis(token, results));
|
dispatch(readyComposeSuggestionsEmojis(token, results));
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchComposeSuggestionsTags = throttle((dispatch, getState, token) => {
|
const fetchComposeSuggestionsTags = throttle((dispatch, token) => {
|
||||||
if (fetchComposeSuggestionsTagsController) {
|
if (fetchComposeSuggestionsTagsController) {
|
||||||
fetchComposeSuggestionsTagsController.abort();
|
fetchComposeSuggestionsTagsController.abort();
|
||||||
}
|
}
|
||||||
@ -662,14 +664,14 @@ export function fetchComposeSuggestions(token) {
|
|||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
switch (token[0]) {
|
switch (token[0]) {
|
||||||
case ':':
|
case ':':
|
||||||
fetchComposeSuggestionsEmojis(dispatch, getState, token);
|
void fetchComposeSuggestionsEmojis(dispatch, token);
|
||||||
break;
|
break;
|
||||||
case '#':
|
case '#':
|
||||||
case '#':
|
case '#':
|
||||||
fetchComposeSuggestionsTags(dispatch, getState, token);
|
fetchComposeSuggestionsTags(dispatch, token);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fetchComposeSuggestionsAccounts(dispatch, getState, token);
|
fetchComposeSuggestionsAccounts(dispatch, token);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,39 +1,19 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
import type {
|
import type { EmojiProps, PickerProps } from 'emoji-mart';
|
||||||
CategoryName,
|
|
||||||
CustomEmoji,
|
|
||||||
EmojiProps,
|
|
||||||
PickerProps,
|
|
||||||
} from 'emoji-mart';
|
|
||||||
import EmojiRaw from 'emoji-mart/dist-es/components/emoji/nimble-emoji';
|
import EmojiRaw from 'emoji-mart/dist-es/components/emoji/nimble-emoji';
|
||||||
import PickerRaw from 'emoji-mart/dist-es/components/picker/nimble-picker';
|
import PickerRaw from 'emoji-mart/dist-es/components/picker/nimble-picker';
|
||||||
|
|
||||||
import { autoPlayGif } from '@/flavours/glitch/initial_state';
|
import { assetHost } from '@/flavours/glitch/utils/config';
|
||||||
import { assetHost } from 'flavours/glitch/utils/config';
|
|
||||||
|
|
||||||
import { EMOJI_MODE_NATIVE } from './constants';
|
import { EMOJI_MODE_NATIVE } from './constants';
|
||||||
import EmojiData from './emoji_data.json';
|
import EmojiData from './emoji_data.json';
|
||||||
import { useEmojiAppState } from './mode';
|
import { useEmojiAppState } from './mode';
|
||||||
import { emojiLogger } from './utils';
|
import { usePickerEmojis } from './picker';
|
||||||
|
|
||||||
const backgroundImageFnDefault = () => `${assetHost}/emoji/sheet_16_0.png`;
|
const backgroundImageFnDefault = () => `${assetHost}/emoji/sheet_16_0.png`;
|
||||||
|
|
||||||
let customEmojis: CustomEmoji[] | null = null;
|
export { fetchCustomEmojiData as loadCustomEmojiData } from './picker';
|
||||||
let customCategories = [
|
|
||||||
'recent',
|
|
||||||
'people',
|
|
||||||
'nature',
|
|
||||||
'foods',
|
|
||||||
'activity',
|
|
||||||
'places',
|
|
||||||
'objects',
|
|
||||||
'symbols',
|
|
||||||
'flags',
|
|
||||||
] as CategoryName[];
|
|
||||||
|
|
||||||
const log = emojiLogger('picker');
|
|
||||||
|
|
||||||
export const Picker: FC<PickerProps> = ({
|
export const Picker: FC<PickerProps> = ({
|
||||||
set = 'twitter',
|
set = 'twitter',
|
||||||
@ -44,24 +24,16 @@ export const Picker: FC<PickerProps> = ({
|
|||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const { mode } = useEmojiAppState();
|
const { mode } = useEmojiAppState();
|
||||||
const [isLoaded, setLoaded] = useState(customEmojis !== null);
|
const { customCategories, customEmojis } = usePickerEmojis();
|
||||||
|
|
||||||
useEffect(() => {
|
if (!customEmojis) {
|
||||||
if (customEmojis === null) {
|
|
||||||
void loadCustomEmojiData().then(() => {
|
|
||||||
setLoaded(true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!isLoaded) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PickerRaw
|
<PickerRaw
|
||||||
data={EmojiData}
|
data={EmojiData}
|
||||||
custom={customEmojis ?? []}
|
custom={customEmojis}
|
||||||
include={customCategories}
|
include={customCategories}
|
||||||
set={set}
|
set={set}
|
||||||
sheetSize={sheetSize}
|
sheetSize={sheetSize}
|
||||||
@ -74,46 +46,6 @@ export const Picker: FC<PickerProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function loadCustomEmojiData() {
|
|
||||||
const { loadAllCustomEmoji } = await import('./database');
|
|
||||||
const emojisRaw = await loadAllCustomEmoji();
|
|
||||||
if (emojisRaw.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const categories = new Set(['custom']);
|
|
||||||
const emojis = [];
|
|
||||||
for (const emoji of emojisRaw) {
|
|
||||||
const name = emoji.shortcode.replaceAll(':', '');
|
|
||||||
emojis.push({
|
|
||||||
name,
|
|
||||||
id: name,
|
|
||||||
custom: true,
|
|
||||||
short_names: [name],
|
|
||||||
imageUrl: autoPlayGif ? emoji.url : emoji.static_url,
|
|
||||||
customCategory: emoji.category,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (emoji.category) {
|
|
||||||
categories.add(`custom-${emoji.category}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customEmojis = emojis.toSorted((a, b) => {
|
|
||||||
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
|
||||||
});
|
|
||||||
customCategories = customCategories.toSpliced(
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
...(Array.from(categories).toSorted() as CategoryName[]),
|
|
||||||
);
|
|
||||||
log(
|
|
||||||
'loaded %d custom emojis in %d categories',
|
|
||||||
customEmojis.length,
|
|
||||||
categories.size,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Emoji: FC<EmojiProps> = ({
|
export const Emoji: FC<EmojiProps> = ({
|
||||||
set = 'twitter',
|
set = 'twitter',
|
||||||
sheetSize = 32,
|
sheetSize = 32,
|
||||||
|
|||||||
85
app/javascript/flavours/glitch/features/emoji/picker.ts
Normal file
85
app/javascript/flavours/glitch/features/emoji/picker.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import type { CategoryName, CustomEmoji } from 'emoji-mart';
|
||||||
|
|
||||||
|
import { autoPlayGif } from '@/flavours/glitch/initial_state';
|
||||||
|
|
||||||
|
import { emojiLogger } from './utils';
|
||||||
|
|
||||||
|
const log = emojiLogger('picker');
|
||||||
|
|
||||||
|
let customEmojis: CustomEmoji[] | null = null;
|
||||||
|
let customCategories = [
|
||||||
|
'recent',
|
||||||
|
'people',
|
||||||
|
'nature',
|
||||||
|
'foods',
|
||||||
|
'activity',
|
||||||
|
'places',
|
||||||
|
'objects',
|
||||||
|
'symbols',
|
||||||
|
'flags',
|
||||||
|
] as CategoryName[];
|
||||||
|
|
||||||
|
export async function fetchCustomEmojiData() {
|
||||||
|
if (customEmojis !== null) {
|
||||||
|
return customEmojis;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { loadAllCustomEmoji } = await import('./database');
|
||||||
|
const emojisRaw = await loadAllCustomEmoji();
|
||||||
|
if (emojisRaw.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const categories = new Set(['custom']);
|
||||||
|
const emojis = [];
|
||||||
|
for (const emoji of emojisRaw) {
|
||||||
|
const name = emoji.shortcode.replaceAll(':', '');
|
||||||
|
emojis.push({
|
||||||
|
name,
|
||||||
|
id: name,
|
||||||
|
custom: true,
|
||||||
|
short_names: [name],
|
||||||
|
imageUrl: autoPlayGif ? emoji.url : emoji.static_url,
|
||||||
|
customCategory: emoji.category,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (emoji.category) {
|
||||||
|
categories.add(`custom-${emoji.category}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customEmojis = emojis.toSorted((a, b) => {
|
||||||
|
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
||||||
|
});
|
||||||
|
customCategories = customCategories.toSpliced(
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
...(Array.from(categories).toSorted() as CategoryName[]),
|
||||||
|
);
|
||||||
|
log(
|
||||||
|
'loaded %d custom emojis in %d categories',
|
||||||
|
customEmojis.length,
|
||||||
|
categories.size,
|
||||||
|
);
|
||||||
|
|
||||||
|
return customEmojis;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function usePickerEmojis() {
|
||||||
|
const [, setLoaded] = useState(customEmojis !== null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (customEmojis === null) {
|
||||||
|
void fetchCustomEmojiData().then(() => {
|
||||||
|
setLoaded(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {
|
||||||
|
customEmojis,
|
||||||
|
customCategories,
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user