summaryrefslogtreecommitdiff
path: root/src/stores/i18n.ts
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /src/stores/i18n.ts
init commit
Diffstat (limited to 'src/stores/i18n.ts')
-rw-r--r--src/stores/i18n.ts73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/stores/i18n.ts b/src/stores/i18n.ts
new file mode 100644
index 0000000..740d0b4
--- /dev/null
+++ b/src/stores/i18n.ts
@@ -0,0 +1,73 @@
+import { readable } from 'svelte/store';
+import I18N from '@amp/web-apps-localization';
+import { getContext } from 'svelte';
+import type { Readable } from 'svelte/store';
+import type { Locale, ILocaleJSON } from '@amp/web-apps-localization';
+import type { Logger, LoggerFactory } from '@amp/web-apps-logger';
+import { isEnabled } from '@amp/web-apps-featurekit';
+
+export type { Locale } from '@amp/web-apps-localization';
+
+import { __FF_SHOW_LOC_KEYS } from '~/utils/features/consts';
+
+const CONTEXT_NAME = 'i18n';
+
+export async function setup(
+ context: Map<string, unknown>,
+ loggerFactory: LoggerFactory,
+ locale: Locale,
+): Promise<I18N> {
+ const log = loggerFactory.loggerFor('i18n');
+
+ let alwaysShowScreamers = false;
+ if (isEnabled(__FF_SHOW_LOC_KEYS)) {
+ alwaysShowScreamers = true;
+ }
+
+ const translations = await getTranslations(log, locale);
+ const i18n = new I18N(log, locale, translations, alwaysShowScreamers);
+ const store = readable(i18n);
+
+ context.set(CONTEXT_NAME, store);
+
+ return i18n;
+}
+
+/**
+ * Gets the current i18n store from the Svelte context.
+ *
+ * @return i18n The i18n store
+ */
+export function getI18n(): Readable<I18N> {
+ const i18n = getContext(CONTEXT_NAME) as Readable<I18N> | undefined;
+
+ if (!i18n) {
+ throw new Error('getI18n called before setup');
+ }
+
+ return i18n;
+}
+
+async function getTranslations(
+ log: Logger,
+ locale: Locale,
+): Promise<ILocaleJSON> {
+ try {
+ // TODO: Shoebox logic here
+ const translations = await importLocale(locale);
+ return translations.default;
+ } catch (err) {
+ log.error('failed to load:', err);
+ throw new Error('i18n failed to load');
+ }
+}
+
+interface IDynamicImportJSON {
+ default: ILocaleJSON;
+}
+
+//TODO: rdar://73157638 (Determine if we can use ES modules based on browser matrix)
+// Possibly switch this to fetch instead of dynamic imports?
+function importLocale(locale: Locale): Promise<IDynamicImportJSON> {
+ return import(`../../tmp/locales/${locale}/translations.json`);
+}