mirror of
https://github.com/k1tbyte/Wand-Enhancer.git
synced 2026-08-28 17:01:04 +00:00
a0b3968d33
Reorganize the panel around product capabilities and integrate the remote i18n feature from origin/master into the new structure. - Restructure src into capability features (app, trainer, library, remote-session, appearance, shared); move the bridge to bridge/src. - Add lingui-based UI localization and wrap remaining user-facing strings (Trans / msg macros); fix the 'END В·' mojibake. - Port WeMod cheat-metadata i18n: capture the access token from the snapshot's renderer in the bridge and fetch localized trainer_meta in remote-session.i18n; guarantee snapshot sync on token failure. - Wire vitest to the app's lingui/preact pipeline (mergeConfig).
61 lines
1.8 KiB
TypeScript
Vendored
61 lines
1.8 KiB
TypeScript
Vendored
import type { CheatSchema, TrainerMetaPayload } from '../../protocol/messages';
|
|
|
|
const WEMOD_TRAINER_ENDPOINT = 'https://api.wemod.com/v3/games';
|
|
|
|
type WemodTrainerResponse = {
|
|
i18n?: { strings?: Record<string, string> };
|
|
};
|
|
|
|
export async function localizeTrainerMeta(payload: TrainerMetaPayload): Promise<TrainerMetaPayload> {
|
|
const strings = await fetchTrainerStrings(payload);
|
|
if (!strings) {
|
|
return payload;
|
|
}
|
|
|
|
const cheats = payload.schema.cheats.map((cheat) => localizeCheat(cheat, strings));
|
|
return { ...payload, schema: { ...payload.schema, cheats } };
|
|
}
|
|
|
|
async function fetchTrainerStrings(payload: TrainerMetaPayload): Promise<Record<string, string> | null> {
|
|
const { accessToken } = payload.session;
|
|
const { gameId, gameVersion, language } = payload.trainer;
|
|
if (!accessToken || !gameId) {
|
|
return null;
|
|
}
|
|
|
|
const params = new URLSearchParams();
|
|
if (gameVersion) params.set('gameVersions', gameVersion);
|
|
if (language) params.set('locale', language);
|
|
|
|
try {
|
|
const response = await fetch(`${WEMOD_TRAINER_ENDPOINT}/${gameId}/trainer?${params}`, {
|
|
headers: { Authorization: `Bearer ${accessToken}` },
|
|
});
|
|
if (!response.ok) {
|
|
return null;
|
|
}
|
|
|
|
const trainer = (await response.json()) as WemodTrainerResponse;
|
|
return trainer.i18n?.strings ?? null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function localizeCheat(cheat: CheatSchema, strings: Record<string, string>): CheatSchema {
|
|
return {
|
|
...cheat,
|
|
name: strings[cheat.name] ?? cheat.name,
|
|
description: translate(cheat.description, strings),
|
|
instructions: translate(cheat.instructions, strings),
|
|
};
|
|
}
|
|
|
|
function translate(value: string | null | undefined, strings: Record<string, string>): string | null {
|
|
if (!value) {
|
|
return value ?? null;
|
|
}
|
|
|
|
return strings[value] ?? value;
|
|
}
|