diff --git a/src/components/compose.jsx b/src/components/compose.jsx index cf4372c1..8cae9ee9 100644 --- a/src/components/compose.jsx +++ b/src/components/compose.jsx @@ -16,7 +16,7 @@ import { } from 'preact/hooks'; import { useHotkeys } from 'react-hotkeys-hook'; import stringLength from 'string-length'; -import { detectAll } from 'tinyld/light'; +// import { detectAll } from 'tinyld/light'; import { uid } from 'uid/single'; import { useDebouncedCallback, useThrottledCallback } from 'use-debounce'; import { useSnapshot } from 'valtio'; @@ -1169,11 +1169,12 @@ function Compose({ - {(supports('@pleroma/local-visibility-post') || supports('@akkoma/local-visibility-post')) && + {(supports('@pleroma/local-visibility-post') || + supports('@akkoma/local-visibility-post')) && ( - } + )} @@ -1673,7 +1674,8 @@ const getCustomEmojis = pmem(_getCustomEmojis, { maxAge: 30 * 60 * 1000, // 30 minutes }); -const detectLangs = (text) => { +const detectLangs = async (text) => { + const { detectAll } = await import('tinyld/light'); const langs = detectAll(text); if (langs?.length) { // return max 2 @@ -1963,13 +1965,15 @@ const Textarea = forwardRef((props, ref) => { }); const text = dom.innerText?.trim(); if (!text) return; - const langs = detectLangs(text); - if (langs?.length) { - onTrigger?.({ - name: 'auto-detect-language', - languages: langs, - }); - } + (async () => { + const langs = await detectLangs(text); + if (langs?.length) { + onTrigger?.({ + name: 'auto-detect-language', + languages: langs, + }); + } + })(); }, 2000); return ( diff --git a/src/components/relative-time.jsx b/src/components/relative-time.jsx index 9308c643..8ab9f646 100644 --- a/src/components/relative-time.jsx +++ b/src/components/relative-time.jsx @@ -14,10 +14,12 @@ function isValidDate(value) { } } -const resolvedLocale = new Intl.DateTimeFormat().resolvedOptions().locale; +const resolvedLocale = mem( + () => new Intl.DateTimeFormat().resolvedOptions().locale, +); const DTF = mem((locale, opts = {}) => { const regionlessLocale = locale.replace(/-[a-z]+$/i, ''); - const lang = localeMatch([regionlessLocale], [resolvedLocale], locale); + const lang = localeMatch([regionlessLocale], [resolvedLocale()], locale); try { return new Intl.DateTimeFormat(lang, opts); } catch (e) {} diff --git a/src/components/status.jsx b/src/components/status.jsx index 44eff006..846603b3 100644 --- a/src/components/status.jsx +++ b/src/components/status.jsx @@ -26,7 +26,7 @@ import { } from 'preact/hooks'; import punycode from 'punycode/'; import { useHotkeys } from 'react-hotkeys-hook'; -import { detectAll } from 'tinyld/light'; +// import { detectAll } from 'tinyld/light'; import { useLongPress } from 'use-long-press'; import { useSnapshot } from 'valtio'; @@ -51,7 +51,6 @@ import htmlContentLength from '../utils/html-content-length'; import isRTL from '../utils/is-rtl'; import isMastodonLinkMaybe from '../utils/isMastodonLinkMaybe'; import localeMatch from '../utils/locale-match'; -import mem from '../utils/mem'; import niceDateTime from '../utils/nice-date-time'; import openCompose from '../utils/open-compose'; import pmem from '../utils/pmem'; @@ -168,7 +167,8 @@ const SIZE_CLASS = { l: 'large', }; -const detectLang = mem((text) => { +const detectLang = pmem(async (text) => { + const { detectAll } = await import('tinyld/light'); text = text?.trim(); // Ref: https://github.com/komodojp/tinyld/blob/develop/docs/benchmark.md @@ -304,8 +304,8 @@ function Status({ if (!content) return; if (_language) return; let timer; - timer = setTimeout(() => { - let detected = detectLang( + timer = setTimeout(async () => { + let detected = await detectLang( getHTMLText(content, { preProcess: (dom) => { // Remove anything that can skew the language detection diff --git a/src/locales/en.po b/src/locales/en.po index c2b169e3..f7b0b492 100644 --- a/src/locales/en.po +++ b/src/locales/en.po @@ -105,7 +105,7 @@ msgstr "" #: src/components/account-info.jsx:427 #: src/components/account-info.jsx:1115 -#: src/components/compose.jsx:2459 +#: src/components/compose.jsx:2463 #: src/components/media-alt-modal.jsx:45 #: src/components/media-modal.jsx:283 #: src/components/status.jsx:1636 @@ -401,10 +401,10 @@ msgstr "" #: src/components/account-info.jsx:2089 #: src/components/account-sheet.jsx:37 #: src/components/compose.jsx:797 -#: src/components/compose.jsx:2415 -#: src/components/compose.jsx:2888 -#: src/components/compose.jsx:3096 -#: src/components/compose.jsx:3326 +#: src/components/compose.jsx:2419 +#: src/components/compose.jsx:2892 +#: src/components/compose.jsx:3100 +#: src/components/compose.jsx:3330 #: src/components/drafts.jsx:58 #: src/components/embed-modal.jsx:12 #: src/components/generic-accounts.jsx:142 @@ -547,8 +547,8 @@ msgstr "" #: src/components/compose.jsx:614 #: src/components/compose.jsx:630 -#: src/components/compose.jsx:1336 -#: src/components/compose.jsx:1597 +#: src/components/compose.jsx:1337 +#: src/components/compose.jsx:1598 msgid "{maxMediaAttachments, plural, one {You can only attach up to 1 file.} other {You can only attach up to # files.}}" msgstr "" @@ -615,61 +615,61 @@ msgid "Content warning or sensitive media" msgstr "" #: src/components/compose.jsx:1170 -#: src/components/status.jsx:93 +#: src/components/status.jsx:92 #: src/pages/settings.jsx:297 msgid "Public" msgstr "" -#: src/components/compose.jsx:1174 +#: src/components/compose.jsx:1175 #: src/components/nav-menu.jsx:386 #: src/components/shortcuts-settings.jsx:162 -#: src/components/status.jsx:94 +#: src/components/status.jsx:93 msgid "Local" msgstr "" -#: src/components/compose.jsx:1178 -#: src/components/status.jsx:95 +#: src/components/compose.jsx:1179 +#: src/components/status.jsx:94 #: src/pages/settings.jsx:300 msgid "Unlisted" msgstr "" -#: src/components/compose.jsx:1181 -#: src/components/status.jsx:96 +#: src/components/compose.jsx:1182 +#: src/components/status.jsx:95 #: src/pages/settings.jsx:303 msgid "Followers only" msgstr "" -#: src/components/compose.jsx:1184 -#: src/components/status.jsx:97 +#: src/components/compose.jsx:1185 +#: src/components/status.jsx:96 #: src/components/status.jsx:1840 msgid "Private mention" msgstr "" -#: src/components/compose.jsx:1193 +#: src/components/compose.jsx:1194 msgid "Post your reply" msgstr "" -#: src/components/compose.jsx:1195 +#: src/components/compose.jsx:1196 msgid "Edit your post" msgstr "" -#: src/components/compose.jsx:1196 +#: src/components/compose.jsx:1197 msgid "What are you doing?" msgstr "" -#: src/components/compose.jsx:1274 +#: src/components/compose.jsx:1275 msgid "Mark media as sensitive" msgstr "" -#: src/components/compose.jsx:1372 +#: src/components/compose.jsx:1373 msgid "Add poll" msgstr "" -#: src/components/compose.jsx:1394 +#: src/components/compose.jsx:1395 msgid "Add custom emoji" msgstr "" -#: src/components/compose.jsx:1478 +#: src/components/compose.jsx:1479 #: src/components/keyboard-shortcuts-help.jsx:143 #: src/components/status.jsx:831 #: src/components/status.jsx:1616 @@ -678,195 +678,195 @@ msgstr "" msgid "Reply" msgstr "" -#: src/components/compose.jsx:1480 +#: src/components/compose.jsx:1481 msgid "Update" msgstr "" -#: src/components/compose.jsx:1481 +#: src/components/compose.jsx:1482 msgctxt "Submit button in composer" msgid "Post" msgstr "" -#: src/components/compose.jsx:1609 +#: src/components/compose.jsx:1610 msgid "Downloading GIF…" msgstr "" -#: src/components/compose.jsx:1637 +#: src/components/compose.jsx:1638 msgid "Failed to download GIF" msgstr "" -#: src/components/compose.jsx:1748 -#: src/components/compose.jsx:1825 +#: src/components/compose.jsx:1750 +#: src/components/compose.jsx:1827 #: src/components/nav-menu.jsx:287 msgid "More…" msgstr "" -#: src/components/compose.jsx:2228 +#: src/components/compose.jsx:2232 msgid "Uploaded" msgstr "" -#: src/components/compose.jsx:2241 +#: src/components/compose.jsx:2245 msgid "Image description" msgstr "" -#: src/components/compose.jsx:2242 +#: src/components/compose.jsx:2246 msgid "Video description" msgstr "" -#: src/components/compose.jsx:2243 +#: src/components/compose.jsx:2247 msgid "Audio description" msgstr "" -#: src/components/compose.jsx:2279 -#: src/components/compose.jsx:2299 +#: src/components/compose.jsx:2283 +#: src/components/compose.jsx:2303 msgid "File size too large. Uploading might encounter issues. Try reduce the file size from {0} to {1} or lower." msgstr "" -#: src/components/compose.jsx:2291 -#: src/components/compose.jsx:2311 +#: src/components/compose.jsx:2295 +#: src/components/compose.jsx:2315 msgid "Dimension too large. Uploading might encounter issues. Try reduce dimension from {0}×{1}px to {2}×{3}px." msgstr "" -#: src/components/compose.jsx:2319 +#: src/components/compose.jsx:2323 msgid "Frame rate too high. Uploading might encounter issues." msgstr "" -#: src/components/compose.jsx:2379 -#: src/components/compose.jsx:2629 +#: src/components/compose.jsx:2383 +#: src/components/compose.jsx:2633 #: src/components/shortcuts-settings.jsx:723 #: src/pages/catchup.jsx:1074 #: src/pages/filters.jsx:412 msgid "Remove" msgstr "" -#: src/components/compose.jsx:2396 +#: src/components/compose.jsx:2400 #: src/compose.jsx:83 msgid "Error" msgstr "" -#: src/components/compose.jsx:2421 +#: src/components/compose.jsx:2425 msgid "Edit image description" msgstr "" -#: src/components/compose.jsx:2422 +#: src/components/compose.jsx:2426 msgid "Edit video description" msgstr "" -#: src/components/compose.jsx:2423 +#: src/components/compose.jsx:2427 msgid "Edit audio description" msgstr "" -#: src/components/compose.jsx:2468 -#: src/components/compose.jsx:2517 +#: src/components/compose.jsx:2472 +#: src/components/compose.jsx:2521 msgid "Generating description. Please wait…" msgstr "" -#: src/components/compose.jsx:2488 +#: src/components/compose.jsx:2492 msgid "Failed to generate description: {0}" msgstr "" -#: src/components/compose.jsx:2489 +#: src/components/compose.jsx:2493 msgid "Failed to generate description" msgstr "" -#: src/components/compose.jsx:2501 -#: src/components/compose.jsx:2507 -#: src/components/compose.jsx:2553 +#: src/components/compose.jsx:2505 +#: src/components/compose.jsx:2511 +#: src/components/compose.jsx:2557 msgid "Generate description…" msgstr "" -#: src/components/compose.jsx:2540 +#: src/components/compose.jsx:2544 msgid "Failed to generate description{0}" msgstr "" -#: src/components/compose.jsx:2555 +#: src/components/compose.jsx:2559 msgid "({0}) <0>— experimental" msgstr "" -#: src/components/compose.jsx:2574 +#: src/components/compose.jsx:2578 msgid "Done" msgstr "" -#: src/components/compose.jsx:2610 +#: src/components/compose.jsx:2614 msgid "Choice {0}" msgstr "" -#: src/components/compose.jsx:2657 +#: src/components/compose.jsx:2661 msgid "Multiple choices" msgstr "" -#: src/components/compose.jsx:2660 +#: src/components/compose.jsx:2664 msgid "Duration" msgstr "" -#: src/components/compose.jsx:2691 +#: src/components/compose.jsx:2695 msgid "Remove poll" msgstr "" -#: src/components/compose.jsx:2905 +#: src/components/compose.jsx:2909 msgid "Search accounts" msgstr "" -#: src/components/compose.jsx:2946 +#: src/components/compose.jsx:2950 #: src/components/shortcuts-settings.jsx:712 #: src/pages/list.jsx:359 msgid "Add" msgstr "" -#: src/components/compose.jsx:2959 +#: src/components/compose.jsx:2963 #: src/components/generic-accounts.jsx:227 msgid "Error loading accounts" msgstr "" -#: src/components/compose.jsx:3102 +#: src/components/compose.jsx:3106 msgid "Custom emojis" msgstr "" -#: src/components/compose.jsx:3122 +#: src/components/compose.jsx:3126 msgid "Search emoji" msgstr "" -#: src/components/compose.jsx:3153 +#: src/components/compose.jsx:3157 msgid "Error loading custom emojis" msgstr "" -#: src/components/compose.jsx:3164 +#: src/components/compose.jsx:3168 msgid "Recently used" msgstr "" -#: src/components/compose.jsx:3165 +#: src/components/compose.jsx:3169 msgid "Others" msgstr "" -#: src/components/compose.jsx:3203 +#: src/components/compose.jsx:3207 msgid "{0} more…" msgstr "" -#: src/components/compose.jsx:3341 +#: src/components/compose.jsx:3345 msgid "Search GIFs" msgstr "" -#: src/components/compose.jsx:3356 +#: src/components/compose.jsx:3360 msgid "Powered by GIPHY" msgstr "" -#: src/components/compose.jsx:3364 +#: src/components/compose.jsx:3368 msgid "Type to search GIFs" msgstr "" -#: src/components/compose.jsx:3462 +#: src/components/compose.jsx:3466 #: src/components/media-modal.jsx:387 #: src/components/timeline.jsx:889 msgid "Previous" msgstr "" -#: src/components/compose.jsx:3480 +#: src/components/compose.jsx:3484 #: src/components/media-modal.jsx:406 #: src/components/timeline.jsx:906 msgid "Next" msgstr "" -#: src/components/compose.jsx:3497 +#: src/components/compose.jsx:3501 msgid "Error loading GIFs" msgstr "" @@ -1571,17 +1571,17 @@ msgid "Ending" msgstr "" #. Relative time in seconds, as short as possible -#: src/components/relative-time.jsx:55 +#: src/components/relative-time.jsx:57 msgid "{0}s" msgstr "" #. Relative time in minutes, as short as possible -#: src/components/relative-time.jsx:60 +#: src/components/relative-time.jsx:62 msgid "{0}m" msgstr "" #. Relative time in hours, as short as possible -#: src/components/relative-time.jsx:65 +#: src/components/relative-time.jsx:67 msgid "{0}h" msgstr "" diff --git a/src/utils/get-translate-target-language.jsx b/src/utils/get-translate-target-language.jsx index 5dc7e912..cb0c5749 100644 --- a/src/utils/get-translate-target-language.jsx +++ b/src/utils/get-translate-target-language.jsx @@ -1,16 +1,17 @@ import translationTargetLanguages from '../data/lingva-target-languages'; import localeMatch from './locale-match'; +import mem from './mem'; import states from './states'; -const locales = [ +const locales = mem(() => [ new Intl.DateTimeFormat().resolvedOptions().locale, ...navigator.languages, -]; +]); const localeTargetLanguages = () => localeMatch( - locales, + locales(), translationTargetLanguages.map((l) => l.code.replace('_', '-')), // The underscore will fail Intl.Locale inside `match` 'en', ); diff --git a/src/utils/nice-date-time.js b/src/utils/nice-date-time.js index adf81c88..53b5138c 100644 --- a/src/utils/nice-date-time.js +++ b/src/utils/nice-date-time.js @@ -3,7 +3,9 @@ import { i18n } from '@lingui/core'; import localeMatch from './locale-match'; import mem from './mem'; -const defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale; +const defaultLocale = mem( + () => new Intl.DateTimeFormat().resolvedOptions().locale, +); const _DateTimeFormat = (opts) => { const { locale, dateYear, hideTime, formatOpts } = opts || {};