Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"dependencies": {
"@decky/api": "^1.1.2",
"axios": "^1.7.9",
"i18next": "^23.15.1",
"qrcode.react": "^4.2.0",
"react": "^19.0.0",
"react-icons": "^5.4.0",
Expand Down
3 changes: 2 additions & 1 deletion src/components/SubList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ButtonItem } from "@decky/ui";
import { FC } from "react";
import * as backend from "../backend/backend";
import { localizationManager, L } from "../i18n";
interface appProp {
Subscriptions: Array<any>;
UpdateSub: any;
Expand All @@ -27,7 +28,7 @@ export const SubList: FC<appProp> = ({ Subscriptions, UpdateSub, Refresh }) => {
Refresh();
}}
>
Delete
{localizationManager.getString(L.DELETE)}
</ButtonItem>
</div>
);
Expand Down
35 changes: 24 additions & 11 deletions src/components/Version.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ import { PanelSection, PanelSectionRow, Field } from "@decky/ui";
import { FC, useEffect, useState } from "react";
import { PyBackend } from "../backend/backend";
import { ActionButtonItem } from ".";

import { localizationManager, L } from "../i18n";

export const VersionComponent: FC = () => {
const [currentVersion, _] = useState<string>(PyBackend.data.getCurrentVersion());
const [latestVersion, setLatestVersion] = useState<string>(PyBackend.data.getLatestVersion());
const [currentVersion, _] = useState<string>(
PyBackend.data.getCurrentVersion()
);
const [latestVersion, setLatestVersion] = useState<string>(
PyBackend.data.getLatestVersion()
);

useEffect(() => {
const getData = async () => {
Expand All @@ -17,34 +21,43 @@ export const VersionComponent: FC = () => {
getData();
});

let uptButtonText = 'Reinstall Plugin';
let uptButtonText = localizationManager.getString(L.REINSTALL_PLUGIN);

if (currentVersion !== latestVersion && Boolean(latestVersion)) {
uptButtonText = `Update to ${latestVersion}`;
uptButtonText =
localizationManager.getString(L.UPDATE_TO) + ` ${latestVersion}`;
}

return (
<PanelSection title={'Version'}>
<PanelSection title={localizationManager.getString(L.VERSION)}>
<PanelSectionRow>
<ActionButtonItem
layout="below"
onClick={async () => {
await PyBackend.updateLatest();
}}
>{uptButtonText}</ActionButtonItem>
>
{uptButtonText}
</ActionButtonItem>
</PanelSectionRow>
<PanelSectionRow>
<Field focusable label={'Installed Version'}>
<Field
focusable
label={localizationManager.getString(L.INSTALLED_VERSION)}
>
{currentVersion}
</Field>
</PanelSectionRow>
{Boolean(latestVersion) && (
<PanelSectionRow>
<Field focusable label={'Latest Version'}>
<Field
focusable
label={localizationManager.getString(L.LATEST_VERSION)}
>
{latestVersion}
</Field>
</PanelSectionRow>
)}
</PanelSection>
)
}
);
};
1 change: 1 addition & 0 deletions src/i18n/bulgarian.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
35 changes: 35 additions & 0 deletions src/i18n/english.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"SERVICE": "Service",
"TOOLS": "Tools",
"VERSION": "Version",
"ABOUT": "About",
"DEBUG": "Debug",
"SUBSCRIPTIONS": "Subscriptions",
"SUBSCRIPTIONS_LINK": "Subscriptions",
"SELECT_SUBSCRIPTION": "Select a Subscription",
"DOWNLOAD": "Download",
"UPDATE_ALL": "Update All",
"DELETE": "Delete",
"ENABLE_CLASH": "Enable Clash",
"ENABLE_CLASH_DESC": "Run Clash in background",
"ENABLE_CLASH_FAILED": "Failed to start, please check /tmp/tomoon.log",
"ENABLE_CLASH_LOADING": "Loading ...",
"ENABLE_CLASH_IS_RUNNING": "Clash is running.",
"MANAGE_SUBSCRIPTIONS": "Manage Subscriptions",
"OPEN_DASHBOARD": "Open Dashboard",
"SELECT_DASHBOARD": "Select Dashboard",
"ALLOW_REMOTE_ACCESS": "Allow Remote Access",
"ALLOW_REMOTE_ACCESS_DESC": "Allow Remote Access to Dashboard",
"SKIP_PROXY": "Skip Proxy",
"SKIP_PROXY_DESC": "Enable for direct Steam downloads",
"OVERRIDE_DNS": "Override DNS",
"OVERRIDE_DNS_DESC": "Force Clash to hijack DNS query",
"ENHANCED_MODE": "Enhanced Mode",
"ENHANCED_MODE_DESC": "Enhanced Mode",
"RESTART_CORE": "Restart Core",
"RESET_NETWORK": "Reset Network",
"REINSTALL_PLUGIN": "Reinstall Plugin",
"UPDATE_TO": "Update to",
"INSTALLED_VERSION": "Installed Version",
"LATEST_VERSION": "Latest Version"
}
1 change: 1 addition & 0 deletions src/i18n/french.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
1 change: 1 addition & 0 deletions src/i18n/german.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
2 changes: 2 additions & 0 deletions src/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./localization"
export * from "./localizeMap"
1 change: 1 addition & 0 deletions src/i18n/italian.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
1 change: 1 addition & 0 deletions src/i18n/japanese.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
1 change: 1 addition & 0 deletions src/i18n/koreana.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
46 changes: 46 additions & 0 deletions src/i18n/localization.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { defaultLocale, localizeMap, LocalizeStrKey } from "./localizeMap";

import i18n, { Resource } from "i18next";

export class localizationManager {
private static language = "english";

public static async init() {
const language =
(await SteamClient.Settings.GetCurrentLanguage()) || "english";
this.language = language;
console.log(">>>>>>>>>> Language: " + this.language);

const resources: Resource = Object.keys(localizeMap).reduce(
(acc: Resource, key) => {
acc[localizeMap[key].locale] = {
translation: localizeMap[key].strings,
};
return acc;
},
{}
);

i18n.init({
resources: resources,
lng: this.getLocale(), // 目标语言
fallbackLng: defaultLocale, // 回落语言
returnEmptyString: false, // 空字符串不返回, 使用回落语言
interpolation: {
escapeValue: false,
},
});
}

private static getLocale() {
return localizeMap[this.language]?.locale ?? defaultLocale;
}

public static getString(
defaultString: LocalizeStrKey,
variables?: Record<string, unknown>
) {
console.log(">>>>>>>>>> getString: " + defaultString);
return i18n.t(defaultString, variables);
}
}
142 changes: 142 additions & 0 deletions src/i18n/localizeMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import * as schinese from "./schinese.json";
import * as tchinese from "./tchinese.json";
import * as english from "./english.json";
import * as german from "./german.json";
import * as japanese from "./japanese.json";
import * as koreana from "./koreana.json";
import * as thai from "./thai.json";
import * as bulgarian from "./bulgarian.json";
import * as italian from "./italian.json";
import * as french from "./french.json";

export interface LanguageProps {
label: string;
strings: any;
credit: string[];
locale: string;
}

export const defaultLanguage = "english";
export const defaultLocale = "en";
export const defaultMessages = english;

export const localizeMap: { [key: string]: LanguageProps } = {
schinese: {
label: "简体中文",
strings: schinese,
credit: ["yxx"],
locale: "zh-CN",
},
tchinese: {
label: "繁體中文",
strings: tchinese,
credit: [],
locale: "zh-TW",
},
english: {
label: "English",
strings: english,
credit: [],
locale: "en",
},
german: {
label: "Deutsch",
strings: german,
credit: ["dctr"],
locale: "de",
},
japanese: {
label: "日本語",
strings: japanese,
credit: [],
locale: "ja",
},
koreana: {
label: "한국어",
strings: koreana,
credit: [],
locale: "ko",
},
thai: {
label: "ไทย",
strings: thai,
credit: [],
locale: "th",
},
bulgarian: {
label: "Български",
strings: bulgarian,
credit: [],
locale: "bg",
},
italian: {
label: "Italiano",
strings: italian,
credit: [],
locale: "it",
},
french: {
label: "Français",
strings: french,
credit: [],
locale: "fr",
},
};

// 创建一个类型安全的常量生成函数
function createLocalizeConstants<T extends readonly string[]>(keys: T) {
return keys.reduce((obj, key) => {
obj[key as keyof typeof obj] = key;
return obj;
}, {} as { [K in T[number]]: K });
}

// 定义所有键名
const I18N_KEYS = [
"SERVICE",
"TOOLS",
"VERSION",
"ABOUT",
"DEBUG",

// Subscriptions manager
"SUBSCRIPTIONS",
"SUBSCRIPTIONS_LINK",
"SELECT_SUBSCRIPTION",
"DOWNLOAD",
"UPDATE_ALL",
"DELETE",

// QAM
"ENABLE_CLASH",
"ENABLE_CLASH_DESC",
"ENABLE_CLASH_FAILED",
"ENABLE_CLASH_LOADING",
"ENABLE_CLASH_IS_RUNNING",
"MANAGE_SUBSCRIPTIONS",
"OPEN_DASHBOARD",
"SELECT_DASHBOARD",
"ALLOW_REMOTE_ACCESS",
"ALLOW_REMOTE_ACCESS_DESC",
"SKIP_PROXY",
"SKIP_PROXY_DESC",
"OVERRIDE_DNS",
"OVERRIDE_DNS_DESC",
"ENHANCED_MODE",
"ENHANCED_MODE_DESC",
"RESTART_CORE",
"RESET_NETWORK",
"REINSTALL_PLUGIN",
"UPDATE_TO",
"INSTALLED_VERSION",
"LATEST_VERSION",
] as const;

// 创建常量对象并导出
export const L = createLocalizeConstants(I18N_KEYS);

// 导出类型
export type LocalizeStrKey = keyof typeof L;

// 为了向后兼容,保留 localizeStrEnum 名称
// export const localizeStrEnum = L;
35 changes: 35 additions & 0 deletions src/i18n/schinese.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"SERVICE": "服务",
"TOOLS": "工具",
"VERSION": "版本",
"ABOUT": "关于",
"DEBUG": "调试",
"SUBSCRIPTIONS": "订阅",
"SUBSCRIPTIONS_LINK": "订阅链接",
"SELECT_SUBSCRIPTION": "选择订阅",
"DOWNLOAD": "下载",
"UPDATE_ALL": "更新所有",
"DELETE": "删除",
"ENABLE_CLASH": "启用 Clash",
"ENABLE_CLASH_DESC": "在后台运行 Clash",
"ENABLE_CLASH_FAILED": "启动失败,请检查 /tmp/tomoon.log",
"ENABLE_CLASH_LOADING": "加载中 ...",
"ENABLE_CLASH_IS_RUNNING": "Clash 正在运行",
"MANAGE_SUBSCRIPTIONS": "管理订阅",
"OPEN_DASHBOARD": "打开 Dashboard",
"SELECT_DASHBOARD": "选择 Dashboard",
"ALLOW_REMOTE_ACCESS": "允许远程访问",
"ALLOW_REMOTE_ACCESS_DESC": "允许远程访问 Dashboard",
"SKIP_PROXY": "跳过代理",
"SKIP_PROXY_DESC": "Steam 下载不经过代理",
"OVERRIDE_DNS": "覆盖 DNS 设置",
"OVERRIDE_DNS_DESC": "强制 Clash 拦截 DNS 查询",
"ENHANCED_MODE": "增强模式",
"ENHANCED_MODE_DESC": "增强模式",
"RESTART_CORE": "重启核心",
"RESET_NETWORK": "重置网络",
"REINSTALL_PLUGIN": "重新安装插件",
"UPDATE_TO": "更新到",
"INSTALLED_VERSION": "已安装版本",
"LATEST_VERSION": "最新版本"
}
1 change: 1 addition & 0 deletions src/i18n/tchinese.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
1 change: 1 addition & 0 deletions src/i18n/thai.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Loading