feat: #8 i18n support (zh/en toggle)

This commit is contained in:
2026-07-26 18:45:23 +08:00
parent 71d039ba82
commit 3514612f7a
3 changed files with 71 additions and 0 deletions
+2
View File
@@ -1,4 +1,5 @@
(function () { (function () {
Lang.init();
Theme.init(); Theme.init();
WS.init(); WS.init();
Sidebar.init(); Sidebar.init();
@@ -11,6 +12,7 @@
Router.init(); Router.init();
document.getElementById('theme-toggle').addEventListener('click', () => Theme.toggle()); document.getElementById('theme-toggle').addEventListener('click', () => Theme.toggle());
document.getElementById('lang-toggle').addEventListener('click', () => Lang.toggle());
console.log('%cTurboSu %cReady', console.log('%cTurboSu %cReady',
'color:#667eea;font-size:16px;font-weight:bold;', 'color:#667eea;font-size:16px;font-weight:bold;',
+67
View File
@@ -0,0 +1,67 @@
const Lang = {
_current: 'zh',
_strings: {
zh: {
home: '首页', dashboard: '仪表盘', scene: '场景', settings: '设置',
debug: '数据测试', selectGame: '选择游戏', collapsed: '折叠侧边栏',
connected: '已连接', disconnected: '未连接', speed: '实时速度', rpm: '实时转速',
gear: '当前档位', server: '服务器状态', telemetry: '遥测监听',
connections: 'WebSocket 连接', packets: '数据包接收', lastPacket: '最后数据包',
currentGame: '当前游戏', systemOverview: '系统概览', running: '运行中',
stopped: '已停止', notStarted: '未启动', noData: '暂无数据', client: '个客户端',
notSelected: '未选择', packetsUnit: '包', secAgo: '秒前',
importTsd: '导入 .tsd', importTss: '导入 .tss', importTsp: '导入 .tsp',
export: '导出', delete: '删除', edit: '编辑', render: '渲染', save: '保存',
cancel: '取消', create: '新建场景', sceneName: '场景名称',
search: '搜索仪表盘...', sort: '排序', all: '全部', none: '暂无',
forward: '数据转发', addTarget: '+ 添加目标', saveActive: '保存并生效',
connectionSettings: '连接设置', telemetryPort: '遥测监听端口',
unifiedPort: '统一端口', perGamePort: '各游戏独立端口',
restart: '重启监听', pluginSettings: '游戏插件管理',
plugins: '游戏插件', reload: '重新加载', backup: '数据备份',
exportBackup: '下载 .tsb', importBackup: '导入 .tsb',
devTools: '开发工具', testMode: 'UI 测试模式',
system: '系统', restartServer: '重启服务',
about: '关于', author: 'Yei.J. (AskaEth)',
},
en: {
home: 'Home', dashboard: 'Dashboard', scene: 'Scene', settings: 'Settings',
debug: 'Debug', selectGame: 'Select Game', collapsed: 'Collapse',
connected: 'Connected', disconnected: 'Disconnected', speed: 'Speed', rpm: 'RPM',
gear: 'Gear', server: 'Server', telemetry: 'Telemetry',
connections: 'Connections', packets: 'Packets', lastPacket: 'Last Packet',
currentGame: 'Game', systemOverview: 'Overview', running: 'Running',
stopped: 'Stopped', notStarted: 'Off', noData: 'No Data', client: ' clients',
notSelected: 'None', packetsUnit: 'pkt', secAgo: 's ago',
importTsd: 'Import .tsd', importTss: 'Import .tss', importTsp: 'Import .tsp',
export: 'Export', delete: 'Delete', edit: 'Edit', render: 'Render', save: 'Save',
cancel: 'Cancel', create: 'New Scene', sceneName: 'Name',
search: 'Search...', sort: 'Sort', all: 'All', none: 'None',
forward: 'Forward', addTarget: '+ Add', saveActive: 'Save',
connectionSettings: 'Connection', telemetryPort: 'Port',
unifiedPort: 'Unified', perGamePort: 'Per Game',
restart: 'Restart', pluginSettings: 'Plugins',
plugins: 'Plugins', reload: 'Reload', backup: 'Backup',
exportBackup: 'Download .tsb', importBackup: 'Import .tsb',
devTools: 'Dev Tools', testMode: 'Test Mode',
system: 'System', restartServer: 'Restart',
about: 'About', author: 'Yei.J. (AskaEth)',
}
},
init() {
this._current = localStorage.getItem('turbosu-lang') || 'zh';
},
t(key) {
return (this._strings[this._current] || this._strings.zh)[key] || key;
},
toggle() {
this._current = this._current === 'zh' ? 'en' : 'zh';
localStorage.setItem('turbosu-lang', this._current);
location.reload();
}
};
window.Lang = Lang;
+2
View File
@@ -84,6 +84,7 @@
<svg class="icon-sun" viewBox="0 0 24 24" width="20" height="20"><path d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79zM4 10.5H1v2h3zm9-9.95h-2V3.5h2zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79zM20 10.5v2h3v-2zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41z" fill="currentColor"/></svg> <svg class="icon-sun" viewBox="0 0 24 24" width="20" height="20"><path d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79zM4 10.5H1v2h3zm9-9.95h-2V3.5h2zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79zM20 10.5v2h3v-2zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41z" fill="currentColor"/></svg>
<svg class="icon-moon" viewBox="0 0 24 24" width="20" height="20"><path d="M9.37 5.51c-.18.64-.27 1.31-.27 1.99 0 4.08 3.32 7.4 7.4 7.4.68 0 1.35-.09 1.99-.27C17.45 17.19 14.93 19 12 19c-3.86 0-7-3.14-7-7 0-2.93 1.81-5.45 4.37-6.49z" fill="currentColor"/></svg> <svg class="icon-moon" viewBox="0 0 24 24" width="20" height="20"><path d="M9.37 5.51c-.18.64-.27 1.31-.27 1.99 0 4.08 3.32 7.4 7.4 7.4.68 0 1.35-.09 1.99-.27C17.45 17.19 14.93 19 12 19c-3.86 0-7-3.14-7-7 0-2.93 1.81-5.45 4.37-6.49z" fill="currentColor"/></svg>
</button> </button>
<button id="lang-toggle" class="icon-btn" title="Language" style="font-size:13px;font-weight:600"></button>
</div> </div>
</header> </header>
@@ -104,6 +105,7 @@
<script src="/static/js/utils/theme.js"></script> <script src="/static/js/utils/theme.js"></script>
<script src="/static/js/utils/toast.js"></script> <script src="/static/js/utils/toast.js"></script>
<script src="/static/js/utils/lang.js"></script>
<script src="/static/js/api.js"></script> <script src="/static/js/api.js"></script>
<script src="/static/js/ws.js"></script> <script src="/static/js/ws.js"></script>
<script src="/static/js/components/sidebar.js"></script> <script src="/static/js/components/sidebar.js"></script>