dsh-remote-plugin 0.6.10 → 0.6.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +23 -3
- package/README.md +23 -3
- package/apk/dsh-remote.apk +0 -0
- package/client.js +56 -4
- package/gateway-stats.cjs +40 -11
- package/gateway.cjs +539 -42
- package/index.mjs +3 -2
- package/package.json +1 -1
- package/public/announcements.json +8 -0
- package/public/app.js +785 -69
- package/public/index.html +132 -16
- package/public/plugin-icon.svg +5 -0
- package/public/styles.css +126 -1
- package/public/theme.js +9 -2
- package/public/update.json +12 -8
- package/public/version.json +1 -1
package/public/index.html
CHANGED
|
@@ -38,6 +38,12 @@
|
|
|
38
38
|
</button>
|
|
39
39
|
<div id="wb-panel" class="wb-panel hidden"></div>
|
|
40
40
|
</div>
|
|
41
|
+
<div class="workspace-nav" id="workspace-nav">
|
|
42
|
+
<label for="session-workspace-filter" data-i18n="workspace.current">当前工作区</label>
|
|
43
|
+
<select id="session-workspace-filter" class="workspace-select" data-i18n-aria="workspace.select"></select>
|
|
44
|
+
<button id="session-workspace-files" class="mini-btn" type="button" data-i18n="workspace.files">查看文件</button>
|
|
45
|
+
<code id="session-workspace-path" class="workspace-path-scroll"></code>
|
|
46
|
+
</div>
|
|
41
47
|
<div class="section-head">
|
|
42
48
|
<span data-i18n="nav.sessions">会话</span>
|
|
43
49
|
<div class="section-actions">
|
|
@@ -55,6 +61,10 @@
|
|
|
55
61
|
|
|
56
62
|
<!-- 文件传输 -->
|
|
57
63
|
<section id="view-files" class="view hidden">
|
|
64
|
+
<div class="fs-workspace-nav">
|
|
65
|
+
<label for="fs-workspace" data-i18n="fs.workspace">DSH 工作区</label>
|
|
66
|
+
<select id="fs-workspace" class="workspace-select" data-i18n-aria="workspace.select"></select>
|
|
67
|
+
</div>
|
|
58
68
|
<div class="fs-head">
|
|
59
69
|
<button id="fs-up" class="icon-btn" data-i18n-title="fs.up" data-i18n-aria="fs.up">‹</button>
|
|
60
70
|
<div id="fs-path" class="fs-path" data-i18n="fs.loading">加载中…</div>
|
|
@@ -186,6 +196,17 @@
|
|
|
186
196
|
</div>
|
|
187
197
|
</div>
|
|
188
198
|
|
|
199
|
+
<section id="overview-announcement-board" class="overview-board" aria-labelledby="overview-board-title">
|
|
200
|
+
<div class="overview-board-head">
|
|
201
|
+
<div>
|
|
202
|
+
<div class="overview-eyebrow" data-i18n="overview.communityEyebrow">COMMUNITY BOARD</div>
|
|
203
|
+
<h2 id="overview-board-title" data-i18n="overview.communityTitle">公告与投票</h2>
|
|
204
|
+
</div>
|
|
205
|
+
<button id="overview-announcement-history" class="mini-btn" type="button" data-i18n="overview.communityHistory">历史公告</button>
|
|
206
|
+
</div>
|
|
207
|
+
<div id="overview-announcement-list" class="overview-announcement-list" aria-live="polite"></div>
|
|
208
|
+
</section>
|
|
209
|
+
|
|
189
210
|
<div class="overview-section-head"><span data-i18n="overview.attention">需要你处理</span><span id="overview-attention-count" class="overview-section-meta"></span></div>
|
|
190
211
|
<div id="overview-attention-list" class="overview-attention-list"></div>
|
|
191
212
|
|
|
@@ -218,23 +239,18 @@
|
|
|
218
239
|
<div class="settings-group">
|
|
219
240
|
<div class="setting-row" data-settings-group="general" style="cursor:pointer">
|
|
220
241
|
<div><div class="setting-name" data-i18n="settings.groupGeneral">通用</div><div class="setting-desc" data-i18n="settings.groupGeneralDesc">显示工具调用、预设提示词</div></div>
|
|
221
|
-
<span class="sc-arrow">›</span>
|
|
222
242
|
</div>
|
|
223
243
|
<div class="setting-row" data-settings-group="servers" style="cursor:pointer">
|
|
224
244
|
<div><div class="setting-name" data-i18n="settings.groupServers">服务器</div><div class="setting-desc" data-i18n="settings.groupServersDesc">服务器地址、扫码连接</div></div>
|
|
225
|
-
<span class="sc-arrow">›</span>
|
|
226
245
|
</div>
|
|
227
246
|
<div class="setting-row" data-settings-group="notify" style="cursor:pointer">
|
|
228
247
|
<div><div class="setting-name" data-i18n="settings.groupNotify">通知</div><div class="setting-desc" data-i18n="settings.groupNotifyDesc">通知、提醒、后台轮询</div></div>
|
|
229
|
-
<span class="sc-arrow">›</span>
|
|
230
248
|
</div>
|
|
231
249
|
<div class="setting-row" data-settings-group="theme" style="cursor:pointer">
|
|
232
250
|
<div><div class="setting-name" data-i18n="settings.groupTheme">皮肤</div><div class="setting-desc" data-i18n="settings.groupThemeDesc">配色主题</div></div>
|
|
233
|
-
<span class="sc-arrow">›</span>
|
|
234
251
|
</div>
|
|
235
252
|
<div class="setting-row" data-settings-group="about" style="cursor:pointer">
|
|
236
253
|
<div><div class="setting-name" data-i18n="settings.groupAbout">关于</div><div class="setting-desc" data-i18n="settings.groupAboutDesc">DSH 状态、检查更新</div></div>
|
|
237
|
-
<span class="sc-arrow">›</span>
|
|
238
254
|
</div>
|
|
239
255
|
</div>
|
|
240
256
|
<div class="settings-group">
|
|
@@ -352,7 +368,7 @@
|
|
|
352
368
|
<label class="switch"><input type="checkbox" id="opt-notify"><span class="slider"></span></label>
|
|
353
369
|
</div>
|
|
354
370
|
<div class="setting-row">
|
|
355
|
-
<div><div class="setting-name" data-i18n="settings.peakRemindTitle">峰谷计费提醒</div><div class="setting-desc" data-i18n="settings.peakRemindDesc"
|
|
371
|
+
<div><div class="setting-name" data-i18n="settings.peakRemindTitle">峰谷计费提醒</div><div class="setting-desc" data-i18n="settings.peakRemindDesc">工作日推送峰谷切换;周末全天谷时,仅 9:00 提醒一次(App 内有效)</div></div>
|
|
356
372
|
<label class="switch"><input type="checkbox" id="opt-peak-remind"><span class="slider"></span></label>
|
|
357
373
|
</div>
|
|
358
374
|
<div class="setting-row">
|
|
@@ -365,7 +381,7 @@
|
|
|
365
381
|
</div>
|
|
366
382
|
<div class="setting-row">
|
|
367
383
|
<div><div class="setting-name" data-i18n="settings.bgIntervalTitle">轮询间隔</div><div class="setting-desc" data-i18n="settings.bgIntervalDesc">灭屏后系统可能拉长间隔(Doze 平台限制)</div></div>
|
|
368
|
-
<select id="bg-interval"
|
|
384
|
+
<select id="bg-interval" class="setting-select">
|
|
369
385
|
<option value="0.5" data-i18n="settings.bgInterval30s">30 秒</option>
|
|
370
386
|
<option value="1" data-i18n="settings.bgInterval1m">1 分钟</option>
|
|
371
387
|
<option value="5" data-i18n="settings.bgInterval5m">5 分钟</option>
|
|
@@ -414,7 +430,7 @@
|
|
|
414
430
|
<button id="btn-host-describe" class="mini-btn" data-i18n="settings.probe">探测</button>
|
|
415
431
|
</div>
|
|
416
432
|
<div class="setting-row">
|
|
417
|
-
<div><div class="setting-name" data-i18n="settings.dshControlTitle">远程启动 DSH</div><div class="setting-desc" id="dsh-control-desc" data-i18n="settings.dshControlProbing">检查本机服务状态…</div></div>
|
|
433
|
+
<div><div class="setting-name" data-i18n="settings.dshControlTitle">远程启动 DSH</div><div class="setting-desc expanded" id="dsh-control-desc" data-i18n="settings.dshControlProbing">检查本机服务状态…</div><div id="dsh-control-steps" class="dsh-control-steps hidden" aria-live="polite"></div></div>
|
|
418
434
|
<div class="setting-actions">
|
|
419
435
|
<button id="btn-dsh-start" class="mini-btn" data-i18n="settings.dshStart">启动</button>
|
|
420
436
|
<button id="btn-dsh-restart" class="mini-btn" data-i18n="settings.dshRestart">重启</button>
|
|
@@ -458,6 +474,18 @@
|
|
|
458
474
|
</button>
|
|
459
475
|
</div>
|
|
460
476
|
|
|
477
|
+
<!-- 统一应用内选择抽屉:替代 Android WebView 的原生 select 弹窗 -->
|
|
478
|
+
<div id="custom-select-backdrop" class="sheet-backdrop custom-select-backdrop hidden"></div>
|
|
479
|
+
<div id="custom-select-sheet" class="sheet custom-select-sheet hidden" role="dialog" aria-modal="true" aria-labelledby="custom-select-title">
|
|
480
|
+
<div class="sheet-handle" aria-hidden="true"></div>
|
|
481
|
+
<div class="custom-select-head">
|
|
482
|
+
<div id="custom-select-title" class="sheet-title" data-i18n="select.choose">请选择</div>
|
|
483
|
+
<button id="custom-select-close" class="icon-btn" type="button" data-i18n-title="modal.close" data-i18n-aria="modal.close">×</button>
|
|
484
|
+
</div>
|
|
485
|
+
<div id="custom-select-options" class="custom-select-options" role="listbox"></div>
|
|
486
|
+
<button id="custom-select-cancel" class="btn subtle custom-select-cancel" type="button" data-i18n="select.cancel">取消</button>
|
|
487
|
+
</div>
|
|
488
|
+
|
|
461
489
|
<nav class="bottom-nav" aria-label="主导航">
|
|
462
490
|
<div class="nav-wave" aria-hidden="true">
|
|
463
491
|
<svg viewBox="0 0 100 100" preserveAspectRatio="none">
|
|
@@ -531,6 +559,20 @@
|
|
|
531
559
|
</div>
|
|
532
560
|
</div>
|
|
533
561
|
|
|
562
|
+
<!-- 反馈发送成功确认 -->
|
|
563
|
+
<div id="modal-feedback-success" class="modal hidden" role="dialog" aria-modal="true" aria-labelledby="feedback-success-title">
|
|
564
|
+
<div class="modal-card feedback-success-card">
|
|
565
|
+
<div class="feedback-success-icon" aria-hidden="true">
|
|
566
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 12 4 4 8-9"/></svg>
|
|
567
|
+
</div>
|
|
568
|
+
<div id="feedback-success-title" class="modal-title feedback-success-title" data-i18n="feedback.successTitle">反馈发送成功</div>
|
|
569
|
+
<div class="modal-body feedback-success-body" data-i18n="feedback.successBody">服务器已确认收到这条反馈,感谢你的帮助。</div>
|
|
570
|
+
<div class="modal-actions">
|
|
571
|
+
<button id="feedback-success-confirm" class="btn primary" data-i18n="feedback.successConfirm">知道了</button>
|
|
572
|
+
</div>
|
|
573
|
+
</div>
|
|
574
|
+
</div>
|
|
575
|
+
|
|
534
576
|
<!-- 新建工作区模态 -->
|
|
535
577
|
<div id="modal-workspace" class="modal hidden" role="dialog" aria-modal="true">
|
|
536
578
|
<div class="modal-card">
|
|
@@ -547,6 +589,52 @@
|
|
|
547
589
|
</div>
|
|
548
590
|
</div>
|
|
549
591
|
|
|
592
|
+
<!-- 新会话工作区选择 -->
|
|
593
|
+
<div id="modal-new-session" class="modal hidden" role="dialog" aria-modal="true">
|
|
594
|
+
<div class="modal-card">
|
|
595
|
+
<div class="modal-title" data-i18n="newSession.title">新建会话</div>
|
|
596
|
+
<div class="modal-body">
|
|
597
|
+
<label class="field-label" for="new-session-workspace" data-i18n="newSession.workspace">选择工作区</label>
|
|
598
|
+
<select id="new-session-workspace" class="workspace-select full" data-i18n-aria="workspace.select"></select>
|
|
599
|
+
<div class="workspace-name-block">
|
|
600
|
+
<span data-i18n="newSession.name">工作区名称</span>
|
|
601
|
+
<strong id="new-session-workspace-name"></strong>
|
|
602
|
+
</div>
|
|
603
|
+
<div class="workspace-path-block">
|
|
604
|
+
<span data-i18n="newSession.path">工作区地址</span>
|
|
605
|
+
<code id="new-session-workspace-path" class="workspace-path-scroll"></code>
|
|
606
|
+
</div>
|
|
607
|
+
<div id="new-session-empty" class="empty hidden" data-i18n="newSession.noWorkspaces">还没有 DSH 工作区,请先新建工作区。</div>
|
|
608
|
+
</div>
|
|
609
|
+
<div class="modal-actions">
|
|
610
|
+
<button id="new-session-cancel" class="btn subtle" data-i18n="workspace.cancel">取消</button>
|
|
611
|
+
<button id="new-session-create" class="btn primary" data-i18n="newSession.create">创建会话</button>
|
|
612
|
+
</div>
|
|
613
|
+
</div>
|
|
614
|
+
</div>
|
|
615
|
+
|
|
616
|
+
<!-- 文本文件预览 -->
|
|
617
|
+
<div id="modal-file-preview" class="modal hidden" role="dialog" aria-modal="true">
|
|
618
|
+
<div class="modal-card file-preview-card">
|
|
619
|
+
<div class="file-preview-head">
|
|
620
|
+
<div class="modal-title" id="file-preview-title" data-i18n="fs.previewTitle">文件预览</div>
|
|
621
|
+
<button id="file-preview-close" class="icon-btn" data-i18n-title="modal.close" data-i18n-aria="modal.close">×</button>
|
|
622
|
+
</div>
|
|
623
|
+
<code id="file-preview-path" class="workspace-path-scroll file-preview-path"></code>
|
|
624
|
+
<div id="file-preview-tabs" class="file-preview-tabs hidden">
|
|
625
|
+
<button id="file-preview-source-tab" class="mini-btn current" type="button" data-i18n="fs.source">源码</button>
|
|
626
|
+
<button id="file-preview-rendered-tab" class="mini-btn" type="button" data-i18n="fs.preview">预览</button>
|
|
627
|
+
</div>
|
|
628
|
+
<div id="file-preview-loading" class="empty" data-i18n="fs.previewLoading">正在加载文件…</div>
|
|
629
|
+
<pre id="file-preview-source" class="file-preview-source hidden"></pre>
|
|
630
|
+
<div id="file-preview-rendered" class="md file-preview-rendered hidden"></div>
|
|
631
|
+
<div class="modal-actions">
|
|
632
|
+
<button id="file-preview-download" class="btn subtle" data-i18n="fs.download">下载</button>
|
|
633
|
+
<button id="file-preview-done" class="btn primary" data-i18n="modal.close">关闭</button>
|
|
634
|
+
</div>
|
|
635
|
+
</div>
|
|
636
|
+
</div>
|
|
637
|
+
|
|
550
638
|
<div id="modal-archive" class="modal hidden" role="dialog" aria-modal="true">
|
|
551
639
|
<div class="modal-card archive-modal-card">
|
|
552
640
|
<div class="modal-title" data-i18n="session.archiveTitle">确认归档会话</div>
|
|
@@ -634,6 +722,12 @@
|
|
|
634
722
|
<div class="announcement-kicker" data-i18n="announcement.label">公告</div>
|
|
635
723
|
<div id="announcement-title" class="modal-title"></div>
|
|
636
724
|
<div id="announcement-content" class="modal-body announcement-content"></div>
|
|
725
|
+
<div id="announcement-poll" class="announcement-poll hidden">
|
|
726
|
+
<div id="announcement-poll-question" class="announcement-poll-question"></div>
|
|
727
|
+
<div id="announcement-poll-options" class="announcement-poll-options" role="radiogroup"></div>
|
|
728
|
+
<div id="announcement-poll-status" class="announcement-poll-status hidden"></div>
|
|
729
|
+
<button id="announcement-poll-submit" class="btn primary" type="button" data-i18n="announcement.voteSubmit">提交投票</button>
|
|
730
|
+
</div>
|
|
637
731
|
<a id="announcement-action" class="announcement-action hidden" target="_blank" rel="noopener"></a>
|
|
638
732
|
<div class="modal-actions">
|
|
639
733
|
<button id="announcement-later" class="btn subtle" data-i18n="announcement.later">稍后再看</button>
|
|
@@ -663,7 +757,7 @@
|
|
|
663
757
|
'conn.reconnectIn': '重连中 {n}s', 'conn.offline': '离线', 'conn.failed': '连接失败',
|
|
664
758
|
'conn.poll': '轮询', 'conn.pollTitle': '当前网络不支持实时推送,已降级为轮询(延迟数秒)',
|
|
665
759
|
'conn.titleGroup': '{group} · {url}({ms})',
|
|
666
|
-
'common.refreshing': '刷新中…',
|
|
760
|
+
'common.refreshing': '刷新中…', 'select.choose': '请选择', 'select.cancel': '取消',
|
|
667
761
|
'nav.sessions': '会话', 'nav.files': '文件', 'nav.pending': '待办', 'nav.overview': '总览', 'nav.home': '主页', 'nav.stats': '统计', 'nav.settings': '设置',
|
|
668
762
|
'overview.eyebrow': 'SYSTEM OVERVIEW', 'overview.title': '主页', 'overview.subtitle': '实时状态与需要你处理的事项',
|
|
669
763
|
'overview.systemPulse': '系统链路', 'overview.nominal': '系统链路正常', 'overview.degraded': '部分链路需要关注', 'overview.offline': '连接已断开', 'overview.checking': '检查中…', 'overview.components': '{n}/4 个模块在线', 'overview.live': 'LIVE', 'overview.allLinked': '全部链路', 'overview.offlineCore': 'OFFLINE',
|
|
@@ -672,6 +766,8 @@
|
|
|
672
766
|
'overview.activeSessions': '活跃会话', 'overview.connectionMode': '连接模式', 'overview.ws': '实时 WS', 'overview.poll': '降级轮询', 'overview.noActivity': '暂无后台活动', 'overview.noSession': '暂无会话',
|
|
673
767
|
'overview.refresh': '刷新总览', 'overview.none': '暂无事项', 'overview.pendingCount': '{n} 项待处理', 'overview.activeCount': '{n} 个活跃会话',
|
|
674
768
|
'overview.action.openSession': '打开最近会话', 'overview.action.newSession': '新建会话', 'overview.action.attention': '处理待办', 'overview.action.connect': '去设置连接', 'overview.action.refresh': '重新检查连接',
|
|
769
|
+
'overview.communityEyebrow': 'COMMUNITY BOARD', 'overview.communityTitle': '公告与投票', 'overview.communityHistory': '历史公告', 'overview.communityEmpty': '暂无未读公告',
|
|
770
|
+
'overview.communityPoll': '投票', 'overview.communityNotice': '公告', 'overview.communityNew': '新', 'overview.communityVote': '参与投票', 'overview.communityView': '查看公告', 'overview.communityVoted': '已参与',
|
|
675
771
|
'statsPage.title': 'Token 统计',
|
|
676
772
|
'statsPage.todayTokens': '今日 Token', 'statsPage.todayCost': '今日费用', 'statsPage.peakShare': '高峰占比',
|
|
677
773
|
'statsPage.input': '未缓存输入', 'statsPage.cacheRead': '缓存命中', 'statsPage.cacheWrite': '缓存写入', 'statsPage.output': '输出',
|
|
@@ -682,6 +778,8 @@
|
|
|
682
778
|
'wb.unbound': '未绑定工作台', 'wb.bound': '绑定 {title}', 'wb.noProjects': '暂无项目', 'wb.noSessions': '暂无会话', 'wb.newSession': '新会话', 'wb.flatHidden': '工作台会话已收起({n} 个)', 'wb.archivedHidden': '------隐藏已归档会话------', 'wb.archivedShown': '------显示已归档会话------',
|
|
683
779
|
'workspace.createTitle': '新建工作区', 'workspace.createDesc': '将在当前文件目录下创建文件夹,并自动打开新会话。', 'workspace.parent': '父目录', 'workspace.namePlaceholder': '例如:my-project', 'workspace.cancel': '取消', 'workspace.create': '创建并打开', 'workspace.nameRequired': '请输入工作区名称', 'workspace.exists': '该目录已存在', 'workspace.invalidName': '名称不能包含路径分隔符', 'workspace.createFailed': '创建工作区失败:{msg}', 'workspace.created': '工作区已创建', 'workspace.createdNoSession': '工作区已创建,但新会话未能打开',
|
|
684
780
|
'workspace.createTitle': '新建工作区', 'workspace.createDesc': '将在当前文件目录下创建文件夹,并自动打开新会话。', 'workspace.parent': '父目录', 'workspace.namePlaceholder': '例如:my-project', 'workspace.cancel': '取消', 'workspace.create': '创建并打开', 'workspace.nameRequired': '请输入工作区名称', 'workspace.created': '工作区已创建', 'workspace.sessionFailed': '目录已创建,但新会话打开失败:{msg}',
|
|
781
|
+
'workspace.current': '当前工作区', 'workspace.select': '选择工作区', 'workspace.all': '全部工作区', 'workspace.ungrouped': '未分组会话', 'workspace.files': '查看文件', 'workspace.allPath': '显示全部 DSH 工作区中的会话',
|
|
782
|
+
'newSession.title': '新建会话', 'newSession.workspace': '选择工作区', 'newSession.name': '工作区名称', 'newSession.path': '工作区地址', 'newSession.create': '创建会话', 'newSession.noWorkspaces': '还没有 DSH 工作区,请先新建工作区。', 'newSession.chooseWorkspace': '请先选择工作区',
|
|
685
783
|
'sessions.running': '运行中', 'sessions.statRunning': '运行中', 'sessions.statPending': '待处理', 'sessions.statTotal': '会话总数',
|
|
686
784
|
'sessions.sortLabel': '会话排序', 'sessions.sortTime': '按时间', 'sessions.sortWorkspace': '按工作区', 'sessions.workspace': '工作区', 'sessions.workspaceUnknown': '未指定工作区',
|
|
687
785
|
'sessions.queueBadge': '队列 {n}', 'sessions.goalBadge': '目标·{phase}',
|
|
@@ -756,9 +854,10 @@
|
|
|
756
854
|
'question.submitted': '已提交回答', 'question.stale': '提问已不在待处理状态', 'question.submitFailed': '回答提交失败:{msg}',
|
|
757
855
|
'jobs.title': '后台任务', 'jobs.empty': '暂无后台任务',
|
|
758
856
|
'fs.loading': '加载中…', 'fs.up': '返回上级', 'fs.newWorkspace': '新建工作区', 'fs.upload': '上传', 'fs.pause': '暂停', 'fs.resume': '继续', 'fs.cancel': '取消',
|
|
857
|
+
'fs.workspace': 'DSH 工作区', 'fs.root': '文件根目录', 'fs.previewTitle': '文件预览', 'fs.previewLoading': '正在加载文件…', 'fs.previewFailed': '无法预览:{msg}', 'fs.previewUnsupported': '该文件类型暂不支持预览', 'fs.previewTooLarge': '文件超过 1 MB,请下载后查看', 'fs.source': '源码', 'fs.preview': '预览', 'fs.download': '下载',
|
|
759
858
|
'fs.pullDown': '下拉刷新', 'fs.pullRelease': '松开刷新', 'fs.refreshing': '刷新中…',
|
|
760
859
|
'fs.noToken': '未设置令牌', 'fs.goSettings': '请先到「设置」页粘贴网关令牌',
|
|
761
|
-
'fs.notFound': '目录不存在', 'fs.forbidden': '
|
|
860
|
+
'fs.notFound': '目录不存在', 'fs.forbidden': '路径不在允许范围内;DSH 已登记工作区会自动放行,其他目录请配置 DSH_REMOTE_FS_ROOT',
|
|
762
861
|
'fs.loadFailed': '加载失败:{msg}', 'fs.loadFailedToast': '文件列表加载失败:{msg}',
|
|
763
862
|
'fs.emptyDir': '空目录', 'fs.dir': '目录',
|
|
764
863
|
'fs.downloadStarted': '开始下载到「下载/dsh-remote」目录', 'fs.downloadFailed': '无法启动下载:{msg}',
|
|
@@ -801,7 +900,7 @@
|
|
|
801
900
|
'settings.notifyTitle': '通知', 'settings.notifyDesc': '收到审批/提问时推送', 'settings.announcementHistoryTitle': '历史公告', 'settings.announcementHistoryDesc': '查看以前收到的公告', 'settings.announcementHistory': '查看记录',
|
|
802
901
|
'settings.testNotifyTitle': '测试通知', 'settings.testNotifyDesc': '立即排一条 3 秒后的本地通知,用于排查系统通知限制', 'settings.testNotify': '发送测试通知',
|
|
803
902
|
'settings.testNotifySent': '测试通知已排定,3 秒后到达', 'settings.testNotifyFailed': '发送测试通知失败:{msg}', 'settings.testNotifyUnavailable': '测试通知仅在 App 内可用',
|
|
804
|
-
'settings.peakRemindTitle': '峰谷计费提醒', 'settings.peakRemindDesc': '
|
|
903
|
+
'settings.peakRemindTitle': '峰谷计费提醒', 'settings.peakRemindDesc': '工作日推送峰谷切换;周末全天谷时,仅 9:00 提醒一次(App 内有效)',
|
|
805
904
|
'peakRemind.enterPeak': '已进入高峰计费时段', 'peakRemind.enterOff': '已进入空闲计费时段',
|
|
806
905
|
'peakRemind.peak0912': '高峰 9:00-12:00', 'peakRemind.off1214': '空闲 12:00-14:00',
|
|
807
906
|
'peakRemind.peak1418': '高峰 14:00-18:00', 'peakRemind.off1809': '空闲 18:00-次日 9:00',
|
|
@@ -828,7 +927,11 @@
|
|
|
828
927
|
'theme.panelTitle': '选择配色', 'theme.close': '关闭',
|
|
829
928
|
'settings.tokenTitle': '访问令牌', 'settings.change': '更换',
|
|
830
929
|
'settings.hostTitle': 'DSH 状态', 'settings.hostProbing': '探测中…', 'settings.probe': '探测', 'settings.probeFailed': '探测失败',
|
|
831
|
-
'settings.dshControlTitle': '远程启动 DSH', 'settings.dshControlProbing': '
|
|
930
|
+
'settings.dshControlTitle': '远程启动 DSH', 'settings.dshControlProbing': '正在向网关查询本机 systemd 服务…', 'settings.dshRunning': '运行中', 'settings.dshStopped': '已停止', 'settings.dshUnsupported': '当前系统未配置可控的 DSH 服务', 'settings.dshStart': '启动', 'settings.dshRestart': '重启', 'settings.dshStarting': '正在{action} DSH…', 'settings.dshStarted': 'DSH 已{action}', 'settings.dshFailed': 'DSH 操作失败:{msg}',
|
|
931
|
+
'settings.dshRunningDetail': '运行中 · {service} · PID {pid} · {state}', 'settings.dshStoppedDetail': '已停止 · {service} · {state}', 'settings.dshStatusFailed': '服务状态查询失败:{msg}',
|
|
932
|
+
'settings.dshStageQueued': '请求已到达网关,等待检查服务', 'settings.dshStageChecking': '正在检查 systemd 用户服务 {service}', 'settings.dshStageCommand': '服务已确认,正在提交{action}命令', 'settings.dshStageWaitingService': '命令已接受,等待服务进程运行({seconds} 秒)', 'settings.dshStageWaitingUpstream': '服务进程已运行,等待 DSH HTTP 接口恢复({seconds} 秒)', 'settings.dshStageWaitingEvents': 'DSH HTTP 已恢复,等待实时消息通道连接({seconds} 秒)',
|
|
933
|
+
'settings.dshSuccessDetail': 'DSH {action}成功 · PID {pid} · HTTP {status} · 用时 {seconds} 秒', 'settings.dshAlreadyRunning': 'DSH 已在运行 · PID {pid}', 'settings.dshResultUnknown': '与网关的连接在操作中断开,最终结果未知;请重新进入此页查看服务状态',
|
|
934
|
+
'settings.dshErrorServiceNotFound': '未找到 systemd 用户服务 {service},请先安装或配置 DSH_REMOTE_DSH_SERVICE', 'settings.dshErrorInvalidService': 'DSH 服务名配置不合法', 'settings.dshErrorSystemctlNotFound': '系统中找不到 systemctl', 'settings.dshErrorSystemdUnavailable': '无法连接当前用户的 systemd 会话', 'settings.dshErrorPermissionDenied': '当前用户无权控制 DSH 服务', 'settings.dshErrorCommandTimeout': 'systemctl 命令执行超时', 'settings.dshErrorCommandFailed': 'systemctl 拒绝或未能执行 DSH 控制命令', 'settings.dshErrorServiceFailed': 'DSH 服务启动后进入 failed 状态', 'settings.dshErrorServiceTimeout': 'DSH 服务未在限时内进入运行状态', 'settings.dshErrorUpstreamTimeout': 'DSH 进程已运行,但 HTTP 接口未在限时内恢复', 'settings.dshErrorEventsTimeout': 'DSH 服务和 HTTP 已恢复,但实时消息通道未在限时内连接', 'settings.dshErrorOperationNotFound': '网关找不到该操作,可能在期间重启过', 'settings.dshErrorOperationProgress': '已有一个 DSH 启停操作正在执行', 'settings.dshErrorGeneric': '{msg}', 'settings.dshErrorDetail': '详情:{detail}',
|
|
832
935
|
'settings.hostDesc': 'DSH {version} · {cwd} · 附加会话 {n}',
|
|
833
936
|
'settings.updateTitle': '检查更新', 'settings.updateLoading': '加载中…', 'settings.downloadUpdate': '下载并安装更新', 'settings.check': '检查',
|
|
834
937
|
'settings.feedbackTitle': '反馈渠道', 'settings.feedbackDesc': 'GitHub / Gitee / B站:反馈 bug、提建议、唠嗑',
|
|
@@ -842,6 +945,7 @@
|
|
|
842
945
|
'feedback.cancel': '取消', 'feedback.submit': '提交',
|
|
843
946
|
'feedback.empty': '请填写描述内容', 'feedback.tooLong': '描述不能超过 2000 字',
|
|
844
947
|
'feedback.submitted': '已提交,感谢反馈',
|
|
948
|
+
'feedback.successTitle': '反馈发送成功', 'feedback.successBody': '服务器已确认收到这条反馈,感谢你的帮助。', 'feedback.successConfirm': '知道了',
|
|
845
949
|
'feedback.rateLimited': '提交太频繁,请稍后再试', 'feedback.rateLimitedAt': '提交太频繁,请 {n} 秒后再试', 'feedback.submitFailed': '提交失败:{msg}', 'feedback.networkError': '网络错误',
|
|
846
950
|
'settings.resetTitle': '清空本地数据', 'settings.resetDesc': '令牌与缓存', 'settings.reset': '重置',
|
|
847
951
|
'settings.confirmReset': '清除本地令牌、服务器与缓存?', 'settings.notifyDenied': '通知权限未开启',
|
|
@@ -851,6 +955,7 @@
|
|
|
851
955
|
'modal.questionTitle': 'DSH 需要你回答', 'modal.later': '稍后', 'modal.submit': '提交',
|
|
852
956
|
'modal.goalTitle': '目标控制', 'modal.close': '关闭', 'modal.updateGoal': '更新目标',
|
|
853
957
|
'announcement.label': '公告', 'announcement.later': '稍后再看', 'announcement.gotIt': '知道了', 'announcement.open': '查看详情', 'announcement.historyLabel': '公告记录', 'announcement.historyTitle': '历史公告', 'announcement.historyEmpty': '暂无历史公告', 'announcement.close': '关闭', 'announcement.noDate': '未标注日期',
|
|
958
|
+
'announcement.voteSubmit': '提交投票', 'announcement.voteChoose': '请先选择一项', 'announcement.voteThanks': '已投票:{option}', 'announcement.voteFailed': '投票失败:{msg}', 'announcement.voteNetworkError': '网络错误', 'announcement.voteAgainLater': '提交太频繁,请稍后再试', 'announcement.voteFromHistory': '参与投票',
|
|
854
959
|
'modal.statsTitle': '本轮统计',
|
|
855
960
|
'time.justNow': '刚刚', 'time.minAgo': ' 分钟前', 'time.hourAgo': ' 小时前'
|
|
856
961
|
},
|
|
@@ -860,7 +965,7 @@
|
|
|
860
965
|
'conn.reconnectIn': 'Reconnecting {n}s', 'conn.offline': 'Offline', 'conn.failed': 'Connection failed',
|
|
861
966
|
'conn.poll': 'Polling', 'conn.pollTitle': 'Realtime push is unavailable on this network; degraded to polling (a few seconds delay)',
|
|
862
967
|
'conn.titleGroup': '{group} · {url} ({ms})',
|
|
863
|
-
'common.refreshing': 'Refreshing…',
|
|
968
|
+
'common.refreshing': 'Refreshing…', 'select.choose': 'Choose an option', 'select.cancel': 'Cancel',
|
|
864
969
|
'nav.sessions': 'Sessions', 'nav.files': 'Files', 'nav.pending': 'Inbox', 'nav.overview': 'Overview', 'nav.home': 'Home', 'nav.stats': 'Stats', 'nav.settings': 'Settings',
|
|
865
970
|
'overview.eyebrow': 'SYSTEM OVERVIEW', 'overview.title': 'Home', 'overview.subtitle': 'Live status and items needing your attention',
|
|
866
971
|
'overview.systemPulse': 'System pulse', 'overview.nominal': 'System nominal', 'overview.degraded': 'Some links need attention', 'overview.offline': 'Connection offline', 'overview.checking': 'Checking…', 'overview.components': '{n}/4 components online', 'overview.live': 'LIVE', 'overview.allLinked': 'ALL LINKED', 'overview.offlineCore': 'OFFLINE',
|
|
@@ -869,6 +974,8 @@
|
|
|
869
974
|
'overview.activeSessions': 'Active sessions', 'overview.connectionMode': 'Connection mode', 'overview.ws': 'Live WS', 'overview.poll': 'Degraded polling', 'overview.noActivity': 'No background activity', 'overview.noSession': 'No sessions yet',
|
|
870
975
|
'overview.refresh': 'Refresh overview', 'overview.none': 'Nothing pending', 'overview.pendingCount': '{n} pending', 'overview.activeCount': '{n} active sessions',
|
|
871
976
|
'overview.action.openSession': 'Open recent session', 'overview.action.newSession': 'New session', 'overview.action.attention': 'Review pending', 'overview.action.connect': 'Set up connection', 'overview.action.refresh': 'Check connection',
|
|
977
|
+
'overview.communityEyebrow': 'COMMUNITY BOARD', 'overview.communityTitle': 'Announcements & polls', 'overview.communityHistory': 'History', 'overview.communityEmpty': 'No unread announcements',
|
|
978
|
+
'overview.communityPoll': 'Poll', 'overview.communityNotice': 'Notice', 'overview.communityNew': 'New', 'overview.communityVote': 'Vote now', 'overview.communityView': 'View notice', 'overview.communityVoted': 'Voted',
|
|
872
979
|
'statsPage.title': 'Token stats',
|
|
873
980
|
'statsPage.todayTokens': 'Tokens today', 'statsPage.todayCost': 'Cost today', 'statsPage.peakShare': 'Peak share',
|
|
874
981
|
'statsPage.input': 'Uncached input', 'statsPage.cacheRead': 'Cache read', 'statsPage.cacheWrite': 'Cache write', 'statsPage.output': 'Output',
|
|
@@ -879,6 +986,8 @@
|
|
|
879
986
|
'wb.unbound': 'No workbench bound', 'wb.bound': 'Bound {title}', 'wb.noProjects': 'No projects', 'wb.noSessions': 'No sessions', 'wb.newSession': 'New session', 'wb.flatHidden': 'Workbench sessions folded ({n})', 'wb.archivedHidden': '------ Hide archived ------', 'wb.archivedShown': '------ Show archived ------',
|
|
880
987
|
'workspace.createTitle': 'New workspace', 'workspace.createDesc': 'Create a folder in the current file directory and open a new session there.', 'workspace.parent': 'Parent folder', 'workspace.namePlaceholder': 'For example: my-project', 'workspace.cancel': 'Cancel', 'workspace.create': 'Create & open', 'workspace.nameRequired': 'Enter a workspace name', 'workspace.exists': 'That folder already exists', 'workspace.invalidName': 'The name cannot contain path separators', 'workspace.createFailed': 'Could not create workspace: {msg}', 'workspace.created': 'Workspace created', 'workspace.createdNoSession': 'Workspace created, but the new session could not be opened',
|
|
881
988
|
'workspace.createTitle': 'New workspace', 'workspace.createDesc': 'Create a folder in the current file directory and open a new session there.', 'workspace.parent': 'Parent folder', 'workspace.namePlaceholder': 'For example: my-project', 'workspace.cancel': 'Cancel', 'workspace.create': 'Create & open', 'workspace.nameRequired': 'Enter a workspace name', 'workspace.created': 'Workspace created', 'workspace.sessionFailed': 'Folder created, but the new session could not be opened: {msg}',
|
|
989
|
+
'workspace.current': 'Current workspace', 'workspace.select': 'Select workspace', 'workspace.all': 'All workspaces', 'workspace.ungrouped': 'Ungrouped sessions', 'workspace.files': 'View files', 'workspace.allPath': 'Showing sessions from every DSH workspace',
|
|
990
|
+
'newSession.title': 'New session', 'newSession.workspace': 'Choose workspace', 'newSession.name': 'Workspace name', 'newSession.path': 'Workspace path', 'newSession.create': 'Create session', 'newSession.noWorkspaces': 'No DSH workspaces yet. Create a workspace first.', 'newSession.chooseWorkspace': 'Choose a workspace first',
|
|
882
991
|
'sessions.running': 'Running', 'sessions.statRunning': 'Running', 'sessions.statPending': 'Pending', 'sessions.statTotal': 'Sessions',
|
|
883
992
|
'sessions.sortLabel': 'Session sort', 'sessions.sortTime': 'By time', 'sessions.sortWorkspace': 'By workspace', 'sessions.workspace': 'Workspace', 'sessions.workspaceUnknown': 'No workspace',
|
|
884
993
|
'sessions.queueBadge': 'Queue {n}', 'sessions.goalBadge': 'Goal·{phase}',
|
|
@@ -953,9 +1062,10 @@
|
|
|
953
1062
|
'question.submitted': 'Answer submitted', 'question.stale': 'Question is no longer pending', 'question.submitFailed': 'Answer failed: {msg}',
|
|
954
1063
|
'jobs.title': 'Background jobs', 'jobs.empty': 'No background jobs',
|
|
955
1064
|
'fs.loading': 'Loading…', 'fs.up': 'Up one level', 'fs.newWorkspace': 'New workspace', 'fs.upload': 'Upload', 'fs.pause': 'Pause', 'fs.resume': 'Resume', 'fs.cancel': 'Cancel',
|
|
1065
|
+
'fs.workspace': 'DSH workspace', 'fs.root': 'File root', 'fs.previewTitle': 'File preview', 'fs.previewLoading': 'Loading file…', 'fs.previewFailed': 'Could not preview: {msg}', 'fs.previewUnsupported': 'This file type cannot be previewed', 'fs.previewTooLarge': 'File is larger than 1 MB; download it to view', 'fs.source': 'Source', 'fs.preview': 'Preview', 'fs.download': 'Download',
|
|
956
1066
|
'fs.pullDown': 'Pull to refresh', 'fs.pullRelease': 'Release to refresh', 'fs.refreshing': 'Refreshing…',
|
|
957
1067
|
'fs.noToken': 'No token set', 'fs.goSettings': 'Go to Settings and paste the gateway token first',
|
|
958
|
-
'fs.notFound': 'Directory not found', 'fs.forbidden': 'Path is outside the allowed roots',
|
|
1068
|
+
'fs.notFound': 'Directory not found', 'fs.forbidden': 'Path is outside the allowed roots. Registered DSH workspaces are allowed automatically; configure DSH_REMOTE_FS_ROOT for other directories.',
|
|
959
1069
|
'fs.loadFailed': 'Load failed: {msg}', 'fs.loadFailedToast': 'Failed to load file list: {msg}',
|
|
960
1070
|
'fs.emptyDir': 'Empty directory', 'fs.dir': 'Directory',
|
|
961
1071
|
'fs.downloadStarted': 'Downloading to "Download/dsh-remote"', 'fs.downloadFailed': 'Could not start download: {msg}',
|
|
@@ -998,7 +1108,7 @@
|
|
|
998
1108
|
'settings.notifyTitle': 'Notifications', 'settings.notifyDesc': 'Push on approvals / questions', 'settings.announcementHistoryTitle': 'Announcement history', 'settings.announcementHistoryDesc': 'Review announcements you received before', 'settings.announcementHistory': 'View history',
|
|
999
1109
|
'settings.testNotifyTitle': 'Test notification', 'settings.testNotifyDesc': 'Schedule a local notification in 3 seconds to verify the notification pipeline', 'settings.testNotify': 'Send test notification',
|
|
1000
1110
|
'settings.testNotifySent': 'Test notification scheduled, arriving in 3s', 'settings.testNotifyFailed': 'Failed to send test notification: {msg}', 'settings.testNotifyUnavailable': 'Test notification is only available in the app',
|
|
1001
|
-
'settings.peakRemindTitle': 'Peak/off-peak reminders', 'settings.peakRemindDesc': '
|
|
1111
|
+
'settings.peakRemindTitle': 'Peak/off-peak reminders', 'settings.peakRemindDesc': 'Weekday transitions; weekends are off-peak all day with one reminder at 9:00 (app only)',
|
|
1002
1112
|
'peakRemind.enterPeak': 'Peak pricing period started', 'peakRemind.enterOff': 'Off-peak pricing period started',
|
|
1003
1113
|
'peakRemind.peak0912': 'Peak 9:00-12:00', 'peakRemind.off1214': 'Off-peak 12:00-14:00',
|
|
1004
1114
|
'peakRemind.peak1418': 'Peak 14:00-18:00', 'peakRemind.off1809': 'Off-peak 18:00-9:00 next day',
|
|
@@ -1025,7 +1135,11 @@
|
|
|
1025
1135
|
'theme.panelTitle': 'Choose theme', 'theme.close': 'Close',
|
|
1026
1136
|
'settings.tokenTitle': 'Access token', 'settings.change': 'Change',
|
|
1027
1137
|
'settings.hostTitle': 'DSH status', 'settings.hostProbing': 'Probing…', 'settings.probe': 'Probe', 'settings.probeFailed': 'Probe failed',
|
|
1028
|
-
'settings.dshControlTitle': 'Remote DSH control', 'settings.dshControlProbing': '
|
|
1138
|
+
'settings.dshControlTitle': 'Remote DSH control', 'settings.dshControlProbing': 'Querying the gateway for the local systemd service…', 'settings.dshRunning': 'Running', 'settings.dshStopped': 'Stopped', 'settings.dshUnsupported': 'No controllable DSH service is configured', 'settings.dshStart': 'Start', 'settings.dshRestart': 'Restart', 'settings.dshStarting': '{action}ing DSH…', 'settings.dshStarted': 'DSH {action}ed', 'settings.dshFailed': 'DSH operation failed: {msg}',
|
|
1139
|
+
'settings.dshRunningDetail': 'Running · {service} · PID {pid} · {state}', 'settings.dshStoppedDetail': 'Stopped · {service} · {state}', 'settings.dshStatusFailed': 'Service status query failed: {msg}',
|
|
1140
|
+
'settings.dshStageQueued': 'Request reached the gateway; waiting to inspect the service', 'settings.dshStageChecking': 'Checking systemd user service {service}', 'settings.dshStageCommand': 'Service confirmed; submitting the {action} command', 'settings.dshStageWaitingService': 'Command accepted; waiting for the service process ({seconds}s)', 'settings.dshStageWaitingUpstream': 'Service process is running; waiting for the DSH HTTP endpoint ({seconds}s)', 'settings.dshStageWaitingEvents': 'DSH HTTP is ready; waiting for the realtime message channels ({seconds}s)',
|
|
1141
|
+
'settings.dshSuccessDetail': 'DSH {action} succeeded · PID {pid} · HTTP {status} · {seconds}s', 'settings.dshAlreadyRunning': 'DSH is already running · PID {pid}', 'settings.dshResultUnknown': 'The gateway connection was interrupted during the operation, so the final result is unknown. Reopen this page to check the service state.',
|
|
1142
|
+
'settings.dshErrorServiceNotFound': 'systemd user service {service} was not found. Install it or configure DSH_REMOTE_DSH_SERVICE first.', 'settings.dshErrorInvalidService': 'The configured DSH service name is invalid', 'settings.dshErrorSystemctlNotFound': 'systemctl is not available on this host', 'settings.dshErrorSystemdUnavailable': 'Could not connect to the current user systemd session', 'settings.dshErrorPermissionDenied': 'The current user cannot control the DSH service', 'settings.dshErrorCommandTimeout': 'The systemctl command timed out', 'settings.dshErrorCommandFailed': 'systemctl rejected or could not run the DSH control command', 'settings.dshErrorServiceFailed': 'The DSH service entered the failed state after startup', 'settings.dshErrorServiceTimeout': 'The DSH service did not enter the running state before timeout', 'settings.dshErrorUpstreamTimeout': 'The DSH process is running, but its HTTP endpoint did not recover before timeout', 'settings.dshErrorEventsTimeout': 'The DSH service and HTTP endpoint recovered, but the realtime message channels did not reconnect before timeout', 'settings.dshErrorOperationNotFound': 'The gateway no longer knows this operation; it may have restarted', 'settings.dshErrorOperationProgress': 'Another DSH start/restart operation is already running', 'settings.dshErrorGeneric': '{msg}', 'settings.dshErrorDetail': 'Detail: {detail}',
|
|
1029
1143
|
'settings.hostDesc': 'DSH {version} · {cwd} · {n} attached sessions',
|
|
1030
1144
|
'settings.updateTitle': 'Check for updates', 'settings.updateLoading': 'Loading…', 'settings.downloadUpdate': 'Download & install update', 'settings.check': 'Check',
|
|
1031
1145
|
'settings.feedbackTitle': 'Feedback', 'settings.feedbackDesc': 'GitHub / Gitee / Bilibili: report bugs, suggest features, or just chat',
|
|
@@ -1039,6 +1153,7 @@
|
|
|
1039
1153
|
'feedback.cancel': 'Cancel', 'feedback.submit': 'Submit',
|
|
1040
1154
|
'feedback.empty': 'Please fill in the description', 'feedback.tooLong': 'Description must be ≤2000 characters',
|
|
1041
1155
|
'feedback.submitted': 'Submitted — thanks!',
|
|
1156
|
+
'feedback.successTitle': 'Feedback sent', 'feedback.successBody': 'The server confirmed receipt of your feedback. Thank you for helping improve DSH Remote.', 'feedback.successConfirm': 'Got it',
|
|
1042
1157
|
'feedback.rateLimited': 'Too frequent, try again later', 'feedback.rateLimitedAt': 'Too frequent, try again in {n}s', 'feedback.submitFailed': 'Submit failed: {msg}', 'feedback.networkError': 'Network error',
|
|
1043
1158
|
'settings.resetTitle': 'Clear local data', 'settings.resetDesc': 'Token and caches', 'settings.reset': 'Reset',
|
|
1044
1159
|
'settings.confirmReset': 'Clear local token, servers and caches?', 'settings.notifyDenied': 'Notification permission not granted',
|
|
@@ -1048,6 +1163,7 @@
|
|
|
1048
1163
|
'modal.questionTitle': 'DSH needs your answer', 'modal.later': 'Later', 'modal.submit': 'Submit',
|
|
1049
1164
|
'modal.goalTitle': 'Goal control', 'modal.close': 'Close', 'modal.updateGoal': 'Update goal',
|
|
1050
1165
|
'announcement.label': 'Announcement', 'announcement.later': 'Later', 'announcement.gotIt': 'Got it', 'announcement.open': 'View details', 'announcement.historyLabel': 'Announcement archive', 'announcement.historyTitle': 'Announcement history', 'announcement.historyEmpty': 'No announcement history', 'announcement.close': 'Close', 'announcement.noDate': 'No date',
|
|
1166
|
+
'announcement.voteSubmit': 'Submit vote', 'announcement.voteChoose': 'Choose an option first', 'announcement.voteThanks': 'Voted: {option}', 'announcement.voteFailed': 'Vote failed: {msg}', 'announcement.voteNetworkError': 'Network error', 'announcement.voteAgainLater': 'Too many submissions; try again later', 'announcement.voteFromHistory': 'Vote now',
|
|
1051
1167
|
'modal.statsTitle': 'This round',
|
|
1052
1168
|
'time.justNow': 'just now', 'time.minAgo': ' min ago', 'time.hourAgo': ' hr ago'
|
|
1053
1169
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
2
|
+
<rect x=".75" y=".75" width="22.5" height="22.5" rx="5" fill="#F6F9FF" stroke="#0F1724" stroke-opacity=".14"/>
|
|
3
|
+
<path d="M10 6l4 4 4-4m-4 4 4 4" fill="none" stroke="#4F7FEF" stroke-width="2.8" stroke-linecap="square" stroke-linejoin="miter"/>
|
|
4
|
+
<path d="M6 10l4 4-4 4m4-4 4 4" fill="none" stroke="#8A64D8" stroke-width="2.8" stroke-linecap="square" stroke-linejoin="miter"/>
|
|
5
|
+
</svg>
|
package/public/styles.css
CHANGED
|
@@ -136,6 +136,30 @@ a.mini-btn { text-decoration: none; display: inline-flex; align-items: center; }
|
|
|
136
136
|
}
|
|
137
137
|
.session-sort:focus { border-color: var(--dsr-accent-line); color: var(--dsr-text); }
|
|
138
138
|
.section-head.small { margin-top: 6px; }
|
|
139
|
+
.workspace-nav, .fs-workspace-nav {
|
|
140
|
+
display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 8px; align-items: center;
|
|
141
|
+
margin: 10px 0; padding: 10px; background: var(--dsr-panel); border: 1px solid var(--dsr-line); border-radius: var(--dsr-radius);
|
|
142
|
+
}
|
|
143
|
+
.workspace-nav > label, .fs-workspace-nav > label, .field-label { color: var(--dsr-muted); font-size: 12px; font-weight: 600; }
|
|
144
|
+
.workspace-select {
|
|
145
|
+
min-width: 0; width: 100%; height: 34px; padding: 0 9px; border-radius: 9px;
|
|
146
|
+
color: var(--dsr-text); background: var(--dsr-bg-2); border: 1px solid var(--dsr-line); font: inherit; font-size: 12.5px; outline: none;
|
|
147
|
+
}
|
|
148
|
+
.workspace-select:focus { border-color: var(--dsr-accent-line); }
|
|
149
|
+
.workspace-select.full { margin: 7px 0 10px; }
|
|
150
|
+
.workspace-path-scroll {
|
|
151
|
+
display: block; min-width: 0; overflow-x: auto; overflow-y: hidden; white-space: nowrap;
|
|
152
|
+
scrollbar-width: thin; touch-action: pan-x; overscroll-behavior-inline: contain;
|
|
153
|
+
color: var(--dsr-text); background: var(--dsr-bg-2); border: 1px solid var(--dsr-line); border-radius: 9px;
|
|
154
|
+
padding: 7px 9px; font-size: 11.5px; user-select: text;
|
|
155
|
+
}
|
|
156
|
+
.workspace-nav > .workspace-path-scroll { grid-column: 1 / -1; }
|
|
157
|
+
.workspace-name-block { display: grid; gap: 6px; margin: 2px 0 10px; color: var(--dsr-muted); font-size: 12px; }
|
|
158
|
+
.workspace-name-block strong {
|
|
159
|
+
min-width: 0; padding: 8px 10px; color: var(--dsr-text); background: var(--dsr-panel); border: 1px solid var(--dsr-line);
|
|
160
|
+
border-radius: 9px; font-size: 14px; line-height: 1.45; overflow-wrap: anywhere; user-select: text;
|
|
161
|
+
}
|
|
162
|
+
.workspace-path-block { display: grid; gap: 6px; margin-top: 2px; color: var(--dsr-muted); font-size: 12px; }
|
|
139
163
|
|
|
140
164
|
/* ---------- Token 统计(移动端) ---------- */
|
|
141
165
|
.stats-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
|
|
@@ -501,9 +525,25 @@ body.in-session .main { padding-bottom: 0; }
|
|
|
501
525
|
.overview-eyebrow { color:var(--dsr-accent-strong); font-size:10px; font-weight:800; letter-spacing:1.7px; line-height:1.3; }
|
|
502
526
|
.overview-title { margin:3px 0 2px; font-size:25px; line-height:1.18; letter-spacing:-.4px; }
|
|
503
527
|
.overview-subtitle { margin:0; color:var(--dsr-muted); font-size:12px; }
|
|
504
|
-
.overview-refresh { width:34px; height:34px; padding:0; border-radius:11px; font-size:18px; line-height:1; }
|
|
528
|
+
.overview-refresh { width:34px; height:34px; padding:0; display:grid; place-items:center; border-radius:11px; font-size:18px; line-height:1; }
|
|
505
529
|
.overview-refresh { color: var(--dsr-accent-strong); }
|
|
506
530
|
.overview-refresh svg { width:17px; height:17px; display:block; }
|
|
531
|
+
.overview-board { margin-bottom:14px; padding:14px; border:1px solid var(--dsr-accent-line); border-radius:16px; background:linear-gradient(145deg,var(--dsr-accent-soft),var(--dsr-panel) 55%,var(--dsr-bg-2)); box-shadow:0 8px 22px var(--dsr-shadow); }
|
|
532
|
+
.overview-board-head { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:11px; }
|
|
533
|
+
.overview-board-head h2 { margin:3px 0 0; color:var(--dsr-text); font-size:18px; line-height:1.25; letter-spacing:-.2px; }
|
|
534
|
+
.overview-announcement-list { display:grid; gap:8px; }
|
|
535
|
+
.overview-announcement-card { width:100%; min-width:0; display:block; padding:12px; border:1px solid var(--dsr-line); border-radius:13px; background:var(--dsr-bg-2); color:var(--dsr-text); text-align:left; cursor:pointer; }
|
|
536
|
+
.overview-announcement-card.poll { border-color:var(--dsr-accent-line); }
|
|
537
|
+
.overview-announcement-card:active { background:var(--dsr-panel-2); }
|
|
538
|
+
.overview-announcement-meta { display:flex; align-items:center; gap:7px; min-width:0; margin-bottom:7px; color:var(--dsr-muted); font-size:10.5px; }
|
|
539
|
+
.overview-announcement-badge { flex:0 0 auto; padding:2px 7px; border-radius:999px; background:var(--dsr-panel); border:1px solid var(--dsr-line); color:var(--dsr-muted); font-size:10px; font-weight:750; }
|
|
540
|
+
.overview-announcement-card.poll .overview-announcement-badge { background:var(--dsr-accent-soft); border-color:var(--dsr-accent-line); color:var(--dsr-accent-strong); }
|
|
541
|
+
.overview-announcement-new { flex:0 0 auto; padding:1px 6px; border-radius:999px; background:var(--dsr-error-soft); color:var(--dsr-error); font-size:9.5px; font-weight:800; }
|
|
542
|
+
.overview-announcement-date { min-width:0; margin-left:auto; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
543
|
+
.overview-announcement-title { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13.5px; font-weight:750; }
|
|
544
|
+
.overview-announcement-copy { display:-webkit-box; margin-top:4px; overflow:hidden; -webkit-box-orient:vertical; -webkit-line-clamp:2; color:var(--dsr-muted); font-size:11.5px; line-height:1.55; }
|
|
545
|
+
.overview-announcement-footer { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-top:10px; padding-top:8px; border-top:1px solid var(--dsr-line); color:var(--dsr-accent-strong); font-size:11px; font-weight:700; }
|
|
546
|
+
.overview-announcement-footer span:last-child { flex:0 0 auto; font-size:16px; font-weight:500; }
|
|
507
547
|
.overview-pulse-card { position:relative; overflow:hidden; display:grid; grid-template-columns:minmax(0,1fr) auto; gap:8px 12px; align-items:center; padding:14px; margin-bottom:14px; border:1px solid var(--dsr-accent-line); border-radius:16px; background:linear-gradient(135deg,var(--dsr-panel),var(--dsr-bg-2)); box-shadow:0 10px 26px var(--dsr-shadow); }
|
|
508
548
|
.overview-pulse-card::after { content:""; position:absolute; width:110px; height:110px; right:-45px; top:-55px; border-radius:50%; background:var(--dsr-accent-soft); filter:blur(3px); pointer-events:none; }
|
|
509
549
|
.overview-pulse-copy { min-width:0; align-self:start; }
|
|
@@ -570,6 +610,7 @@ button.overview-attention-item, button.overview-session-item { cursor:pointer; }
|
|
|
570
610
|
|
|
571
611
|
/* ---------- 文件传输 ---------- */
|
|
572
612
|
.fs-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
|
|
613
|
+
.fs-workspace-nav { grid-template-columns: auto minmax(0, 1fr); margin-top: 0; }
|
|
573
614
|
.fs-path {
|
|
574
615
|
flex: 1 1 150px; min-width: 0; font-size: 12.5px; color: var(--dsr-muted);
|
|
575
616
|
background: var(--dsr-panel); border: 1px solid var(--dsr-line); border-radius: 10px;
|
|
@@ -611,6 +652,19 @@ button.overview-attention-item, button.overview-session-item { cursor:pointer; }
|
|
|
611
652
|
}
|
|
612
653
|
.fs-sub { font-size: 12px; color: var(--dsr-muted); margin-top: 1px; }
|
|
613
654
|
.fs-arrow { flex-shrink: 0; color: var(--dsr-muted); font-size: 18px; }
|
|
655
|
+
.file-preview-card { max-width: 760px; height: min(82vh, 760px); display: flex; flex-direction: column; overflow: hidden; }
|
|
656
|
+
.file-preview-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
|
|
657
|
+
.file-preview-head .modal-title { margin-bottom: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
658
|
+
.file-preview-path { margin: 10px 0; flex-shrink: 0; }
|
|
659
|
+
.file-preview-tabs { display: flex; gap: 7px; margin-bottom: 8px; flex-shrink: 0; }
|
|
660
|
+
.file-preview-tabs .current { border-color: var(--dsr-accent-line); color: var(--dsr-accent-strong); background: var(--dsr-accent-soft); }
|
|
661
|
+
.file-preview-source, .file-preview-rendered {
|
|
662
|
+
flex: 1; min-height: 0; overflow: auto; margin: 0; padding: 12px; border-radius: 10px;
|
|
663
|
+
color: var(--dsr-text); background: var(--dsr-panel); border: 1px solid var(--dsr-line); font-size: 12.5px; line-height: 1.55;
|
|
664
|
+
}
|
|
665
|
+
.file-preview-source { white-space: pre; tab-size: 2; }
|
|
666
|
+
.file-preview-rendered { overflow-wrap: anywhere; }
|
|
667
|
+
.file-preview-card > .modal-actions { flex-shrink: 0; }
|
|
614
668
|
|
|
615
669
|
/* ---------- 设置 ---------- */
|
|
616
670
|
.settings-group {
|
|
@@ -628,6 +682,13 @@ button.overview-attention-item, button.overview-session-item { cursor:pointer; }
|
|
|
628
682
|
.setting-desc.expanded { white-space: normal; overflow: visible; text-overflow: clip; word-break: break-word; }
|
|
629
683
|
.setting-select { min-width: 112px; max-width: 145px; padding: 7px 9px; border-radius: 10px; border: 1px solid var(--dsr-line); background: var(--dsr-bg-2); color: var(--dsr-text); font: inherit; font-size: 12px; }
|
|
630
684
|
.setting-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
|
|
685
|
+
.dsh-control-steps { display:flex; flex-direction:column; gap:5px; margin-top:8px; padding:8px 9px; border:1px solid var(--dsr-line); border-radius:10px; background:var(--dsr-bg-2); }
|
|
686
|
+
.dsh-control-step { display:grid; grid-template-columns:16px minmax(0,1fr); gap:6px; align-items:start; color:var(--dsr-muted); font-size:11px; line-height:1.45; }
|
|
687
|
+
.dsh-control-step.current { color:var(--dsr-accent-strong); }
|
|
688
|
+
.dsh-control-step.success { color:var(--dsr-success); }
|
|
689
|
+
.dsh-control-step.failed { color:var(--dsr-error); }
|
|
690
|
+
.dsh-control-step-mark { text-align:center; font-weight:800; }
|
|
691
|
+
.dsh-control-step-detail { grid-column:2; color:var(--dsr-muted); white-space:pre-wrap; overflow-wrap:anywhere; }
|
|
631
692
|
.about { text-align: center; color: var(--dsr-muted); font-size: 12px; margin-top: 16px; line-height: 1.8; }
|
|
632
693
|
|
|
633
694
|
/* 多服务器列表(分组) */
|
|
@@ -775,6 +836,45 @@ button.overview-attention-item, button.overview-session-item { cursor:pointer; }
|
|
|
775
836
|
@keyframes sheet-fade { from { opacity: 0 } to { opacity: 1 } }
|
|
776
837
|
@keyframes sheet-up { from { transform: translateY(24px); opacity: .6 } to { transform: translateY(0); opacity: 1 } }
|
|
777
838
|
|
|
839
|
+
/* ---------- 应用内选择抽屉 ---------- */
|
|
840
|
+
.custom-select-native {
|
|
841
|
+
position: fixed !important; left: -10000px !important; width: 1px !important; height: 1px !important;
|
|
842
|
+
opacity: 0 !important; pointer-events: none !important;
|
|
843
|
+
}
|
|
844
|
+
.custom-select-trigger {
|
|
845
|
+
min-width: 0; height: 34px; display: flex; align-items: center; justify-content: space-between; gap: 8px;
|
|
846
|
+
padding: 0 10px; border: 1px solid var(--dsr-line); border-radius: 9px;
|
|
847
|
+
color: var(--dsr-text); background: var(--dsr-bg-2); font: inherit; font-size: 12.5px;
|
|
848
|
+
text-align: left; cursor: pointer; outline: none;
|
|
849
|
+
}
|
|
850
|
+
.custom-select-trigger::after { content: '⌄'; flex: 0 0 auto; color: var(--dsr-muted); font-size: 14px; transform: translateY(-1px); }
|
|
851
|
+
.custom-select-trigger:focus-visible { border-color: var(--dsr-accent-line); box-shadow: 0 0 0 2px var(--dsr-accent-soft); }
|
|
852
|
+
.custom-select-trigger:disabled { opacity: .48; cursor: default; }
|
|
853
|
+
.custom-select-trigger-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
854
|
+
.workspace-select-trigger { width: 100%; }
|
|
855
|
+
.workspace-select-trigger.full { margin: 7px 0 10px; }
|
|
856
|
+
.session-sort-trigger { height: 30px; max-width: 112px; color: var(--dsr-muted); background: var(--dsr-panel); font-size: 11px; }
|
|
857
|
+
.setting-select-trigger { min-width: 112px; max-width: 145px; }
|
|
858
|
+
.custom-select-backdrop { z-index: 79; }
|
|
859
|
+
.custom-select-sheet { z-index: 80; max-height: min(72vh, 620px); overflow: hidden; display: flex; flex-direction: column; }
|
|
860
|
+
.custom-select-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
|
|
861
|
+
.custom-select-head .sheet-title { min-width: 0; margin: 0; padding-bottom: 8px; }
|
|
862
|
+
.custom-select-head .icon-btn { width: 34px; height: 34px; flex: 0 0 auto; }
|
|
863
|
+
.custom-select-options { min-height: 48px; overflow-y: auto; overscroll-behavior: contain; display: grid; gap: 5px; padding: 2px 0 8px; }
|
|
864
|
+
.custom-select-option {
|
|
865
|
+
width: 100%; min-height: 52px; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 10px;
|
|
866
|
+
padding: 9px 11px; border: 1px solid transparent; border-radius: 13px;
|
|
867
|
+
color: var(--dsr-text); background: transparent; font: inherit; text-align: left; cursor: pointer;
|
|
868
|
+
}
|
|
869
|
+
.custom-select-option:focus-visible, .custom-select-option:active { background: var(--dsr-panel); border-color: var(--dsr-line); outline: none; }
|
|
870
|
+
.custom-select-option.current { background: var(--dsr-accent-soft); border-color: var(--dsr-accent-line); }
|
|
871
|
+
.custom-select-option:disabled { opacity: .45; cursor: default; }
|
|
872
|
+
.custom-select-option-copy { min-width: 0; display: grid; gap: 3px; }
|
|
873
|
+
.custom-select-option-name { font-size: 14px; font-weight: 650; overflow-wrap: anywhere; }
|
|
874
|
+
.custom-select-option-path { color: var(--dsr-muted); font-size: 11.5px; line-height: 1.45; overflow-wrap: anywhere; }
|
|
875
|
+
.custom-select-option-check { width: 24px; color: var(--dsr-accent-strong); font-size: 18px; font-weight: 800; text-align: center; }
|
|
876
|
+
.custom-select-cancel { flex: 0 0 auto; width: 100%; margin-top: 2px; }
|
|
877
|
+
|
|
778
878
|
/* 写反馈弹层 */
|
|
779
879
|
.fb-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
|
|
780
880
|
.fb-chip {
|
|
@@ -789,6 +889,16 @@ button.overview-attention-item, button.overview-session-item { cursor:pointer; }
|
|
|
789
889
|
}
|
|
790
890
|
.fb-textarea:focus, .fb-input:focus { border-color: var(--dsr-accent-line); }
|
|
791
891
|
.fb-input { min-height: 42px; }
|
|
892
|
+
.feedback-success-card { max-width: 360px; text-align: center; padding: 22px 20px 18px; }
|
|
893
|
+
.feedback-success-icon {
|
|
894
|
+
width: 52px; height: 52px; display: grid; place-items: center; margin: 0 auto 13px; border-radius: 50%;
|
|
895
|
+
color: var(--dsr-success); background: var(--dsr-success-soft); border: 1px solid var(--dsr-success-line);
|
|
896
|
+
}
|
|
897
|
+
.feedback-success-icon svg { width: 28px; height: 28px; }
|
|
898
|
+
.feedback-success-title { margin-bottom: 8px; font-size: 18px; }
|
|
899
|
+
.feedback-success-body { color: var(--dsr-muted); line-height: 1.65; }
|
|
900
|
+
.feedback-success-card .modal-actions { justify-content: stretch; }
|
|
901
|
+
.feedback-success-card .modal-actions .btn { flex: 1; min-height: 42px; }
|
|
792
902
|
|
|
793
903
|
/* ---------- 模态 ---------- */
|
|
794
904
|
.modal {
|
|
@@ -827,6 +937,16 @@ button.overview-attention-item, button.overview-session-item { cursor:pointer; }
|
|
|
827
937
|
.announcement-card { border-top: 3px solid var(--dsr-accent); }
|
|
828
938
|
.announcement-kicker { color: var(--dsr-accent-strong); font-size: 12px; font-weight: 700; letter-spacing: .04em; margin-bottom: 6px; }
|
|
829
939
|
.announcement-content { line-height: 1.7; overflow-wrap: anywhere; word-break: break-word; }
|
|
940
|
+
.announcement-poll { display: grid; gap: 10px; margin-top: 14px; padding: 12px; border: 1px solid var(--dsr-line); border-radius: 12px; background: var(--dsr-panel); }
|
|
941
|
+
.announcement-poll-question { font-size: 14px; font-weight: 700; line-height: 1.5; }
|
|
942
|
+
.announcement-poll-options { display: grid; gap: 7px; }
|
|
943
|
+
.announcement-poll-option { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 9px; align-items: start; padding: 10px; border: 1px solid var(--dsr-line); border-radius: 10px; background: var(--dsr-bg-2); cursor: pointer; }
|
|
944
|
+
.announcement-poll-option:has(input:checked) { border-color: var(--dsr-accent-line); background: var(--dsr-accent-soft); }
|
|
945
|
+
.announcement-poll-option input { margin-top: 3px; accent-color: var(--dsr-accent); }
|
|
946
|
+
.announcement-poll-option strong { display: block; font-size: 13px; line-height: 1.45; }
|
|
947
|
+
.announcement-poll-option small { display: block; margin-top: 2px; color: var(--dsr-muted); font-size: 11.5px; line-height: 1.45; }
|
|
948
|
+
.announcement-poll-status { color: var(--dsr-accent-strong); font-size: 12.5px; font-weight: 650; }
|
|
949
|
+
.announcement-poll > .btn { justify-self: stretch; }
|
|
830
950
|
.announcement-action { display: inline-block; margin-top: 12px; color: var(--dsr-accent-strong); font-size: 13px; font-weight: 600; text-decoration: none; }
|
|
831
951
|
.announcement-action:hover { text-decoration: underline; }
|
|
832
952
|
.announcement-history-card { max-width: 520px; }
|
|
@@ -857,6 +977,11 @@ button.overview-attention-item, button.overview-session-item { cursor:pointer; }
|
|
|
857
977
|
.topbar-right .topbar-btn.conn-badge { max-width: 72px; padding-left: 8px; padding-right: 8px; overflow: hidden; text-overflow: ellipsis; }
|
|
858
978
|
.setting-row { align-items: flex-start; flex-wrap: wrap; }
|
|
859
979
|
.setting-row > .setting-actions { width: 100%; justify-content: flex-end; }
|
|
980
|
+
.workspace-nav { grid-template-columns: minmax(0, 1fr) auto; }
|
|
981
|
+
.workspace-nav > label { grid-column: 1 / -1; }
|
|
982
|
+
.workspace-nav > .workspace-path-scroll { grid-column: 1 / -1; }
|
|
983
|
+
.fs-workspace-nav { grid-template-columns: 1fr; }
|
|
984
|
+
.file-preview-card { height: 88vh; padding: 13px; }
|
|
860
985
|
}
|
|
861
986
|
.theme-panel-list { display: flex; flex-direction: column; gap: 8px; }
|
|
862
987
|
.theme-option {
|