Skip to content

Commit

Permalink
feat: load custom i18n strings for plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
FedeIlLeone committed Nov 12, 2024
1 parent 5ad36fe commit dd89808
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 22 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
"replug": "tsx scripts/inject/index.mts reinject",
"typescript:check": "tsc --noEmit",
"cspell:check": "cspell lint ./src/**/* ./scripts/**/* ./bin*",
"prettier:check": "prettier ./src ./scripts ./bin ./i18n --check",
"prettier:check": "prettier ./src ./scripts ./bin --check",
"eslint:check": "eslint ./src ./scripts ./bin",
"prettier:fix": "prettier ./src ./scripts ./bin ./i18n --write",
"prettier:fix": "prettier ./src ./scripts ./bin --write",
"eslint:fix": "eslint ./src ./scripts ./bin --fix",
"lint": "pnpm run prettier:check && pnpm run eslint:check && pnpm run cspell:check && pnpm run typescript:check",
"lint:fix": "pnpm run prettier:fix && pnpm run eslint:fix && pnpm run cspell:check && pnpm run typescript:check",
Expand All @@ -38,6 +38,7 @@
"url": "https://github.com/replugged-org/replugged/issues"
},
"devDependencies": {
"@discord/intl": "^0.13.0",
"@discord/intl-loader-core": "^0.13.0",
"@marshift/argus": "^1.2.1",
"@types/adm-zip": "^0.5.6",
Expand Down Expand Up @@ -80,7 +81,6 @@
"@codemirror/lang-css": "^6.3.0",
"@codemirror/language": "^6.10.3",
"@codemirror/state": "^6.4.1",
"@discord/intl": "^0.13.0",
"@electron/asar": "^3.2.17",
"@lezer/highlight": "^1.2.1",
"@octokit/rest": "^21.0.2",
Expand Down
6 changes: 3 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 17 additions & 10 deletions scripts/build-plugins/intl-loader.mts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import esbuild from "esbuild";
import { readFileSync } from "node:fs";
import { dirname, posix, relative, resolve } from "node:path";
import { production } from "scripts/build.mjs";

const FILE_PATH_SEPARATOR_MATCH = /[\\\\\\/]/g;
const INTL_MESSAGES_REGEXP = /\.messages\.(js|json|jsona)$/;
Expand Down Expand Up @@ -59,17 +60,23 @@ export default {
messageKeys = result.messageKeys;
}

const transformedOutput = new MessageDefinitionsTransformer({
messageKeys: Object.fromEntries(
Object.entries(result.messageKeys).map(([_, key]) => [key, key]),
),
localeMap: result.translationsLocaleMap,
defaultLocale: result.locale,
getTranslationImport: (importPath) => `import("${importPath}")`,
debug: !production,
preGenerateBinds: false,
getPrelude: () => `import {waitForProps} from '@webpack';`,
}).getOutput();

return {
contents: new MessageDefinitionsTransformer({
messageKeys: Object.fromEntries(
Object.entries(result.messageKeys).map(([_, key]) => [key, key]),
),
localeMap: result.translationsLocaleMap,
defaultLocale: result.locale,
getTranslationImport: (importPath) => `import("${importPath}")`,
debug: process.env.NODE_ENV === "development",
preGenerateBinds: false,
}).getOutput(),
contents: transformedOutput.replace(
/require\('@discord\/intl'\);/,
"await waitForProps('createLoader','IntlManager');",
),
loader: "js",
};
} else {
Expand Down
2 changes: 1 addition & 1 deletion scripts/build.mts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const CHROME_VERSION = "128";

const ctx = createContext(process.argv);
const watch = ctx.hasOptionalArg(/--watch/);
const production = ctx.hasOptionalArg(/--production/);
export const production = ctx.hasOptionalArg(/--production/);

const dirname = path.dirname(fileURLToPath(import.meta.url));

Expand Down
43 changes: 38 additions & 5 deletions src/renderer/modules/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,58 @@
import type { I18n } from "@common";
import { loadAllMessagesInLocale } from "@discord/intl";
import type { loadAllMessagesInLocale as LoadAllMessagesInLocale } from "@discord/intl";
import { waitForProps } from "@webpack";
import { DEFAULT_LOCALE } from "src/constants";
import messages from "../../../i18n/en-US.messages";
import type * as definitions from "../../../i18n/en-US.messages";

export let locale: string | undefined;
export const t = messages;
export let t: typeof definitions.default;
export let messagesLoader: typeof definitions.messagesLoader;

export async function load(): Promise<void> {
const { intl } = await waitForProps<I18n>("getAvailableLocales", "intl");

// ! HACK: This is a workaround until ignition issues are fixed.
// We need to delay the import of the messages for intl to be loaded and use that module instead of @discord/intl directly.
const { default: messages, messagesLoader: loader } = await import(
"../../../i18n/en-US.messages"
);
t = messages;
messagesLoader = loader;

locale = intl.currentLocale || intl.defaultLocale || DEFAULT_LOCALE;

intl.onLocaleChange((newLocale) => {
locale = newLocale;
addRepluggedStrings();
void addRepluggedStrings();
});
void addRepluggedStrings();
}

export function addRepluggedStrings(): void {
export async function addRepluggedStrings(): Promise<void> {
const { loadAllMessagesInLocale } = await waitForProps<{
loadAllMessagesInLocale: typeof LoadAllMessagesInLocale;
}>("loadAllMessagesInLocale");

if (locale) {
void loadAllMessagesInLocale(locale);
}
}

/**
* Load custom strings into Replugged's translations, typically for plugins.
*/
export function loadAllStrings(translations: Record<string, object>): void {
Object.keys(translations).forEach(async (locale) => {
const { default: originalStrings } = await messagesLoader.localeImportMap[locale]();
const strings = translations[locale];
const messages = { ...strings, ...originalStrings };

if (locale in messagesLoader.messages) messagesLoader.messages[locale] = messages;
messagesLoader.localeImportMap[locale] = () =>
new Promise((resolve) => {
resolve({ default: messages });
});
messagesLoader.messageKeys = [...messagesLoader.messageKeys, ...Object.keys(strings)];
});
void addRepluggedStrings();
}

0 comments on commit dd89808

Please sign in to comment.