dsh-mobile 0.3.13 → 0.3.14
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/CHANGELOG.md +5 -0
- package/README.en.md +7 -7
- package/README.md +7 -7
- package/lib/client.js +68 -10
- package/lib/client.js.map +1 -1
- package/lib/index.mjs +25 -2
- package/lib/index.mjs.map +1 -1
- package/lib/mobile-layout.js +6 -2
- package/lib/mobile-layout.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
Notable changes to DSH Mobile are recorded here. GitHub Releases remain the source for downloadable packages and complete generated commit notes.
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
## 0.3.14 - 2026-09-08
|
|
7
|
+
|
|
8
|
+
- The panel's “Update plugin” action now shows a preview card first: the latest release notes (fetched from the GitHub releases API, graceful fallback when unavailable) plus fixed upgrade notices (restart DSH after installing; apps and paired devices need no re-pairing; check the README compatibility table when unsure about the desktop version), then explicit Update now / Not now buttons. Notes are served from the release itself, so a user on any older plugin version sees the current guidance before updating.
|
|
9
|
+
- Fixed a regression in 0.3.13: its layout adaptation tracked the harness master branch (which renamed the right details seat to `rightbar`), but the published 0.1.3-alpha.2 host still exposes `details` — so on real hosts the mobile right panel rendered empty. The layout now registers and renders both seat names (`details` with the legacy empty owner share, `rightbar` with resolved column geometry), so the right panel works on 0.1.3-alpha.1, the published 0.1.3-alpha.2, and the master contract alike. The compatibility check still asserts the master (`rightbar`) contract.
|
|
10
|
+
|
|
6
11
|
## 0.3.13 - 2026-09-08
|
|
7
12
|
|
|
8
13
|
- Third-party WebSocket approval is interception-driven and generic: whenever a plugin's WebSocket connection is blocked, the diagnostics view groups the rejected paths by directory with attempt counts and offers per-path or allow-all approval, behind the same local-admin trust as pairing, and both the sidebar entry and the in-panel diagnostics button carry a red badge until reviewed. Manual path entry is tucked under an “advanced” disclosure that most users never need to open (thanks @idoall for reporting #47). Badge changes are announced to screen readers and the disclosure has a visible focus ring.
|
package/README.en.md
CHANGED
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
|
|
20
20
|
> DSH Mobile is a DeepSeek Harness community plugin; the native app supports Android only.
|
|
21
21
|
>
|
|
22
|
-
> **0.3.
|
|
22
|
+
> **0.3.14 update**: the 0.3.13 layout regression is fixed (right panel renders on both the published and the newer host contract), and the panel's “Update plugin” action now shows the latest release notes and upgrade notices before updating. Everything 0.3.13 brought stays (interception-driven WebSocket approval #47, panel polish, screen-reader announcements). [Details](CHANGELOG.md).
|
|
23
23
|
>
|
|
24
|
-
> **Upgrade reminder**:
|
|
24
|
+
> **Upgrade reminder**: plugin **0.3.14** is recommended and works on every 0.1.3 desktop release (alpha.1 included). Restart DSH after installing a new plugin. Existing 0.3.3-0.3.13 apps and paired devices remain compatible without re-pairing. [Compatibility notes](#compatibility).
|
|
25
25
|
|
|
26
26
|
<p align="center">
|
|
27
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.
|
|
28
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.
|
|
29
|
-
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.3.
|
|
27
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.14/dsh-mobile-android-v0.3.14.apk"><img src="assets/brand/app-icon-rounded.svg" alt="DSH Mobile Android app icon" width="72" height="72"></a><br>
|
|
28
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.14/dsh-mobile-android-v0.3.14.apk"><strong>Download Android app 0.3.14</strong></a><br>
|
|
29
|
+
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.3.14">Release notes and checksums</a></sub>
|
|
30
30
|
</p>
|
|
31
31
|
|
|
32
32
|
DSH Mobile is a DeepSeek Harness plugin that lets a mobile browser or the Android app connect over a protected LAN or an optional Tailscale Funnel, cpolar, or self-hosted FRP remote path. Local and remote access keep the same sessions, Workspaces, messages, and tools while using separate switches and paired-device stores without modifying DeepSeek Harness source.
|
|
@@ -201,14 +201,14 @@ The table below lists, for each plugin version, the DeepSeek Harness version it
|
|
|
201
201
|
|
|
202
202
|
| DSH Mobile plugin | Verified DeepSeek Harness version |
|
|
203
203
|
| --- | --- |
|
|
204
|
-
| `0.3.
|
|
204
|
+
| `0.3.14` | `0.1.3-alpha.2` |
|
|
205
205
|
| `0.3.9`-`0.3.12` | `0.1.3-alpha.1` |
|
|
206
206
|
| `0.3.6`-`0.3.8` | `0.1.2-rc.1` |
|
|
207
207
|
| `0.3.4`, `0.3.5` | `0.1.2-alpha.2` |
|
|
208
208
|
| `0.3.0`-`0.3.3` | `0.1.2-alpha.1` |
|
|
209
209
|
| `0.1.4`, `0.2.x` | `0.1.1-rc.2` |
|
|
210
210
|
|
|
211
|
-
Existing 0.3.3-0.3.
|
|
211
|
+
Existing 0.3.3-0.3.14 apps do not need re-pairing. Earlier apps use a different status-bar strategy, so updating both is recommended. App 0.1.3 or earlier requires reinstalling and pairing again.
|
|
212
212
|
|
|
213
213
|
## Uninstall
|
|
214
214
|
|
package/README.md
CHANGED
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
|
|
27
27
|
> DSH Mobile 是 DeepSeek Harness 社区插件,原生 App 仅支持 Android。
|
|
28
28
|
>
|
|
29
|
-
> **0.3.13
|
|
29
|
+
> **0.3.14 更新**:0.3.13 布局回归修复(右栏在已发布与开发线宿主均可显示)+ 面板「更新插件」现在先展示最新版更新内容与注意事项、确认后才更新;0.3.13 功能不变(第三方 WebSocket 一键放行 #47、面板修整、读屏播报)。[详细记录](CHANGELOG.md)。
|
|
30
30
|
>
|
|
31
|
-
>
|
|
31
|
+
> **升级提醒**:推荐升级到插件 **0.3.14**(0.1.3 各版本桌面均适用,含 alpha.1)。安装新插件后需重启 DSH。现有 0.3.3-0.3.13 App 可继续使用,无需重新配对。[兼容说明](#兼容性)。
|
|
32
32
|
|
|
33
33
|
<p align="center">
|
|
34
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.
|
|
35
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.
|
|
36
|
-
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.3.
|
|
34
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.14/dsh-mobile-android-v0.3.14.apk"><img src="assets/brand/app-icon-rounded.svg" alt="DSH Mobile 安卓应用图标" width="72" height="72"></a><br>
|
|
35
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.14/dsh-mobile-android-v0.3.14.apk"><strong>下载 Android App 0.3.14</strong></a><br>
|
|
36
|
+
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.3.14">版本说明与校验文件</a></sub>
|
|
37
37
|
</p>
|
|
38
38
|
|
|
39
39
|
DSH Mobile 是一个 DeepSeek Harness 插件,让手机浏览器或 Android App 通过局域网,或可选的 Tailscale Funnel、cpolar、自建 FRP 远程通道连接电脑,继续使用同一份会话、工作区、消息和工具。局域网与远程访问分别启停、分别管理设备,且都不修改 DeepSeek Harness 源码。
|
|
@@ -210,14 +210,14 @@ flowchart LR
|
|
|
210
210
|
|
|
211
211
|
| DSH Mobile 插件 | 验证支持的 DeepSeek Harness 版本 |
|
|
212
212
|
| --- | --- |
|
|
213
|
-
| `0.3.
|
|
213
|
+
| `0.3.14` | `0.1.3-alpha.2` |
|
|
214
214
|
| `0.3.9`-`0.3.12` | `0.1.3-alpha.1` |
|
|
215
215
|
| `0.3.6`-`0.3.8` | `0.1.2-rc.1` |
|
|
216
216
|
| `0.3.4`、`0.3.5` | `0.1.2-alpha.2` |
|
|
217
217
|
| `0.3.0`-`0.3.3` | `0.1.2-alpha.1` |
|
|
218
218
|
| `0.1.4`、`0.2.x` | `0.1.1-rc.2` |
|
|
219
219
|
|
|
220
|
-
现有 0.3.3-0.3.
|
|
220
|
+
现有 0.3.3-0.3.14 App 无需重新配对;更早的 App 使用不同的状态栏策略,建议同步升级;App 0.1.3 及更早版本需卸载重装并重新配对。
|
|
221
221
|
|
|
222
222
|
## 卸载
|
|
223
223
|
|
package/lib/client.js
CHANGED
|
@@ -19,6 +19,12 @@ window.__ModuleLoader__.load({
|
|
|
19
19
|
updatingPlugin: "Updating…",
|
|
20
20
|
pluginUpdatedRestart: "Updated to v{version}. Restart DSH to apply it.",
|
|
21
21
|
pluginUpdateFailed: "Update failed: {error}",
|
|
22
|
+
updateTo: "Update to v{version}",
|
|
23
|
+
updateNotesHeading: "What’s new",
|
|
24
|
+
updateNotice: "Restart DSH after installing. Existing apps and paired devices need no re-pairing; unsure about the desktop version? Check the README compatibility table.",
|
|
25
|
+
updateNotesEmpty: "No release notes fetched — updating is still fine; full details on the GitHub Release page.",
|
|
26
|
+
updateNow: "Update now",
|
|
27
|
+
updateLater: "Not now",
|
|
22
28
|
lan: "Local network",
|
|
23
29
|
remote: "Remote",
|
|
24
30
|
lanAccess: "Local network access",
|
|
@@ -180,6 +186,12 @@ window.__ModuleLoader__.load({
|
|
|
180
186
|
updatingPlugin: "Aggiornamento…",
|
|
181
187
|
pluginUpdatedRestart: "Aggiornato alla v{version}. Riavvia DSH per applicarlo.",
|
|
182
188
|
pluginUpdateFailed: "Aggiornamento non riuscito: {error}",
|
|
189
|
+
updateTo: "Aggiorna alla v{version}",
|
|
190
|
+
updateNotesHeading: "Novità",
|
|
191
|
+
updateNotice: "Riavvia DSH dopo l’installazione. Le app esistenti e i dispositivi già associati non richiedono ri-associazione; in caso di dubbi sulla versione desktop, consulta la tabella di compatibilità nel README.",
|
|
192
|
+
updateNotesEmpty: "Note di rilascio non recuperate — l’aggiornamento resta possibile; dettagli nella pagina Release su GitHub.",
|
|
193
|
+
updateNow: "Aggiorna ora",
|
|
194
|
+
updateLater: "Non ora",
|
|
183
195
|
lan: "Rete locale",
|
|
184
196
|
remote: "Remoto",
|
|
185
197
|
lanAccess: "Accesso rete locale",
|
|
@@ -343,6 +355,12 @@ window.__ModuleLoader__.load({
|
|
|
343
355
|
updatingPlugin: "正在更新…",
|
|
344
356
|
pluginUpdatedRestart: "插件已更新至 v{version},重启 DSH 后生效。",
|
|
345
357
|
pluginUpdateFailed: "更新失败:{error}",
|
|
358
|
+
updateTo: "更新到 v{version}",
|
|
359
|
+
updateNotesHeading: "更新内容",
|
|
360
|
+
updateNotice: "安装后需重启 DSH。现有 App 与已配对设备无需重新配对;电脑端版本不确定时,先对照 README 兼容表。",
|
|
361
|
+
updateNotesEmpty: "未取到最新版更新说明,仍可继续更新;详情见 GitHub Release 页。",
|
|
362
|
+
updateNow: "立即更新",
|
|
363
|
+
updateLater: "暂不",
|
|
346
364
|
lan: "局域网",
|
|
347
365
|
remote: "远程",
|
|
348
366
|
lanAccess: "局域网访问",
|
|
@@ -2019,7 +2037,8 @@ window.__ModuleLoader__.load({
|
|
|
2019
2037
|
updateAvailable: data.updateAvailable === true && latestVersion !== void 0,
|
|
2020
2038
|
...latestVersion === void 0 ? {} : { latestVersion },
|
|
2021
2039
|
...androidVersion === void 0 ? {} : { androidVersion },
|
|
2022
|
-
androidDownloadUrl
|
|
2040
|
+
androidDownloadUrl,
|
|
2041
|
+
...typeof data.releaseNotes === "string" && data.releaseNotes !== "" ? { releaseNotes: data.releaseNotes.slice(0, 4e3) } : {}
|
|
2023
2042
|
};
|
|
2024
2043
|
}
|
|
2025
2044
|
async function requestJson(path, init, timeoutMs = CONTROL_REQUEST_TIMEOUT_MS) {
|
|
@@ -2094,6 +2113,22 @@ window.__ModuleLoader__.load({
|
|
|
2094
2113
|
updatePlugin.type = "button";
|
|
2095
2114
|
updatePlugin.textContent = t("updatePlugin");
|
|
2096
2115
|
updatePlugin.hidden = true;
|
|
2116
|
+
const updateCard = element("div", "dsh-mobile-control__update-card");
|
|
2117
|
+
updateCard.hidden = true;
|
|
2118
|
+
const updateCardTitle = element("div", "dsh-mobile-control__update-card-title");
|
|
2119
|
+
const updateCardNotes = element("pre", "dsh-mobile-control__update-notes");
|
|
2120
|
+
updateCardNotes.setAttribute("tabindex", "0");
|
|
2121
|
+
const updateCardNotice = element("p", "dsh-mobile-control__update-notice");
|
|
2122
|
+
updateCardNotice.textContent = t("updateNotice");
|
|
2123
|
+
const updateActions = element("div", "dsh-mobile-control__update-actions");
|
|
2124
|
+
const updateNow = element("button", "dsh-mobile-control__primary");
|
|
2125
|
+
updateNow.type = "button";
|
|
2126
|
+
updateNow.textContent = t("updateNow");
|
|
2127
|
+
const updateLater = element("button", "dsh-mobile-control__secondary");
|
|
2128
|
+
updateLater.type = "button";
|
|
2129
|
+
updateLater.textContent = t("updateLater");
|
|
2130
|
+
updateActions.append(updateLater, updateNow);
|
|
2131
|
+
updateCard.append(updateCardTitle, updateCardNotes, updateCardNotice, updateActions);
|
|
2097
2132
|
const diagnosticsEntry = element("button", "dsh-mobile-control__diagnostic-entry");
|
|
2098
2133
|
diagnosticsEntry.type = "button";
|
|
2099
2134
|
diagnosticsEntry.textContent = t("diagnostics");
|
|
@@ -2800,7 +2835,7 @@ window.__ModuleLoader__.load({
|
|
|
2800
2835
|
lanView.append(access, qrBox, status, extensionStatus, actions, manageRow, devicePanel);
|
|
2801
2836
|
remoteView.append(remoteIntro, providerSection, remoteWorkspace);
|
|
2802
2837
|
diagnosticsView.append(diagnosticsIntro, diagnosticsSummary, diagnosticsToolbar, diagnosticsFeedback, diagnosticsChecks, wsPathsSection, diagnosticsDetails);
|
|
2803
|
-
panel.append(header, releaseNotice, appDownload, switcher, lanView, remoteView, diagnosticsView);
|
|
2838
|
+
panel.append(header, releaseNotice, updateCard, appDownload, switcher, lanView, remoteView, diagnosticsView);
|
|
2804
2839
|
root.append(panel);
|
|
2805
2840
|
document.body.append(root);
|
|
2806
2841
|
let running = false;
|
|
@@ -2830,11 +2865,14 @@ window.__ModuleLoader__.load({
|
|
|
2830
2865
|
let copiedDiagnosticReport = "";
|
|
2831
2866
|
let pluginUpdateAvailable = false;
|
|
2832
2867
|
let pluginLatestVersion = "";
|
|
2868
|
+
let pluginReleaseNotes = "";
|
|
2869
|
+
let updateInFlight = false;
|
|
2833
2870
|
const renderRelease = (data) => {
|
|
2834
2871
|
const release = clientReleaseInfo(data);
|
|
2835
2872
|
pluginUpdateAvailable = release.updateAvailable;
|
|
2836
2873
|
pluginLatestVersion = release.latestVersion ?? "";
|
|
2837
|
-
|
|
2874
|
+
pluginReleaseNotes = release.releaseNotes ?? "";
|
|
2875
|
+
updatePlugin.hidden = !pluginUpdateAvailable || !diagnosticsView.hidden || !updateCard.hidden;
|
|
2838
2876
|
updatePlugin.textContent = t("updatePlugin");
|
|
2839
2877
|
if (pluginLatestVersion !== "") updatePlugin.setAttribute("aria-label", t("updatePluginAria", { version: pluginLatestVersion }));
|
|
2840
2878
|
if (release.androidVersion !== void 0) {
|
|
@@ -3967,10 +4005,16 @@ window.__ModuleLoader__.load({
|
|
|
3967
4005
|
loadDiagnostics();
|
|
3968
4006
|
});
|
|
3969
4007
|
diagnosticsRun.addEventListener("click", loadDiagnostics);
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
updatePlugin.
|
|
3973
|
-
|
|
4008
|
+
const closeUpdateCard = () => {
|
|
4009
|
+
updateCard.hidden = true;
|
|
4010
|
+
if (pluginUpdateAvailable && pluginLatestVersion !== "") updatePlugin.hidden = !diagnosticsView.hidden;
|
|
4011
|
+
};
|
|
4012
|
+
const runPluginUpdate = () => {
|
|
4013
|
+
if (!pluginUpdateAvailable || pluginLatestVersion === "" || updateInFlight) return;
|
|
4014
|
+
updateInFlight = true;
|
|
4015
|
+
updateNow.disabled = true;
|
|
4016
|
+
updateLater.disabled = true;
|
|
4017
|
+
updateCardTitle.textContent = t("updatingPlugin");
|
|
3974
4018
|
releaseNotice.hidden = true;
|
|
3975
4019
|
releaseNotice.classList.remove("is-error");
|
|
3976
4020
|
controlRequestJson("/api/mobile-access/release/update", {
|
|
@@ -3979,18 +4023,32 @@ window.__ModuleLoader__.load({
|
|
|
3979
4023
|
}, LONG_CONTROL_REQUEST_TIMEOUT_MS).then((data) => {
|
|
3980
4024
|
const installedVersion = releaseVersion(data.installedVersion) ?? pluginLatestVersion;
|
|
3981
4025
|
pluginUpdateAvailable = false;
|
|
4026
|
+
updateCard.hidden = true;
|
|
3982
4027
|
updatePlugin.hidden = true;
|
|
3983
4028
|
releaseNotice.textContent = t("pluginUpdatedRestart", { version: installedVersion });
|
|
3984
4029
|
releaseNotice.hidden = false;
|
|
3985
4030
|
}, (error) => {
|
|
3986
|
-
|
|
4031
|
+
updateCard.hidden = true;
|
|
4032
|
+
updatePlugin.hidden = false;
|
|
3987
4033
|
releaseNotice.textContent = t("pluginUpdateFailed", { error: String(error) });
|
|
3988
4034
|
releaseNotice.classList.add("is-error");
|
|
3989
4035
|
releaseNotice.hidden = false;
|
|
3990
4036
|
}).finally(() => {
|
|
3991
|
-
|
|
4037
|
+
updateInFlight = false;
|
|
4038
|
+
updateNow.disabled = false;
|
|
4039
|
+
updateLater.disabled = false;
|
|
3992
4040
|
});
|
|
4041
|
+
};
|
|
4042
|
+
updatePlugin.addEventListener("click", () => {
|
|
4043
|
+
if (!pluginUpdateAvailable || pluginLatestVersion === "" || updateInFlight) return;
|
|
4044
|
+
updatePlugin.hidden = true;
|
|
4045
|
+
updateCardTitle.textContent = t("updateTo", { version: pluginLatestVersion });
|
|
4046
|
+
updateCardNotes.textContent = pluginReleaseNotes === "" ? t("updateNotesEmpty") : pluginReleaseNotes;
|
|
4047
|
+
updateCardNotes.hidden = pluginReleaseNotes === "";
|
|
4048
|
+
updateCard.hidden = false;
|
|
3993
4049
|
});
|
|
4050
|
+
updateNow.addEventListener("click", runPluginUpdate);
|
|
4051
|
+
updateLater.addEventListener("click", closeUpdateCard);
|
|
3994
4052
|
diagnosticsCopy.addEventListener("click", () => {
|
|
3995
4053
|
if (copiedDiagnosticReport === "") return;
|
|
3996
4054
|
navigator.clipboard.writeText(copiedDiagnosticReport).then(() => {
|
|
@@ -5222,7 +5280,7 @@ window.__ModuleLoader__.load({
|
|
|
5222
5280
|
.dsh-mobile-control{position:fixed;z-index:1000;left:16px;bottom:112px;font:14px/1.45 system-ui;color:var(--dsw-alias-label-primary,#16181d)}
|
|
5223
5281
|
.dsh-mobile-control__panel{box-sizing:border-box;width:min(380px,calc(100vw - 32px));max-height:calc(100vh - 140px);overflow-y:auto;padding:16px;border:1px solid var(--dsw-alias-border-subtle,#e1e5eb);border-radius:18px;background:var(--dsw-alias-bg-layer-2,#fff);box-shadow:0 18px 50px rgb(15 23 42 / 18%)}
|
|
5224
5282
|
.dsh-mobile-control__header{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:10px}.dsh-mobile-control__panel h2{margin:0;font-size:17px;line-height:24px}.dsh-mobile-control__header-actions{display:flex;align-items:center;gap:2px}.dsh-mobile-control__update-plugin,.dsh-mobile-control__diagnostic-entry,.dsh-mobile-control__close{display:inline-flex;align-items:center;justify-content:center;min-width:44px;height:44px;padding:0;border:0;border-radius:10px;background:transparent;color:inherit;cursor:pointer}.dsh-mobile-control__update-plugin,.dsh-mobile-control__diagnostic-entry{padding:0 8px;color:#2563eb;font:650 12px/1 system-ui;white-space:nowrap}.dsh-mobile-control__update-plugin[hidden]{display:none}.dsh-mobile-control__update-plugin:disabled{cursor:wait;opacity:.55}.dsh-mobile-control__close{font-size:24px;line-height:1}.dsh-mobile-control__update-plugin:hover:not(:disabled),.dsh-mobile-control__diagnostic-entry:hover,.dsh-mobile-control__close:hover{background:var(--dsw-alias-interactive-bg-hover,#f1f3f6)}
|
|
5225
|
-
.dsh-mobile-control__release-notice{margin:-2px 0 10px;padding:8px 10px;border-radius:9px;background:var(--dsw-alias-bg-layer-1,#eff6ff);color:var(--dsw-alias-label-primary,#1d4ed8);font-size:11px;line-height:1.45}.dsh-mobile-control__release-notice.is-error{color:#dc2626}.dsh-mobile-control__release-notice[hidden]{display:none}.dsh-mobile-control__app-download{display:flex;align-items:center;justify-content:space-between;box-sizing:border-box;min-height:38px;margin:0 0 10px;padding:8px 11px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:11px;background:var(--dsw-alias-bg-layer-1,#f7f8fa);color:var(--dsw-alias-label-primary,#16181d);font:600 12px/1.3 system-ui;text-decoration:none}.dsh-mobile-control__app-download[hidden]{display:none}.dsh-mobile-control__app-download::after{color:#2563eb;font-size:14px;content:"↗"}.dsh-mobile-control__app-download:hover{border-color:#9fb9e8;background:var(--dsw-alias-interactive-bg-hover-solid,var(--dsw-alias-bg-layer-2,#f5f8ff));color:var(--dsw-alias-label-primary,#1d4ed8)}
|
|
5283
|
+
.dsh-mobile-control__release-notice{margin:-2px 0 10px;padding:8px 10px;border-radius:9px;background:var(--dsw-alias-bg-layer-1,#eff6ff);color:var(--dsw-alias-label-primary,#1d4ed8);font-size:11px;line-height:1.45}.dsh-mobile-control__release-notice.is-error{color:#dc2626}.dsh-mobile-control__release-notice[hidden]{display:none}.dsh-mobile-control__update-card{margin:0 0 10px;padding:11px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:12px;background:var(--dsw-alias-bg-layer-1,#f8fafc)}.dsh-mobile-control__update-card[hidden]{display:none}.dsh-mobile-control__update-card-title{margin:0 0 7px;color:var(--dsw-alias-label-primary,#16181d);font:650 13px/1.4 system-ui}.dsh-mobile-control__update-notes{display:block;box-sizing:border-box;max-height:150px;overflow-y:auto;margin:0 0 8px;padding:8px 10px;border:1px solid var(--dsw-alias-border-subtle,#e1e5eb);border-radius:9px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-secondary,#475569);white-space:pre-wrap;word-break:break-word;font:11px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.dsh-mobile-control__update-notes[hidden]{display:none}.dsh-mobile-control__update-notice{margin:0 0 9px;padding:7px 9px;border-radius:8px;background:#fff4d6;color:#92400e;font-size:11px;line-height:1.5}.dsh-mobile-control__update-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px}.dsh-mobile-control__update-actions .dsh-mobile-control__primary,.dsh-mobile-control__update-actions .dsh-mobile-control__secondary{min-height:34px;padding:0 12px}.dsh-mobile-control__app-download{display:flex;align-items:center;justify-content:space-between;box-sizing:border-box;min-height:38px;margin:0 0 10px;padding:8px 11px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:11px;background:var(--dsw-alias-bg-layer-1,#f7f8fa);color:var(--dsw-alias-label-primary,#16181d);font:600 12px/1.3 system-ui;text-decoration:none}.dsh-mobile-control__app-download[hidden]{display:none}.dsh-mobile-control__app-download::after{color:#2563eb;font-size:14px;content:"↗"}.dsh-mobile-control__app-download:hover{border-color:#9fb9e8;background:var(--dsw-alias-interactive-bg-hover-solid,var(--dsw-alias-bg-layer-2,#f5f8ff));color:var(--dsw-alias-label-primary,#1d4ed8)}
|
|
5226
5284
|
.dsh-mobile-control__switcher{display:grid;grid-template-columns:repeat(2,1fr);gap:4px;margin:0 0 14px;padding:4px;border-radius:12px;background:var(--dsw-alias-bg-layer-1,#f3f5f8)}.dsh-mobile-control__switcher[hidden]{display:none}.dsh-mobile-control__tab{min-height:36px;border:0;border-radius:9px;background:transparent;color:var(--dsw-alias-label-secondary,#606873);font:600 13px/1 system-ui;cursor:pointer}.dsh-mobile-control__tab.is-active{background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);box-shadow:0 1px 3px rgb(15 23 42 / 10%)}.dsh-mobile-control__view[hidden]{display:none}.dsh-mobile-control__intro{margin:0 0 12px;color:var(--dsw-alias-label-secondary,#606873);font-size:12px;line-height:1.55}.dsh-mobile-control__view.is-remote .dsh-mobile-control__actions{display:grid;grid-template-columns:1fr 1fr;gap:8px}.dsh-mobile-control__view.is-remote .dsh-mobile-control__actions button[hidden]{display:none}
|
|
5227
5285
|
.dsh-mobile-control__provider-section{position:relative;margin:0 0 14px}.dsh-mobile-control__section-title{margin:0 0 8px;color:var(--dsw-alias-label-primary,#16181d);font:650 13px/1.4 system-ui}.dsh-mobile-control__provider-section>.dsh-mobile-control__section-title{padding-right:42px}.dsh-mobile-control__provider-choices{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.dsh-mobile-control__provider{display:flex;min-width:0;flex-direction:column;gap:6px;min-height:94px;padding:10px 11px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);text-align:left;cursor:pointer;touch-action:manipulation;transition:border-color 160ms ease,background-color 160ms ease,box-shadow 160ms ease}.dsh-mobile-control__provider:hover{border-color:#6f96db;background:var(--dsw-alias-interactive-bg-hover-solid,var(--dsw-alias-bg-layer-1,#f8fbff))}.dsh-mobile-control__provider.is-selected{border-color:#2563eb;background:var(--dsw-alias-interactive-bg-active,var(--dsw-alias-bg-layer-1,#f5f8ff));box-shadow:0 0 0 1px #2563eb inset}.dsh-mobile-control__provider:disabled{cursor:wait;opacity:.62}.dsh-mobile-control__provider-top{display:flex;min-width:0;align-items:flex-start;justify-content:space-between;gap:5px}.dsh-mobile-control__provider-top strong{min-width:0;font-size:12px;line-height:1.3}.dsh-mobile-control__provider-badge{flex:none;padding:2px 5px;border-radius:999px;background:#e8f0ff;color:#1d4ed8;font:650 9px/1.25 system-ui}.dsh-mobile-control__provider-badge.is-cpolar{background:#eaf8f2;color:#087454}.dsh-mobile-control__provider-description{color:var(--dsw-alias-label-secondary,#606873);font-size:10px;line-height:1.45}.dsh-mobile-control__provider-info{position:absolute;z-index:5;top:-13px;right:-8px}.dsh-mobile-control__provider-info-button{display:flex;align-items:center;justify-content:center;width:44px;height:44px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--dsw-alias-label-secondary,#475569);cursor:pointer;touch-action:manipulation}.dsh-mobile-control__provider-info-button:hover{background:var(--dsw-alias-interactive-bg-hover,#f1f5f9);color:#2563eb}.dsh-mobile-control__provider-info-glyph{display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:18px;height:18px;border:1.5px solid currentColor;border-radius:50%;font:700 12px/1 system-ui}.dsh-mobile-control__provider-info-popover{position:absolute;z-index:6;top:38px;right:4px;box-sizing:border-box;width:min(292px,calc(100vw - 72px));padding:10px 12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:12px;background:var(--dsw-alias-bg-layer-2,#fff);box-shadow:0 10px 28px rgb(15 23 42 / 16%)}.dsh-mobile-control__provider-info-popover[hidden]{display:none}.dsh-mobile-control__provider-info-popover strong,.dsh-mobile-control__provider-info-popover span{display:block}.dsh-mobile-control__provider-info-popover strong{margin-bottom:3px;font-size:12px}.dsh-mobile-control__provider-info-popover span{color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.55}
|
|
5228
5286
|
.dsh-mobile-control__self-hosted{margin:8px 0 0;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:12px;background:var(--dsw-alias-bg-layer-1,#f8fafc)}.dsh-mobile-control__self-hosted-summary{display:flex;box-sizing:border-box;min-height:48px;align-items:center;justify-content:space-between;gap:10px;padding:8px 11px;cursor:pointer;list-style-position:inside}.dsh-mobile-control__self-hosted-summary>span:first-child{display:flex;min-width:0;flex-direction:column;gap:1px}.dsh-mobile-control__self-hosted-summary strong{font-size:11px}.dsh-mobile-control__self-hosted-summary span span{color:var(--dsw-alias-label-secondary,#606873);font-size:9px;line-height:1.35}.dsh-mobile-control__provider-badge.is-frp{background:#eef0f3;color:#475569}.dsh-mobile-control__self-hosted-body{padding:0 8px 8px}.dsh-mobile-control__provider.is-frp{width:100%;min-height:64px;background:var(--dsw-alias-bg-layer-2,#fff)}
|