Skip to content

Commit 488f213

Browse files
committed
WIP: feat: add an option to change UI language
1 parent ee94ce3 commit 488f213

12 files changed

+75
-10
lines changed

Diff for: src/helpers/createGetMessage.ts

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import type { Settings } from '@/settings';
2+
import { getMessageNative } from './getMessageNative';
3+
4+
const browserPolyfill = (typeof browser !== 'undefined' ? browser : chrome);
5+
6+
// TODO make an npm module of this.
7+
8+
// export default function createGetMessage(settings: Pick<Settings, 'language'>): {
9+
// TODO cache (lodash/once)
10+
export async function createGetMessage(overrideLanguage?: ReturnType<typeof browser.i18n.getUILanguage>) {
11+
if (!overrideLanguage) {
12+
return getMessageNative;
13+
}
14+
// TODO but this import call is gonna be processed by Webpack, so it's gonna try to bundle the i18n files twice.
15+
// Use `fetch`?
16+
// const locale = await import(`_locales/${overrideLanguage}`);
17+
// const localeP = import(`_locales/${overrideLanguage}/messages.json`);
18+
const localeP = fetch(browserPolyfill.runtime.getURL(`_locales/${overrideLanguage}/messages.json`));
19+
let locale: { [key: string]: { message: string }};
20+
try {
21+
locale = await (await localeP).json();
22+
} catch (e) {
23+
if (process.env.NODE_ENV !== 'production') {
24+
console.error('Failed to fetch i18n JSON, falling back to default', e);
25+
}
26+
return getMessageNative;
27+
}
28+
29+
// TODO placeholder substitution.
30+
// TODO defaulting to `default_locale`.
31+
32+
// // const transformed = locale
33+
// for (const [key, value] of Object.entries(locale)) {
34+
// // locale[key] = (value as { message: string }).message;
35+
// }
36+
37+
// const transformedEntries = Object.entries(locale).map(([key, value]) => [key, value.message])
38+
// const transformed = Object.fromEntries(transformedEntries);
39+
40+
// return (messageName: string) => locale[mesageName];
41+
return (messageName: string) => locale[messageName].message;
42+
}

Diff for: src/helpers/getMessage.ts

-2
This file was deleted.

Diff for: src/helpers/getMessageNative.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// import browser from '@/webextensions-api';
2+
export const getMessageNative = (typeof browser !== 'undefined' ? browser : chrome).i18n.getMessage;

Diff for: src/helpers/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ export * from './filterOutUnchangedValues';
2929
export * from './speedName';
3030
export * from './getGeckoMajorVersion';
3131
export * from './getGeckoLikelyMaxNonMutedPlaybackRate';
32-
export * from './getMessage';
32+
export * from './getMessageNative';
33+
export * from './createGetMessage';

Diff for: src/hotkeys/hotkeyActionToString.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import { getMessage } from '@/helpers';
1+
import { createGetMessage } from '@/helpers';
22
import { HotkeyAction } from './HotkeyAction';
33

4+
const getMessage = await createGetMessage();
5+
46
export const hotkeyActionToString: Record<HotkeyAction, string> = {
57
// TODO check if emojis are ok with screen readers, though I think they should be.
68

Diff for: src/local-file-player/App.svelte

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<script lang="ts">
22
import { tick, onMount } from 'svelte';
33
// TODO get rid of svelte?
4-
import { getMessage } from '@/helpers';
4+
import { createGetMessage, getMessageNative } from '@/helpers';
5+
6+
let getMessage = getMessageNative;
7+
createGetMessage().then(r => getMessage = r);
58
69
const defaultDocumentTitle = 'Jump Cutter: local video player'; // TODO translate?
710
document.title = defaultDocumentTitle;

Diff for: src/manifest.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
"web_accessible_resources": [
2727
"content/SilenceDetectorProcessor.js",
2828
"content/VolumeFilterProcessor.js",
29-
"chunks/*.js"
29+
"chunks/*.js",
30+
"_locales/*/messages.json"
3031
],
3132
"options_ui": {
3233
"page": "options/index.html",

Diff for: src/options/App.svelte

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
import CheckboxField from './components/CheckboxField.svelte';
66
import NumberField from './components/NumberField.svelte';
77
import InputFieldBase from './components/InputFieldBase.svelte';
8-
import { cloneDeepJson, assertDev, assertNever, getMessage } from '@/helpers';
8+
import { cloneDeepJson, assertDev, assertNever, createGetMessage, getMessageNative } from '@/helpers';
99
import { defaultSettings, filterOutLocalStorageOnlySettings, getSettings, setSettings, Settings } from '@/settings';
1010
import debounce from 'lodash/debounce';
1111
import { getDecayTimeConstant as getTimeSavedDataWeightDecayTimeConstant } from '@/content/TimeSavedTracker';
1212
13+
let getMessage = getMessageNative;
14+
createGetMessage().then(r => getMessage = r);
15+
1316
let unsaved = false;
1417
let formValid = true;
1518
let formEl: HTMLFormElement;

Diff for: src/options/components/HotkeysTable.svelte

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
eventToCombination, combinationToString, HotkeyBinding, hotkeyActionToString, HotkeyAction, NoArgumentAction,
1111
allNoArgumentActions,
1212
} from '@/hotkeys';
13-
import { getMessage } from '@/helpers';
13+
import { createGetMessage, getMessageNative } from '@/helpers';
14+
15+
let getMessage = getMessageNative;
16+
createGetMessage().then(r => getMessage = r);
1417
1518
export let hotkeys: PotentiallyInvalidHotkeyBinding[];
1619
export let displayOverrideWebsiteHotkeysColumn: boolean;

Diff for: src/popup/App.svelte

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
import debounce from 'lodash/debounce';
1616
import throttle from 'lodash/throttle';
1717
import { fromS } from 'hh-mm-ss'; // TODO it could be lighter. Make a MR or merge it directly and modify.
18-
import { getMessage } from '@/helpers';
18+
import { createGetMessage, getMessageNative } from '@/helpers';
19+
20+
let getMessage = getMessageNative;
21+
createGetMessage('en').then(r => getMessage = r);
1922
2023
let settings: Settings;
2124

Diff for: src/popup/MediaUnsupportedMessage.svelte

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
import { createEventDispatcher } from 'svelte';
33
import { Settings, ControllerKind_CLONING, ControllerKind_STRETCHING, } from '@/settings';
44
import type { TelemetryMessage } from '@/content/AllMediaElementsController';
5-
import { assertNever, getMessage } from '@/helpers';
5+
import { assertNever, createGetMessage, getMessageNative } from '@/helpers';
6+
7+
let getMessage = getMessageNative;
8+
createGetMessage().then(r => getMessage = r);
69
710
export let settings: Pick<Settings,
811
'experimentalControllerType'

Diff for: webpack.config.js

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ module.exports = env => {
1919
});
2020

2121
return {
22+
experiments: {
23+
topLevelAwait: true,
24+
},
25+
2226
devtool: process.env.NODE_ENV === 'production'
2327
? undefined
2428
// The default one ('eval') doesn't work because "'unsafe-eval' is not an allowed source of script in the following

0 commit comments

Comments
 (0)