113 lines
2.9 KiB
TypeScript
113 lines
2.9 KiB
TypeScript
import { initialState } from '@/mastodon/initial_state';
|
|
|
|
import { toSupportedLocale } from './locale';
|
|
import { reloadCustomEmojis } from './picker';
|
|
import type { EmojiWorkerMessage } from './types';
|
|
import { emojiLogger } from './utils';
|
|
|
|
const userLocale = toSupportedLocale(initialState?.meta.locale ?? 'en');
|
|
|
|
let worker: Worker | null = null;
|
|
|
|
const log = emojiLogger('index');
|
|
const workerLog = emojiLogger('worker');
|
|
|
|
// This is too short, but better to fallback quickly than wait.
|
|
const WORKER_TIMEOUT = 2_000;
|
|
|
|
export async function initializeEmoji() {
|
|
log('initializing emojis');
|
|
|
|
// Create a temp worker, and assign it to the module-level worker once we know it's ready.
|
|
let tempWorker: Worker | null = null;
|
|
if (!worker && 'Worker' in window) {
|
|
try {
|
|
const { default: EmojiWorker } = await import('./worker?worker&inline');
|
|
tempWorker = new EmojiWorker();
|
|
} catch (err) {
|
|
console.warn('Error creating web worker:', err);
|
|
}
|
|
}
|
|
|
|
if (!tempWorker) {
|
|
void fallbackLoad();
|
|
return;
|
|
}
|
|
|
|
const timeoutId = setTimeout(() => {
|
|
log('worker is not ready after timeout');
|
|
void fallbackLoad();
|
|
}, WORKER_TIMEOUT);
|
|
|
|
tempWorker.addEventListener('message', (event: MessageEvent<string>) => {
|
|
const { data: message } = event;
|
|
|
|
worker ??= tempWorker;
|
|
clearTimeout(timeoutId);
|
|
|
|
if (message !== 'ready') {
|
|
workerLog(message);
|
|
return;
|
|
}
|
|
|
|
const debugValue = localStorage.getItem('debug');
|
|
if (debugValue) {
|
|
messageWorker({ type: 'debug', debugValue });
|
|
}
|
|
|
|
workerLog('loading data');
|
|
messageWorker(userLocale);
|
|
messageWorker('custom');
|
|
messageWorker('shortcodes');
|
|
});
|
|
}
|
|
|
|
async function fallbackLoad() {
|
|
log('falling back to main thread for loading');
|
|
|
|
const { importCustomEmojiData, importLegacyShortcodes, importEmojiData } =
|
|
await import('./loader');
|
|
|
|
const customEmojis = await importCustomEmojiData();
|
|
if (customEmojis && customEmojis.length > 0) {
|
|
log('loaded %d custom emojis', customEmojis.length);
|
|
await reloadCustomEmojis();
|
|
}
|
|
const shortcodes = await importLegacyShortcodes();
|
|
if (shortcodes?.length) {
|
|
log('loaded %d legacy shortcodes', shortcodes.length);
|
|
}
|
|
|
|
const emojis = await importEmojiData(userLocale);
|
|
if (emojis) {
|
|
log('loaded %d emojis to locale %s', emojis.length, userLocale);
|
|
}
|
|
}
|
|
|
|
export async function loadCustomEmoji() {
|
|
if (worker) {
|
|
messageWorker('custom');
|
|
} else {
|
|
const { importCustomEmojiData } = await import('./loader');
|
|
const emojis = await importCustomEmojiData();
|
|
if (emojis && emojis.length > 0) {
|
|
log('loaded %d custom emojis', emojis.length);
|
|
await reloadCustomEmojis();
|
|
}
|
|
}
|
|
}
|
|
|
|
function messageWorker(data: EmojiWorkerMessage | string) {
|
|
if (!worker) {
|
|
return;
|
|
}
|
|
if (typeof data === 'string') {
|
|
worker.postMessage({
|
|
type: 'load',
|
|
storeName: data,
|
|
} satisfies EmojiWorkerMessage);
|
|
} else {
|
|
worker.postMessage(data);
|
|
}
|
|
}
|