mirror of
https://github.com/lifegpc/eh-downloader.git
synced 2026-07-08 01:31:00 +08:00
Add i18n support
This commit is contained in:
16
server/i18n.ts
Normal file
16
server/i18n.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { signal } from "@preact/signals";
|
||||
|
||||
export type I18NMap = { [x: string]: string | I18NMap };
|
||||
|
||||
export const i18n_map = signal<I18NMap>({});
|
||||
const NOT_FOUND = "__NOT_FOUND__";
|
||||
|
||||
export default function t(key: string) {
|
||||
const keys = key.split(".");
|
||||
let map: string | I18NMap = i18n_map.value;
|
||||
for (const k of keys) {
|
||||
if (typeof map === "string") return NOT_FOUND;
|
||||
else map = map[k];
|
||||
}
|
||||
return typeof map === "string" ? map : NOT_FOUND;
|
||||
}
|
||||
72
server/i18ns.ts
Normal file
72
server/i18ns.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { exists } from "std/fs/exists.ts";
|
||||
import { parse } from "std/jsonc/mod.ts";
|
||||
import { join } from "std/path/mod.ts";
|
||||
import { I18NMap } from "./i18n.ts";
|
||||
import { pick } from "accept-language-parser/";
|
||||
|
||||
const whole_maps = new Map<string, I18NMap>();
|
||||
const LANGUAGES = ["zh-cn"];
|
||||
type MODULE = "common";
|
||||
const MODULES: MODULE[] = ["common"];
|
||||
|
||||
export async function load_translation(signal?: AbortSignal) {
|
||||
const base = import.meta.resolve("../translation").slice(8);
|
||||
const enmap: I18NMap = {};
|
||||
for (const m of MODULES) {
|
||||
const t = await Deno.readTextFile(join(base, "en", m + ".jsonc"), {
|
||||
signal,
|
||||
});
|
||||
const v = <I18NMap> <unknown> parse(t);
|
||||
enmap[m] = v;
|
||||
}
|
||||
whole_maps.set("en", enmap);
|
||||
for (const l of LANGUAGES) {
|
||||
const map: I18NMap = {};
|
||||
for (const m of MODULES) {
|
||||
const p = join(base, l, m + ".jsonc");
|
||||
if (await exists(p)) {
|
||||
const t = await Deno.readTextFile(join(base, l, m + ".jsonc"), {
|
||||
signal,
|
||||
});
|
||||
const v = <I18NMap> <unknown> Object.assign(
|
||||
structuredClone(enmap[m]),
|
||||
parse(t),
|
||||
);
|
||||
map[m] = v;
|
||||
} else map[m] = enmap[m];
|
||||
}
|
||||
whole_maps.set(l, map);
|
||||
}
|
||||
}
|
||||
|
||||
export function get_i18nmap(lang: string, ...modules: MODULE[]) {
|
||||
const m = whole_maps.get(lang);
|
||||
if (!m) throw Error(`Language ${lang} is not supported.`);
|
||||
if (!modules.length) return m;
|
||||
const r: I18NMap = {};
|
||||
for (const n of modules) {
|
||||
r[n] = m[n];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
export function i18n_handle_request(req: Request) {
|
||||
const u = new URL(req.url);
|
||||
const lang = u.searchParams.get("lang");
|
||||
if (lang && (lang === "en" || LANGUAGES.includes(lang))) {
|
||||
return lang;
|
||||
} else {
|
||||
const a = req.headers.get("Accept-Language");
|
||||
const l = (a
|
||||
? pick(LANGUAGES, a) || pick(LANGUAGES, a, { loose: true })
|
||||
: null) || "en";
|
||||
const params = new URLSearchParams();
|
||||
params.append("lang", l);
|
||||
for (const p of u.searchParams.entries()) {
|
||||
if (p[0] !== "lang") {
|
||||
params.append(p[0], p[1]);
|
||||
}
|
||||
}
|
||||
return Response.redirect(`${u.origin}${u.pathname}?${params}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user