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>— experimental0>"
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 || {};