From ef028edc0dbf4091fd3e7ad0480c710b9fa9f15c Mon Sep 17 00:00:00 2001 From: Lewis Crichton Date: Sun, 9 Jun 2024 21:47:03 +0100 Subject: [PATCH] feat: top level hax --- src/components/PluginSettings/index.tsx | 3 +- src/utils/text.ts | 2 -- src/utils/translation.tsx | 40 +++++++++++++++++-------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/components/PluginSettings/index.tsx b/src/components/PluginSettings/index.tsx index 5065a85cf..d2c48eeb1 100644 --- a/src/components/PluginSettings/index.tsx +++ b/src/components/PluginSettings/index.tsx @@ -33,7 +33,6 @@ import { Margins } from "@utils/margins"; import { classes, isObjectEmpty } from "@utils/misc"; import { openModalLazy } from "@utils/modal"; import { useAwaiter } from "@utils/react"; -import { lowercaseify } from "@utils/text"; import { $t } from "@utils/translation"; import { Plugin } from "@utils/types"; import { findByPropsLazy } from "@webpack"; @@ -154,7 +153,7 @@ export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, on return ( export const wordsToTitle = (words: string[]) => words.map(w => w[0].toUpperCase() + w.slice(1)).join(" "); -export const lowercaseify = (text: string) => text[0].toLowerCase() + text.slice(1); - const units = ["years", "months", "weeks", "days", "hours", "minutes", "seconds"] as const; type Units = typeof units[number]; diff --git a/src/utils/translation.tsx b/src/utils/translation.tsx index 6da989bea..e5f51910c 100644 --- a/src/utils/translation.tsx +++ b/src/utils/translation.tsx @@ -107,26 +107,40 @@ function _t(key: string, bundle: any): Translation { * @returns A translated string. */ export function $t(key: string, variables?: Record): string { - const translation = _t(key, loadedLocale); + const getter = (): string => { + const translation = _t(key, loadedLocale); - if (typeof translation !== "string") { - if (!variables || !variables.count) throw new Error(`translation key ${key} is an object (requires plurality?)`); + if (typeof translation !== "string") { + if (!variables || !variables.count) throw new Error(`translation key ${key} is an object (requires plurality?)`); - if (variables.count) { - const pluralTag: Intl.LDMLPluralRule = variables.count === 0 ? "zero" : - new Intl.PluralRules(bestLocale).select(variables.count); + if (variables.count) { + const pluralTag: Intl.LDMLPluralRule = variables.count === 0 ? "zero" : + new Intl.PluralRules(bestLocale).select(variables.count); - if (translation[pluralTag]) { - return format(translation[pluralTag]!, variables); - } else { - return format(translation.other, variables); + if (translation[pluralTag]) { + return format(translation[pluralTag]!, variables); + } else { + return format(translation.other, variables); + } } } - } - if (!variables) return translation as string; + if (!variables) return translation as string; - return format(translation as string, variables); + return format(translation as string, variables); + }; + + // top level support hax (thank you vee!!) + // tl;dr: this lets you use $t at the top level in objects by simulating a string, a la: + // { + // description: $t("clientTheme.description") + // } + // and any future accesses of the description prop will result in an up to date translation + return { + __proto__: String.prototype, + valueOf: getter, + toString: getter + } as unknown as string; } interface TranslateProps {