@wenbin_wb/dsh-bridge 2.8.5 → 2.8.7
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 +34 -0
- package/client/client.js +396 -39
- package/client/index.js +399 -40
- package/docs/fix-tunnel-sse-and-session-list.md +134 -0
- package/lib/bridge-rpc-constants.js +1 -0
- package/lib/bridge-rpc.js +9 -0
- package/lib/cloudflared-manager.mjs +75 -12
- package/lib/index.js +147 -26
- package/lib/platform/conversation-bridge.js +153 -128
- package/lib/tunnel-client.mjs +402 -289
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,40 @@
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [v2.8.7] - 2026-08-30
|
|
8
|
+
|
|
9
|
+
### 🛜 多网卡智能切换与 macOS 升级与隧道自愈加固
|
|
10
|
+
- **🛜 支持局域网多网卡可视化切换与持久化 (Issue #5)**:
|
|
11
|
+
- 自动探测并列出宿主机所有可用物理网卡与虚拟网卡(Wi-Fi、以太网、WSL、VMware、Docker 等),支持识别网卡类型与优先级推荐;
|
|
12
|
+
- 在局域网控制台提供网卡下拉切换器,切换后即时重新生成局域网链接与二维码,并自动记忆持久化保存,彻底解决多网卡/WSL 环境下移动端扫码 IP 无法互通的问题;
|
|
13
|
+
- **🍏 加固 macOS 一键平滑升级**:
|
|
14
|
+
- `upgradePlugin` 自动补全 macOS GUI / 后台环境下缺失的系统 `PATH` 环境变量(自动兼容 `/opt/homebrew/bin`、`/usr/local/bin`、`~/.nvm/...` 等);
|
|
15
|
+
- 自动优先绑定当前运行中 Node.js 同级目录下的 `npm`/`npx` 二进制绝对路径,杜绝 `spawn ENOENT` 升级失败;
|
|
16
|
+
- **🛡️ 优化 macOS Cloudflared 二进制探测与隔离自愈**:
|
|
17
|
+
- 启动时优先扫描系统 `PATH` 与 Homebrew 安装的 `cloudflared` 全局二进制;
|
|
18
|
+
- 网络下载解压后自动通过 `xattr -d com.apple.quarantine` 移除 Gatekeeper 隔离标记,并加入 `--version` 运行期校验与自愈。
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## [v2.8.6] - 2026-08-30
|
|
23
|
+
|
|
24
|
+
### 📱 移动端交互适配重构 & 隧道保活与传输优化
|
|
25
|
+
- **📱 移动端工作区体验重构与多途径秒级回切**:
|
|
26
|
+
- 修复移动端工作区面板(Workbench / `dsh-better-sidebar` / 任务管理)遮盖聊天对话与收起后白屏残留问题;
|
|
27
|
+
- 引入严密的显隐状态机(`dsh-workbench-open`),打开面板时在 Tab 栏常驻 **`✕ 返回对话`** 蓝色操作胶囊;
|
|
28
|
+
- 提供多途径极速回切:支持点击「返回对话」按钮、点击顶部 Header 会话标题、或在左侧抽屉切换会话秒级返回对话流;
|
|
29
|
+
- **🗂️ DSH 原生收起图标深度适配与双向开合**:
|
|
30
|
+
- 在移动端侧边栏抽屉顶部 Logo 栏完整集成并复用 DSH 原生自带的收起图标(`[|`);
|
|
31
|
+
- 支持点击主界面 `≡` 汉堡菜单流畅滑出抽屉、点击原生收起图标/点击会话/轻触遮罩丝滑收回抽屉;
|
|
32
|
+
- **🖥️ PC 桌面端严格隔离与零侵入**:
|
|
33
|
+
- 通过媒体查询与运行期断点双重守卫,确保 PC 桌面端(`> 768px`)100% 保持官方原生多列分栏布局与纯净体验,无任何样式污染与多余组件;
|
|
34
|
+
- **🛡️ Cloudflared 隧道守护进程自愈与自动重启**:
|
|
35
|
+
- 修复 Cloudflared 进程异常退出后无法自动拉起的问题,增加子进程退出监听与指数退避自动重连机制,确保长时间公网访问不断连;
|
|
36
|
+
- **⚡ 自建隧道 SSE 稳定性与数据传输优化**:
|
|
37
|
+
- 修复弱网环境下 SSE 断线重连问题,精简 Session 列表超大数据负载传输,显著降低移动端带宽占用与弱网延迟。
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
7
41
|
## [v2.8.5] - 2026-08-27
|
|
8
42
|
|
|
9
43
|
### 🎯 产物文件推送改为 AI 指令驱动 & 修复 IM 平台断开连接问题
|
package/client/client.js
CHANGED
|
@@ -43,6 +43,7 @@ var BRIDGE_ENDPOINTS = {
|
|
|
43
43
|
saveCloudflaredConfig: "saveCloudflaredConfig",
|
|
44
44
|
setTunnelAutoStart: "setTunnelAutoStart",
|
|
45
45
|
saveCustomTunnelConfig: "saveCustomTunnelConfig",
|
|
46
|
+
setLanIp: "setLanIp",
|
|
46
47
|
checkVersion: "checkVersion",
|
|
47
48
|
upgradePlugin: "upgradePlugin",
|
|
48
49
|
restartDsh: "restartDsh",
|
|
@@ -376,6 +377,84 @@ function QrBlock({ url, qr, onReset, auth, onNavigateSecurity }) {
|
|
|
376
377
|
)
|
|
377
378
|
);
|
|
378
379
|
}
|
|
380
|
+
var LanNetworkSelector = React.memo(function LanNetworkSelector2({ lan, onSelectIp }) {
|
|
381
|
+
const interfaces = lan?.interfaces || [];
|
|
382
|
+
const selectedIp = lan?.selectedIp || "";
|
|
383
|
+
const currentIp = lan?.ip || "";
|
|
384
|
+
const [switching, setSwitching] = React.useState(false);
|
|
385
|
+
if (!interfaces || interfaces.length <= 1) return null;
|
|
386
|
+
const handleChange = async (e) => {
|
|
387
|
+
const val = e.target.value;
|
|
388
|
+
setSwitching(true);
|
|
389
|
+
try {
|
|
390
|
+
await onSelectIp(val || null);
|
|
391
|
+
} finally {
|
|
392
|
+
setSwitching(false);
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
return React.createElement(
|
|
396
|
+
"div",
|
|
397
|
+
{
|
|
398
|
+
style: {
|
|
399
|
+
...s.block,
|
|
400
|
+
background: "var(--dsw-alias-bg-layer-2, rgba(243, 244, 246, 0.6))",
|
|
401
|
+
padding: "10px 12px",
|
|
402
|
+
borderRadius: 8,
|
|
403
|
+
border: "1px solid var(--dsw-alias-border-l2, #e5e7eb)",
|
|
404
|
+
marginTop: 8,
|
|
405
|
+
marginBottom: 6
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
React.createElement(
|
|
409
|
+
"div",
|
|
410
|
+
{
|
|
411
|
+
style: {
|
|
412
|
+
display: "flex",
|
|
413
|
+
alignItems: "center",
|
|
414
|
+
justifyContent: "space-between",
|
|
415
|
+
marginBottom: 6,
|
|
416
|
+
fontSize: 12,
|
|
417
|
+
fontWeight: 500,
|
|
418
|
+
color: "var(--dsw-alias-label-primary, currentColor)"
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
React.createElement(
|
|
422
|
+
"span",
|
|
423
|
+
{ style: { display: "inline-flex", alignItems: "center", gap: 5 } },
|
|
424
|
+
"\u{1F6DC} \u5C40\u57DF\u7F51\u7F51\u5361 / IP \u9009\u62E9"
|
|
425
|
+
),
|
|
426
|
+
switching && React.createElement("span", {
|
|
427
|
+
style: { fontSize: 11, color: "var(--dsw-alias-brand-primary, #4f6ef7)" }
|
|
428
|
+
}, "\u5207\u6362\u4E2D\u2026")
|
|
429
|
+
),
|
|
430
|
+
React.createElement(
|
|
431
|
+
"div",
|
|
432
|
+
{ style: { ...s.muted, fontSize: 11, marginBottom: 6 } },
|
|
433
|
+
"\u68C0\u6D4B\u5230\u4E3B\u673A\u5B58\u5728\u591A\u5F20\u7F51\u5361\uFF08\u5982\u7269\u7406 Wi-Fi\u3001\u4EE5\u592A\u7F51\u3001WSL \u6216\u865A\u62DF\u673A\uFF09\u3002\u82E5\u9ED8\u8BA4 IP \u65E0\u6CD5\u88AB\u79FB\u52A8\u7AEF\u8BBF\u95EE\uFF0C\u53EF\u624B\u52A8\u5207\u6362\uFF1A"
|
|
434
|
+
),
|
|
435
|
+
React.createElement(
|
|
436
|
+
"select",
|
|
437
|
+
{
|
|
438
|
+
style: {
|
|
439
|
+
...s.input,
|
|
440
|
+
height: 32,
|
|
441
|
+
fontSize: 12,
|
|
442
|
+
padding: "0 8px",
|
|
443
|
+
background: "var(--dsw-alias-bg-layer-1, #ffffff)",
|
|
444
|
+
cursor: "pointer"
|
|
445
|
+
},
|
|
446
|
+
value: selectedIp,
|
|
447
|
+
onChange: handleChange,
|
|
448
|
+
disabled: switching
|
|
449
|
+
},
|
|
450
|
+
React.createElement("option", { value: "" }, `\u26A1 \u81EA\u52A8\u63A8\u8350 (${interfaces[0]?.address || currentIp} \xB7 ${interfaces[0]?.label || interfaces[0]?.name || ""})`),
|
|
451
|
+
interfaces.map((iface) => React.createElement("option", {
|
|
452
|
+
key: `${iface.name}-${iface.address}`,
|
|
453
|
+
value: iface.address
|
|
454
|
+
}, `${iface.address} \xB7 ${iface.label || iface.name}${iface.isVirtual ? " [\u865A\u62DF/WSL]" : ""}`))
|
|
455
|
+
)
|
|
456
|
+
);
|
|
457
|
+
});
|
|
379
458
|
var CustomTunnelGuide = React.memo(function CustomTunnelGuide2() {
|
|
380
459
|
return React.createElement(
|
|
381
460
|
"div",
|
|
@@ -2783,6 +2862,7 @@ function BridgePanel({ rpcCall }) {
|
|
|
2783
2862
|
({ token, hostname }) => act(BRIDGE_ENDPOINTS.saveCloudflaredConfig, { token, hostname }),
|
|
2784
2863
|
[act]
|
|
2785
2864
|
);
|
|
2865
|
+
const onSelectLanIp = React.useCallback((ip) => act(BRIDGE_ENDPOINTS.setLanIp, { ip }), [act]);
|
|
2786
2866
|
const onStartCustom = React.useCallback(() => act(BRIDGE_ENDPOINTS.startCustomTunnel), [act]);
|
|
2787
2867
|
const onStopCustom = React.useCallback(() => act(BRIDGE_ENDPOINTS.stopCustomTunnel), [act]);
|
|
2788
2868
|
const onToggleCustomAutoStart = React.useCallback(
|
|
@@ -2811,13 +2891,20 @@ function BridgePanel({ rpcCall }) {
|
|
|
2811
2891
|
};
|
|
2812
2892
|
let tabContent;
|
|
2813
2893
|
if (activeTab === "lan") {
|
|
2814
|
-
tabContent = React.createElement(
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2894
|
+
tabContent = React.createElement(
|
|
2895
|
+
TunnelCard,
|
|
2896
|
+
{
|
|
2897
|
+
title: "\u5C40\u57DF\u7F51\u8BBF\u95EE",
|
|
2898
|
+
desc: "\u540C\u4E00 Wi-Fi \u4E0B\u7684\u8BBE\u5907\u53EF\u76F4\u63A5\u626B\u7801\u8BBF\u95EE",
|
|
2899
|
+
data: { running: status?.proxy?.running, url: status?.lan?.url, qr: status?.lan?.qr },
|
|
2900
|
+
auth: status?.auth,
|
|
2901
|
+
onNavigateSecurity: navSecurity
|
|
2902
|
+
},
|
|
2903
|
+
React.createElement(LanNetworkSelector, {
|
|
2904
|
+
lan: status?.lan,
|
|
2905
|
+
onSelectIp: onSelectLanIp
|
|
2906
|
+
})
|
|
2907
|
+
);
|
|
2821
2908
|
} else if (activeTab === "tunnel") {
|
|
2822
2909
|
tabContent = React.createElement(
|
|
2823
2910
|
React.Fragment,
|
|
@@ -3389,6 +3476,163 @@ function injectMobileStyles() {
|
|
|
3389
3476
|
display: none !important;
|
|
3390
3477
|
}
|
|
3391
3478
|
|
|
3479
|
+
/* 3.0 \u5DE5\u4F5C\u533A Workbench / \u4EFB\u52A1\u7BA1\u7406 / \u591A Tab \u680F\u79FB\u52A8\u7AEF\u81EA\u9002\u5E94\u9002\u914D */
|
|
3480
|
+
body:not(.dsh-workbench-open) div[class*="nArs4W_panel"],
|
|
3481
|
+
body:not(.dsh-workbench-open) div[class*="workbench_panel"],
|
|
3482
|
+
body:not(.dsh-workbench-open) div[class*="workbenchPanel"],
|
|
3483
|
+
div[class*="nArs4W_panel"][class*="panelHidden"],
|
|
3484
|
+
div[class*="workbench_panel"][class*="panelHidden"],
|
|
3485
|
+
div[class*="workbenchPanel"][class*="panelHidden"],
|
|
3486
|
+
div[class*="panelHidden"] {
|
|
3487
|
+
display: none !important;
|
|
3488
|
+
visibility: hidden !important;
|
|
3489
|
+
pointer-events: none !important;
|
|
3490
|
+
width: 0 !important;
|
|
3491
|
+
height: 0 !important;
|
|
3492
|
+
max-height: 0 !important;
|
|
3493
|
+
z-index: -1 !important;
|
|
3494
|
+
opacity: 0 !important;
|
|
3495
|
+
transform: translateX(105%) !important;
|
|
3496
|
+
}
|
|
3497
|
+
|
|
3498
|
+
body.dsh-workbench-open div[class*="nArs4W_panel"]:not([class*="panelHidden"]),
|
|
3499
|
+
body.dsh-workbench-open div[class*="workbench_panel"]:not([class*="panelHidden"]),
|
|
3500
|
+
body.dsh-workbench-open div[class*="workbenchPanel"]:not([class*="panelHidden"]) {
|
|
3501
|
+
display: flex !important;
|
|
3502
|
+
visibility: visible !important;
|
|
3503
|
+
pointer-events: auto !important;
|
|
3504
|
+
top: var(--dsh-mobile-header-h, 52px) !important;
|
|
3505
|
+
height: calc(100dvh - var(--dsh-mobile-header-h, 52px)) !important;
|
|
3506
|
+
max-height: calc(100dvh - var(--dsh-mobile-header-h, 52px)) !important;
|
|
3507
|
+
z-index: 50 !important;
|
|
3508
|
+
box-sizing: border-box !important;
|
|
3509
|
+
background: var(--dsw-alias-bg-layer-1, #ffffff) !important;
|
|
3510
|
+
transform: none !important;
|
|
3511
|
+
opacity: 1 !important;
|
|
3512
|
+
}
|
|
3513
|
+
|
|
3514
|
+
/* Tab \u680F\uFF1A\u6A2A\u5411\u6ED1\u52A8\u624B\u52BF + \u5E72\u51C0\u7684\u5E95\u90E8\u8FB9\u6846\uFF0C\u675C\u7EDD\u4E0E\u9876\u90E8\u79FB\u52A8\u7AEF Header \u91CD\u53E0 */
|
|
3515
|
+
div[class*="nArs4W_tabBar"],
|
|
3516
|
+
div[class*="workbench_tabBar"],
|
|
3517
|
+
div[class*="tabBar"] {
|
|
3518
|
+
min-height: 40px !important;
|
|
3519
|
+
height: 40px !important;
|
|
3520
|
+
background: var(--dsw-alias-bg-layer-1, #ffffff) !important;
|
|
3521
|
+
border-bottom: 1px solid rgba(0, 0, 0, 0.08) !important;
|
|
3522
|
+
display: flex !important;
|
|
3523
|
+
align-items: center !important;
|
|
3524
|
+
justify-content: space-between !important;
|
|
3525
|
+
padding: 0 8px !important;
|
|
3526
|
+
gap: 6px !important;
|
|
3527
|
+
overflow: visible !important;
|
|
3528
|
+
box-sizing: border-box !important;
|
|
3529
|
+
}
|
|
3530
|
+
|
|
3531
|
+
div[class*="nArs4W_tabList"],
|
|
3532
|
+
div[class*="tabList"] {
|
|
3533
|
+
display: flex !important;
|
|
3534
|
+
align-items: center !important;
|
|
3535
|
+
gap: 6px !important;
|
|
3536
|
+
flex: 1 1 auto !important;
|
|
3537
|
+
min-width: 0 !important;
|
|
3538
|
+
overflow-x: auto !important;
|
|
3539
|
+
scrollbar-width: none !important;
|
|
3540
|
+
-webkit-overflow-scrolling: touch !important;
|
|
3541
|
+
}
|
|
3542
|
+
div[class*="nArs4W_tabList"]::-webkit-scrollbar,
|
|
3543
|
+
div[class*="tabList"]::-webkit-scrollbar {
|
|
3544
|
+
display: none !important;
|
|
3545
|
+
}
|
|
3546
|
+
|
|
3547
|
+
/* \u5355\u4E2A Tab \u80F6\u56CA\u5316\uFF0C\u6587\u5B57\u8D85\u957F\u81EA\u52A8\u6253\u70B9\uFF0C\u9632\u6B62 Tab \u4E92\u76F8\u6324\u538B */
|
|
3548
|
+
div[class*="nArs4W_tab"],
|
|
3549
|
+
div[class*="workbench_tab"] {
|
|
3550
|
+
flex: 0 0 auto !important;
|
|
3551
|
+
max-width: 170px !important;
|
|
3552
|
+
min-width: 70px !important;
|
|
3553
|
+
height: 30px !important;
|
|
3554
|
+
padding: 0 8px 0 10px !important;
|
|
3555
|
+
border-radius: 6px !important;
|
|
3556
|
+
font-size: 12.5px !important;
|
|
3557
|
+
display: inline-flex !important;
|
|
3558
|
+
align-items: center !important;
|
|
3559
|
+
justify-content: space-between !important;
|
|
3560
|
+
gap: 6px !important;
|
|
3561
|
+
background: var(--dsw-alias-bg-layer-2, #f3f4f6) !important;
|
|
3562
|
+
color: var(--dsw-alias-label-secondary, #6b7280) !important;
|
|
3563
|
+
cursor: pointer !important;
|
|
3564
|
+
user-select: none !important;
|
|
3565
|
+
box-sizing: border-box !important;
|
|
3566
|
+
}
|
|
3567
|
+
|
|
3568
|
+
div[class*="nArs4W_tabActive"],
|
|
3569
|
+
div[class*="workbench_tabActive"] {
|
|
3570
|
+
background: var(--dsw-alias-bg-layer-1, #ffffff) !important;
|
|
3571
|
+
color: var(--dsw-alias-label-primary, #111827) !important;
|
|
3572
|
+
font-weight: 600 !important;
|
|
3573
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1) !important;
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
span[class*="nArs4W_tabTitle"],
|
|
3577
|
+
span[class*="tabTitle"] {
|
|
3578
|
+
overflow: hidden !important;
|
|
3579
|
+
text-overflow: ellipsis !important;
|
|
3580
|
+
white-space: nowrap !important;
|
|
3581
|
+
flex: 1 1 auto !important;
|
|
3582
|
+
}
|
|
3583
|
+
|
|
3584
|
+
button[class*="nArs4W_tabClose"],
|
|
3585
|
+
button[class*="tabClose"] {
|
|
3586
|
+
width: 18px !important;
|
|
3587
|
+
height: 18px !important;
|
|
3588
|
+
border-radius: 50% !important;
|
|
3589
|
+
display: inline-flex !important;
|
|
3590
|
+
align-items: center !important;
|
|
3591
|
+
justify-content: center !important;
|
|
3592
|
+
flex-shrink: 0 !important;
|
|
3593
|
+
opacity: 0.6 !important;
|
|
3594
|
+
padding: 0 !important;
|
|
3595
|
+
}
|
|
3596
|
+
|
|
3597
|
+
button[class*="nArs4W_tabBarPlus"],
|
|
3598
|
+
button[class*="tabBarPlus"] {
|
|
3599
|
+
width: 28px !important;
|
|
3600
|
+
height: 28px !important;
|
|
3601
|
+
border-radius: 50% !important;
|
|
3602
|
+
display: inline-flex !important;
|
|
3603
|
+
align-items: center !important;
|
|
3604
|
+
justify-content: center !important;
|
|
3605
|
+
flex-shrink: 0 !important;
|
|
3606
|
+
}
|
|
3607
|
+
|
|
3608
|
+
/* \u79FB\u52A8\u7AEF\u9762\u677F\u53F3\u4E0A\u89D2\u201C\u8FD4\u56DE\u5BF9\u8BDD / \u2715 \u6536\u8D77\u201D\u6309\u94AE\uFF1A\u5E38\u9A7B\u53F3\u4FA7\uFF0C\u9192\u76EE\u4E14\u6613\u89E6\u8FBE */
|
|
3609
|
+
.dsh-mobile-panel-close-btn {
|
|
3610
|
+
margin-left: 8px !important;
|
|
3611
|
+
flex: 0 0 auto !important;
|
|
3612
|
+
height: 28px !important;
|
|
3613
|
+
padding: 0 10px !important;
|
|
3614
|
+
border-radius: 14px !important;
|
|
3615
|
+
font-size: 12px !important;
|
|
3616
|
+
font-weight: 600 !important;
|
|
3617
|
+
background: #2563eb !important;
|
|
3618
|
+
color: #ffffff !important;
|
|
3619
|
+
border: none !important;
|
|
3620
|
+
display: inline-flex !important;
|
|
3621
|
+
align-items: center !important;
|
|
3622
|
+
justify-content: center !important;
|
|
3623
|
+
gap: 4px !important;
|
|
3624
|
+
cursor: pointer !important;
|
|
3625
|
+
user-select: none !important;
|
|
3626
|
+
box-shadow: 0 2px 6px rgba(37, 99, 235, 0.28) !important;
|
|
3627
|
+
white-space: nowrap !important;
|
|
3628
|
+
transition: transform 0.1s, opacity 0.15s !important;
|
|
3629
|
+
z-index: 10 !important;
|
|
3630
|
+
}
|
|
3631
|
+
.dsh-mobile-panel-close-btn:active {
|
|
3632
|
+
transform: scale(0.95) !important;
|
|
3633
|
+
opacity: 0.85 !important;
|
|
3634
|
+
}
|
|
3635
|
+
|
|
3392
3636
|
/* 3.1 \u4F1A\u8BDD\u5BF9\u8BDD\u5934\u90E8\u9876\u680F\uFF1A\u79FB\u52A8\u7AEF\u9632\u6324\u538B\u4E0E\u7A7A\u95F4\u91CA\u653E\u4F18\u5316\uFF08\u4E25\u683C\u6392\u9664 .dsh-mobile-app-header\uFF09 */
|
|
3393
3637
|
div[class*="_centerCol"] header,
|
|
3394
3638
|
header[class*="wSkVaW_header"] {
|
|
@@ -3583,19 +3827,53 @@ function injectMobileStyles() {
|
|
|
3583
3827
|
transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
|
|
3584
3828
|
overflow-y: auto !important;
|
|
3585
3829
|
border-right: 1px solid rgba(0, 0, 0, 0.06) !important;
|
|
3830
|
+
pointer-events: auto !important;
|
|
3586
3831
|
}
|
|
3587
3832
|
body.dsh-drawer-open div[class*="_sidebarCol"] {
|
|
3588
3833
|
transform: translateX(0) !important;
|
|
3589
3834
|
box-shadow: 4px 0 28px rgba(0, 0, 0, 0.25) !important;
|
|
3835
|
+
pointer-events: auto !important;
|
|
3590
3836
|
}
|
|
3591
3837
|
|
|
3592
|
-
/* \u62BD\u5C49\u5185\u90E8\uFF1A\u5F3A\u5236 100% \u5BBD\u5EA6\uFF0C\
|
|
3838
|
+
/* \u62BD\u5C49\u5185\u90E8\uFF1A\u5F3A\u5236 100% \u5BBD\u5EA6\uFF0C\u65E0\u8BBA\u5185\u90E8\u72B6\u6001\u5982\u4F55\u5747\u6B63\u5E38\u5C55\u5F00\u5E76\u5C55\u793A DSH \u81EA\u5E26\u7684\u9876\u90E8\u6536\u8D77\u4FA7\u8FB9\u680F\u56FE\u6807 */
|
|
3593
3839
|
body.dsh-drawer-open div[class*="hHd-Xa_root"] {
|
|
3594
3840
|
width: 100% !important;
|
|
3595
3841
|
max-width: 100% !important;
|
|
3842
|
+
min-width: 100% !important;
|
|
3843
|
+
display: flex !important;
|
|
3844
|
+
flex-direction: column !important;
|
|
3845
|
+
}
|
|
3846
|
+
body.dsh-drawer-open div[class*="hHd-Xa_collapsed"] div[class*="hHd-Xa_regionArea"],
|
|
3847
|
+
body.dsh-drawer-open div[class*="hHd-Xa_collapsed"] button[class*="hHd-Xa_newSession"],
|
|
3848
|
+
body.dsh-drawer-open div[class*="hHd-Xa_collapsed"] div[class*="qDHVXG_root"] {
|
|
3849
|
+
display: flex !important;
|
|
3850
|
+
visibility: visible !important;
|
|
3851
|
+
}
|
|
3852
|
+
div[class*="hHd-Xa_logoRow"] {
|
|
3853
|
+
display: flex !important;
|
|
3854
|
+
align-items: center !important;
|
|
3855
|
+
justify-content: space-between !important;
|
|
3856
|
+
width: 100% !important;
|
|
3857
|
+
padding: 10px 14px 6px 14px !important;
|
|
3858
|
+
box-sizing: border-box !important;
|
|
3596
3859
|
}
|
|
3597
3860
|
div[class*="hHd-Xa_logoRow"] button[class*="hHd-Xa_toggle"] {
|
|
3598
|
-
display:
|
|
3861
|
+
display: inline-flex !important;
|
|
3862
|
+
align-items: center !important;
|
|
3863
|
+
justify-content: center !important;
|
|
3864
|
+
width: 32px !important;
|
|
3865
|
+
height: 32px !important;
|
|
3866
|
+
border-radius: 8px !important;
|
|
3867
|
+
color: var(--dsw-alias-label-secondary, #6b7280) !important;
|
|
3868
|
+
background: transparent !important;
|
|
3869
|
+
border: none !important;
|
|
3870
|
+
cursor: pointer !important;
|
|
3871
|
+
margin-left: auto !important;
|
|
3872
|
+
transition: background 0.15s, color 0.15s !important;
|
|
3873
|
+
}
|
|
3874
|
+
div[class*="hHd-Xa_logoRow"] button[class*="hHd-Xa_toggle"]:active {
|
|
3875
|
+
background: var(--dsw-alias-bg-layer-2, rgba(0, 0, 0, 0.06)) !important;
|
|
3876
|
+
color: var(--dsw-alias-label-primary, #111827) !important;
|
|
3599
3877
|
}
|
|
3600
3878
|
|
|
3601
3879
|
/* \u8BBE\u7F6E\u5F39\u7A97\u6253\u5F00\u65F6\u89E3\u9664\u62BD\u5C49\u9690\u85CF\u9650\u5236 */
|
|
@@ -3613,8 +3891,6 @@ function injectMobileStyles() {
|
|
|
3613
3891
|
position: fixed;
|
|
3614
3892
|
inset: 0;
|
|
3615
3893
|
background: rgba(0, 0, 0, 0.4);
|
|
3616
|
-
backdrop-filter: blur(4px);
|
|
3617
|
-
-webkit-backdrop-filter: blur(4px);
|
|
3618
3894
|
z-index: 9999;
|
|
3619
3895
|
display: none !important;
|
|
3620
3896
|
}
|
|
@@ -3866,7 +4142,8 @@ function injectMobileStyles() {
|
|
|
3866
4142
|
|
|
3867
4143
|
@media (min-width: 769px) {
|
|
3868
4144
|
.dsh-mobile-app-header,
|
|
3869
|
-
.dsh-mobile-backdrop
|
|
4145
|
+
.dsh-mobile-backdrop,
|
|
4146
|
+
.dsh-mobile-panel-close-btn {
|
|
3870
4147
|
display: none !important;
|
|
3871
4148
|
}
|
|
3872
4149
|
}
|
|
@@ -3890,16 +4167,21 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
3890
4167
|
<line x1="3" y1="15" x2="14" y2="15"></line>
|
|
3891
4168
|
</svg>
|
|
3892
4169
|
`;
|
|
3893
|
-
leftBtn.onclick = () => {
|
|
4170
|
+
leftBtn.onclick = (e) => {
|
|
4171
|
+
e.stopPropagation();
|
|
3894
4172
|
const isOpen = document.body.classList.toggle("dsh-drawer-open");
|
|
3895
4173
|
if (isOpen) {
|
|
3896
|
-
const
|
|
3897
|
-
if (
|
|
4174
|
+
const expand = document.querySelector('button[aria-label*="\u6253\u5F00\u4FA7\u8FB9\u680F"], button[title*="\u6253\u5F00\u4FA7\u8FB9\u680F"]');
|
|
4175
|
+
if (expand) expand.click();
|
|
3898
4176
|
}
|
|
3899
4177
|
};
|
|
3900
4178
|
titleEl = document.createElement("div");
|
|
3901
4179
|
titleEl.className = "dsh-mobile-header-title";
|
|
3902
4180
|
titleEl.innerText = "\u65B0\u4F1A\u8BDD";
|
|
4181
|
+
titleEl.onclick = () => {
|
|
4182
|
+
const openPanels = document.querySelectorAll('div[class*="nArs4W_panel"]:not([class*="panelHidden"]), div[class*="workbench_panel"]:not([class*="panelHidden"])');
|
|
4183
|
+
openPanels.forEach((p) => p.classList.add("nArs4W_panelHidden"));
|
|
4184
|
+
};
|
|
3903
4185
|
const rightBtn = document.createElement("button");
|
|
3904
4186
|
rightBtn.className = "dsh-header-new-btn";
|
|
3905
4187
|
rightBtn.title = "\u65B0\u5EFA\u4F1A\u8BDD";
|
|
@@ -3911,6 +4193,8 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
3911
4193
|
</svg>
|
|
3912
4194
|
`;
|
|
3913
4195
|
rightBtn.onclick = () => {
|
|
4196
|
+
const openPanels = document.querySelectorAll('div[class*="nArs4W_panel"]:not([class*="panelHidden"]), div[class*="workbench_panel"]:not([class*="panelHidden"])');
|
|
4197
|
+
openPanels.forEach((p) => p.classList.add("nArs4W_panelHidden"));
|
|
3914
4198
|
const dshNewBtn = document.querySelector('button[aria-label="\u65B0\u5EFA\u4F1A\u8BDD"]');
|
|
3915
4199
|
if (dshNewBtn) dshNewBtn.click();
|
|
3916
4200
|
};
|
|
@@ -3935,6 +4219,59 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
3935
4219
|
if (typeof ctx?.sessions?.list?.subscribe === "function") {
|
|
3936
4220
|
ctx.sessions.list.subscribe(syncMobileTitle);
|
|
3937
4221
|
}
|
|
4222
|
+
if (typeof ctx?.sessions?.active?.subscribe === "function") {
|
|
4223
|
+
ctx.sessions.active.subscribe(() => {
|
|
4224
|
+
if (document.body.classList.contains("dsh-drawer-open")) {
|
|
4225
|
+
document.body.classList.remove("dsh-drawer-open");
|
|
4226
|
+
}
|
|
4227
|
+
if (typeof window !== "undefined" && window.innerWidth <= 768) {
|
|
4228
|
+
document.body.classList.remove("dsh-workbench-open");
|
|
4229
|
+
const openPanels = document.querySelectorAll('div[class*="nArs4W_panel"]:not([class*="panelHidden"]), div[class*="workbench_panel"]:not([class*="panelHidden"])');
|
|
4230
|
+
openPanels.forEach((p) => p.classList.add("nArs4W_panelHidden"));
|
|
4231
|
+
}
|
|
4232
|
+
});
|
|
4233
|
+
}
|
|
4234
|
+
const ensurePanelCloseButton = () => {
|
|
4235
|
+
if (typeof window === "undefined") return;
|
|
4236
|
+
if (window.innerWidth > 768) {
|
|
4237
|
+
document.querySelectorAll(".dsh-mobile-panel-close-btn").forEach((btn) => btn.remove());
|
|
4238
|
+
return;
|
|
4239
|
+
}
|
|
4240
|
+
const panels = document.querySelectorAll('div[class*="nArs4W_panel"]:not([class*="panelHidden"]), div[class*="workbench_panel"]:not([class*="panelHidden"])');
|
|
4241
|
+
panels.forEach((p) => {
|
|
4242
|
+
const bar = p.querySelector('div[class*="tabBar"], div[class*="nArs4W_tabBar"]');
|
|
4243
|
+
if (bar && !bar.querySelector(".dsh-mobile-panel-close-btn")) {
|
|
4244
|
+
const btn = document.createElement("button");
|
|
4245
|
+
btn.className = "dsh-mobile-panel-close-btn";
|
|
4246
|
+
btn.innerHTML = `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg><span>\u8FD4\u56DE\u5BF9\u8BDD</span>`;
|
|
4247
|
+
btn.onclick = (e) => {
|
|
4248
|
+
e.stopPropagation();
|
|
4249
|
+
document.body.classList.remove("dsh-workbench-open");
|
|
4250
|
+
p.classList.add("nArs4W_panelHidden");
|
|
4251
|
+
const collapseBtn = document.querySelector('button[class*="toggleButton"][aria-label*="\u6536\u8D77"]');
|
|
4252
|
+
if (collapseBtn) collapseBtn.click();
|
|
4253
|
+
};
|
|
4254
|
+
bar.appendChild(btn);
|
|
4255
|
+
}
|
|
4256
|
+
});
|
|
4257
|
+
};
|
|
4258
|
+
const panelObserver = new MutationObserver(ensurePanelCloseButton);
|
|
4259
|
+
panelObserver.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ["class"] });
|
|
4260
|
+
window.addEventListener("resize", ensurePanelCloseButton);
|
|
4261
|
+
document.addEventListener("click", (e) => {
|
|
4262
|
+
if (typeof window === "undefined" || window.innerWidth > 768) return;
|
|
4263
|
+
const trigger = e.target.closest('button[aria-label*="\u9762\u677F"], button[aria-label*="\u5DE5\u4F5C\u533A"], div[class*="toggleCluster"] button, button[class*="subagent"], div[class*="headerActions"] button, div[class*="titleRow"] button');
|
|
4264
|
+
if (trigger && !trigger.classList.contains("dsh-mobile-panel-close-btn") && !trigger.classList.contains("dsh-header-menu-btn") && !trigger.classList.contains("dsh-header-new-btn")) {
|
|
4265
|
+
document.body.classList.add("dsh-workbench-open");
|
|
4266
|
+
}
|
|
4267
|
+
}, true);
|
|
4268
|
+
document.addEventListener("click", (e) => {
|
|
4269
|
+
if (typeof window === "undefined" || window.innerWidth > 768) return;
|
|
4270
|
+
const toggle = e.target.closest('button[aria-label*="\u6536\u8D77\u4FA7\u8FB9\u680F"], button[title*="\u6536\u8D77\u4FA7\u8FB9\u680F"]');
|
|
4271
|
+
if (toggle) {
|
|
4272
|
+
document.body.classList.remove("dsh-drawer-open");
|
|
4273
|
+
}
|
|
4274
|
+
}, true);
|
|
3938
4275
|
let backdrop = document.querySelector(".dsh-mobile-backdrop");
|
|
3939
4276
|
if (!backdrop) {
|
|
3940
4277
|
backdrop = document.createElement("div");
|
|
@@ -3971,10 +4308,16 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
3971
4308
|
return;
|
|
3972
4309
|
}
|
|
3973
4310
|
}
|
|
3974
|
-
const sessionRow = e.target.closest('div[class*="sessionRow"], div[role="treeitem"]');
|
|
4311
|
+
const sessionRow = e.target.closest('a, div[class*="sessionRow"], div[role="treeitem"]');
|
|
3975
4312
|
if (sessionRow) {
|
|
3976
|
-
|
|
4313
|
+
setTimeout(() => {
|
|
4314
|
+
if (document.body.classList.contains("dsh-drawer-open")) {
|
|
4315
|
+
document.body.classList.remove("dsh-drawer-open");
|
|
4316
|
+
}
|
|
4317
|
+
}, 80);
|
|
3977
4318
|
}
|
|
4319
|
+
} else if (e.target.classList?.contains("dsh-mobile-backdrop")) {
|
|
4320
|
+
document.body.classList.remove("dsh-drawer-open");
|
|
3978
4321
|
}
|
|
3979
4322
|
}, true);
|
|
3980
4323
|
let longPressTimer = null;
|
|
@@ -4570,28 +4913,7 @@ function RemoteDirectoryFlow(props) {
|
|
|
4570
4913
|
const outcome = React.useRef(props);
|
|
4571
4914
|
outcome.current = props;
|
|
4572
4915
|
const armed = React.useRef(false);
|
|
4573
|
-
|
|
4574
|
-
if (!open) {
|
|
4575
|
-
armed.current = false;
|
|
4576
|
-
return;
|
|
4577
|
-
}
|
|
4578
|
-
if (armed.current) return;
|
|
4579
|
-
armed.current = true;
|
|
4580
|
-
if (isLocalEnvironment()) {
|
|
4581
|
-
const pickFn = typeof pick === "function" ? pick : typeof window.__dshClientCtx?.workspaces?.pickDirectory === "function" ? () => window.__dshClientCtx.workspaces.pickDirectory() : null;
|
|
4582
|
-
if (pickFn) {
|
|
4583
|
-
pickFn().then((chosenPath) => {
|
|
4584
|
-
if (chosenPath === null) {
|
|
4585
|
-
if (outcome.current?.onCancel) outcome.current.onCancel();
|
|
4586
|
-
} else if (chosenPath) {
|
|
4587
|
-
if (outcome.current?.onPicked) outcome.current.onPicked(chosenPath);
|
|
4588
|
-
}
|
|
4589
|
-
}, (err) => {
|
|
4590
|
-
if (outcome.current?.onError) outcome.current.onError(err instanceof Error ? err.message : String(err));
|
|
4591
|
-
});
|
|
4592
|
-
return;
|
|
4593
|
-
}
|
|
4594
|
-
}
|
|
4916
|
+
const openRemoteModal = () => {
|
|
4595
4917
|
if (typeof window.__dshOpenRemoteWorkspaceModal === "function") {
|
|
4596
4918
|
window.__dshOpenRemoteWorkspaceModal(
|
|
4597
4919
|
(res) => {
|
|
@@ -4610,7 +4932,42 @@ function RemoteDirectoryFlow(props) {
|
|
|
4610
4932
|
}
|
|
4611
4933
|
}
|
|
4612
4934
|
);
|
|
4935
|
+
} else if (outcome.current?.onCancel) {
|
|
4936
|
+
outcome.current.onCancel();
|
|
4937
|
+
}
|
|
4938
|
+
};
|
|
4939
|
+
React.useEffect(() => {
|
|
4940
|
+
if (!open) {
|
|
4941
|
+
armed.current = false;
|
|
4942
|
+
return;
|
|
4943
|
+
}
|
|
4944
|
+
if (armed.current) return;
|
|
4945
|
+
armed.current = true;
|
|
4946
|
+
const isNativeHost = typeof window !== "undefined" && (window.electron || window.__DSH_NATIVE_HOST__);
|
|
4947
|
+
if (isNativeHost || isLocalEnvironment()) {
|
|
4948
|
+
const pickFn = typeof pick === "function" ? pick : typeof window.__dshClientCtx?.workspaces?.pickDirectory === "function" ? () => window.__dshClientCtx.workspaces.pickDirectory() : null;
|
|
4949
|
+
if (pickFn) {
|
|
4950
|
+
try {
|
|
4951
|
+
const promise = pickFn();
|
|
4952
|
+
if (promise && typeof promise.then === "function") {
|
|
4953
|
+
promise.then((chosenPath) => {
|
|
4954
|
+
if (chosenPath === null) {
|
|
4955
|
+
if (outcome.current?.onCancel) outcome.current.onCancel();
|
|
4956
|
+
} else if (chosenPath) {
|
|
4957
|
+
if (outcome.current?.onPicked) outcome.current.onPicked(chosenPath);
|
|
4958
|
+
}
|
|
4959
|
+
}).catch(() => {
|
|
4960
|
+
openRemoteModal();
|
|
4961
|
+
});
|
|
4962
|
+
return;
|
|
4963
|
+
}
|
|
4964
|
+
} catch {
|
|
4965
|
+
openRemoteModal();
|
|
4966
|
+
return;
|
|
4967
|
+
}
|
|
4968
|
+
}
|
|
4613
4969
|
}
|
|
4970
|
+
openRemoteModal();
|
|
4614
4971
|
}, [open, pick]);
|
|
4615
4972
|
return null;
|
|
4616
4973
|
}
|