client refactor: merge script/i18n.ts into i18n.ts

The file i18n.ts was basically only a few lines that call into
scripts/i18n.ts. Instead of having the extra file it is just as good to
have the relevant code for i18n in one file. Since i18n.ts is
imported in many client components, while scripts/i18n.ts was only
imported in i18n.ts, the latter seems better to keep.

Added some more comments and translated the Japanese comments to
English.
This commit is contained in:
Johann150 2022-10-01 13:24:44 +02:00
parent 59adb0b6e2
commit cb888673b8
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1
2 changed files with 39 additions and 30 deletions

View file

@ -1,5 +1,43 @@
import { markRaw } from 'vue'; import { markRaw } from 'vue';
import { locale } from '@/config'; import { locale } from '@/config';
import { I18n } from '@/scripts/i18n';
class I18n<T extends Record<string, any>> {
// This contains all defined keys, even if a string is missing in a particular language.
// This is achieved by setting English strings as a fallback during locale generation in /locales/index.js
public ts: T;
constructor(locale: T) {
this.ts = locale;
this.t = this.t.bind(this);
}
// The key is a string (rather than a Symbol) to allow for the dot-delimited names.
//
// If possible it should probably be preferred to use the locale directly (i.e. the ts member),
// because it may allow for vue to cache information.
//
// Performs string interpolation for patters like `{foo}` and replaces it with the respective value from `args` (using its `toString()` method).
// If a pattern is present in the string but not provided in args, it will not be replaced.
// If `args` is not provided, no interpolation is performed.
public t(key: string, args?: Record<string, string | number>): string {
try {
// Resolve dot-delimited names as properties of objects.
let str = key.split('.').reduce((o, i) => o[i], this.ts) as unknown as string;
// Perform string interpolation.
if (args) {
for (const [k, v] of Object.entries(args)) {
str = str.replace(`{${k}}`, v.toString());
}
}
return str;
} catch (err) {
// This should normally not happen because of the English language fallback strings, see comment for ts member.
console.warn(`missing localization '${key}'`);
return key;
}
}
}
export const i18n = markRaw(new I18n(locale)); export const i18n = markRaw(new I18n(locale));

View file

@ -1,29 +0,0 @@
export class I18n<T extends Record<string, any>> {
public ts: T;
constructor(locale: T) {
this.ts = locale;
//#region BIND
this.t = this.t.bind(this);
//#endregion
}
// string にしているのは、ドット区切りでのパス指定を許可するため
// なるべくこのメソッド使うよりもlocale直接参照の方がvueのキャッシュ効いてパフォーマンスが良いかも
public t(key: string, args?: Record<string, string | number>): string {
try {
let str = key.split('.').reduce((o, i) => o[i], this.ts) as unknown as string;
if (args) {
for (const [k, v] of Object.entries(args)) {
str = str.replace(`{${k}}`, v.toString());
}
}
return str;
} catch (err) {
console.warn(`missing localization '${key}'`);
return key;
}
}
}