@wenbin_wb/dsh-bridge 2.5.5 → 2.6.0

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/client/client.js CHANGED
@@ -115,7 +115,7 @@ function semverGt(a, b) {
115
115
  return av.pre > bv.pre;
116
116
  }
117
117
  var s = {
118
- card: { background: "var(--dsw-alias-bg-layer-2,#f9fafb)", border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", borderRadius: 12, padding: "16px 20px", marginBottom: 16 },
118
+ card: { background: "var(--dsw-alias-bg-layer-2,#f9fafb)", border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", borderRadius: 12, padding: "16px 18px", marginBottom: 16, boxSizing: "border-box" },
119
119
  block: { borderTop: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", marginTop: 12, paddingTop: 12 },
120
120
  muted: { color: "var(--dsw-alias-label-tertiary,#8b93a1)", fontSize: 12, lineHeight: 1.5 },
121
121
  label: { color: "var(--dsw-alias-label-primary,currentColor)", fontSize: 13, fontWeight: 500 },
@@ -123,8 +123,8 @@ var s = {
123
123
  btnPri: { font: "inherit", cursor: "pointer", border: "none", background: "var(--dsw-alias-brand-primary,#4f6ef7)", color: "var(--dsw-alias-label-primary-foreground,#fff)", height: 32, padding: "0 14px", borderRadius: 999, fontSize: 13, fontWeight: 500, display: "inline-flex", alignItems: "center", gap: 4 },
124
124
  btnGhost: { font: "inherit", cursor: "pointer", border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", background: "var(--dsw-alias-bg-layer-2,#f9fafb)", color: "var(--dsw-alias-label-primary,currentColor)", height: 32, padding: "0 14px", borderRadius: 999, fontSize: 13, display: "inline-flex", alignItems: "center", gap: 4, textDecoration: "none" },
125
125
  btnLink: { font: "inherit", cursor: "pointer", border: "none", background: "none", color: "var(--dsw-alias-brand-primary,#4f6ef7)", fontSize: 12, padding: 0, display: "inline-flex", alignItems: "center", gap: 3, textDecoration: "none" },
126
- qr: { width: 200, height: 200, borderRadius: 10, border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", margin: "8px 0", display: "block", background: "#ffffff", padding: 6, boxSizing: "border-box" },
127
- tag: { display: "inline-flex", alignItems: "center", padding: "2px 8px", borderRadius: 999, fontSize: 12, fontWeight: 500 },
126
+ qr: { width: 200, height: 200, maxWidth: "100%", borderRadius: 10, border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", margin: "8px 0", display: "block", background: "#ffffff", padding: 6, boxSizing: "border-box" },
127
+ tag: { display: "inline-flex", alignItems: "center", justifyContent: "center", padding: "3px 10px", borderRadius: 999, fontSize: 12, fontWeight: 500, whiteSpace: "nowrap", flexShrink: 0, minWidth: "max-content", lineHeight: 1.4 },
128
128
  input: { width: "100%", font: "inherit", fontSize: 13, padding: "7px 10px", borderRadius: 8, border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", background: "var(--dsw-alias-bg-layer-2,#f9fafb)", color: "var(--dsw-alias-label-primary,currentColor)", outline: "none", boxSizing: "border-box" },
129
129
  warn: { background: "var(--dsw-alias-state-warn-bg,#fffbeb)", border: "1px solid var(--dsw-alias-state-warn-border,#fde68a)", borderRadius: 8, padding: "10px 14px", fontSize: 12, color: "var(--dsw-alias-state-warn-primary,#92400e)", lineHeight: 1.6 },
130
130
  tip: { background: "var(--dsw-alias-bg-layer-2,#f9fafb)", borderRadius: 8, padding: "10px 14px", fontSize: 12, color: "var(--dsw-alias-label-secondary,#6b7280)", lineHeight: 1.6 }
@@ -281,10 +281,11 @@ function QrBlock({ url, qr, onReset, auth, onNavigateSecurity }) {
281
281
  "div",
282
282
  {
283
283
  style: {
284
- display: "inline-flex",
284
+ display: "flex",
285
285
  alignItems: "center",
286
+ justifyContent: "space-between",
286
287
  gap: 6,
287
- padding: "4px 10px",
288
+ padding: "6px 10px",
288
289
  background: "var(--dsw-alias-state-success-bg,#ecfdf5)",
289
290
  border: "1px solid var(--dsw-alias-state-success-primary,#10b981)",
290
291
  borderRadius: 8,
@@ -292,13 +293,14 @@ function QrBlock({ url, qr, onReset, auth, onNavigateSecurity }) {
292
293
  color: "var(--dsw-alias-state-success-primary,#059669)",
293
294
  marginBottom: 8,
294
295
  fontWeight: 500,
296
+ flexWrap: "wrap",
295
297
  cursor: onNavigateSecurity ? "pointer" : "default"
296
298
  },
297
299
  onClick: onNavigateSecurity,
298
300
  title: onNavigateSecurity ? "\u70B9\u51FB\u524D\u5F80\u300C\u5B89\u5168\u8BA4\u8BC1\u300D\u914D\u7F6E" : void 0
299
301
  },
300
- "\u{1F6E1}\uFE0F \u8BBF\u95EE\u5B89\u5168\u8BA4\u8BC1\u5DF2\u751F\u6548 \xB7 \u626B\u7801\u8BBE\u5907\u81EA\u52A8\u5B8C\u6210\u514D\u5BC6\u6388\u6743",
301
- onNavigateSecurity && React.createElement("span", { style: { textDecoration: "underline", fontSize: 11, marginLeft: 4 } }, "\u8BBE\u7F6E \u2794")
302
+ React.createElement("span", { style: { display: "inline-flex", alignItems: "center", gap: 4 } }, "\u{1F6E1}\uFE0F \u8BBF\u95EE\u5B89\u5168\u8BA4\u8BC1\u5DF2\u751F\u6548 \xB7 \u626B\u7801\u8BBE\u5907\u514D\u5BC6"),
303
+ onNavigateSecurity && React.createElement("span", { style: { textDecoration: "underline", fontSize: 11, fontWeight: 600 } }, "\u8BBE\u7F6E \u2794")
302
304
  ) : React.createElement(
303
305
  "div",
304
306
  {
@@ -311,20 +313,28 @@ function QrBlock({ url, qr, onReset, auth, onNavigateSecurity }) {
311
313
  ),
312
314
  React.createElement(
313
315
  "div",
314
- { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 6 } },
315
- React.createElement("code", { style: { ...s.code, flex: 1 } }, url),
316
- React.createElement("button", {
317
- style: { ...s.btnGhost, height: 26, padding: "0 10px", fontSize: 12, flexShrink: 0 },
318
- onClick: copy
319
- }, copied ? "\u2713 \u5DF2\u590D\u5236" : "\u590D\u5236"),
320
- React.createElement("button", {
321
- style: { ...s.btnGhost, height: 26, padding: "0 10px", fontSize: 12, flexShrink: 0 },
322
- onClick: toggleQr
323
- }, showQr ? "\u9690\u85CF\u4E8C\u7EF4\u7801" : "\u663E\u793A\u4E8C\u7EF4\u7801")
316
+ { style: { display: "flex", flexDirection: "column", gap: 8, marginTop: 8 } },
317
+ React.createElement(
318
+ "div",
319
+ { style: { padding: "6px 10px", background: "var(--dsw-alias-bg-layer-1,#ffffff)", border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", borderRadius: 8 } },
320
+ React.createElement("code", { style: { ...s.code, display: "block", wordBreak: "break-all", fontSize: 12, lineHeight: 1.5 } }, url)
321
+ ),
322
+ React.createElement(
323
+ "div",
324
+ { style: { display: "flex", gap: 8, alignItems: "center" } },
325
+ React.createElement("button", {
326
+ style: { ...s.btnGhost, height: 28, padding: "0 12px", fontSize: 12, flex: "1 1 auto", justifyContent: "center" },
327
+ onClick: copy
328
+ }, copied ? "\u2713 \u5DF2\u590D\u5236" : "\u590D\u5236\u94FE\u63A5"),
329
+ React.createElement("button", {
330
+ style: { ...s.btnGhost, height: 28, padding: "0 12px", fontSize: 12, flex: "1 1 auto", justifyContent: "center" },
331
+ onClick: toggleQr
332
+ }, showQr ? "\u9690\u85CF\u4E8C\u7EF4\u7801" : "\u663E\u793A\u4E8C\u7EF4\u7801")
333
+ )
324
334
  ),
325
335
  showQr && qr && React.createElement(
326
336
  "div",
327
- { style: { marginTop: 8 } },
337
+ { style: { marginTop: 10 } },
328
338
  React.createElement("img", { src: qr, alt: "QR", style: s.qr }),
329
339
  React.createElement("div", { style: { ...s.muted, marginTop: 4 } }, "\u8BF7\u5728\u79C1\u5BC6\u73AF\u5883\u4E0B\u4F7F\u7528")
330
340
  ),
@@ -445,10 +455,10 @@ var TunnelCard = React.memo(function TunnelCard2({ title, desc, data, onStart, o
445
455
  { style: s.card },
446
456
  React.createElement(
447
457
  "div",
448
- { style: { display: "flex", justifyContent: "space-between", alignItems: "center" } },
458
+ { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 10 } },
449
459
  React.createElement(
450
460
  "div",
451
- null,
461
+ { style: { flex: "1 1 auto", minWidth: 0 } },
452
462
  React.createElement("div", { style: s.label }, title),
453
463
  React.createElement("div", { style: { ...s.muted, marginTop: 2 } }, desc)
454
464
  ),
@@ -1129,10 +1139,10 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
1129
1139
  { style: s.card },
1130
1140
  React.createElement(
1131
1141
  "div",
1132
- { style: { display: "flex", justifyContent: "space-between", alignItems: "center" } },
1142
+ { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 10 } },
1133
1143
  React.createElement(
1134
1144
  "div",
1135
- null,
1145
+ { style: { flex: "1 1 auto", minWidth: 0 } },
1136
1146
  React.createElement(
1137
1147
  "div",
1138
1148
  { style: { ...s.label, display: "flex", alignItems: "center", gap: 7 } },
@@ -1737,6 +1747,25 @@ function VersionBanner({ rpcCall }) {
1737
1747
  ) : upgradeResult?.ok ? "\u2713 \u5DF2\u5B8C\u6210\u5347\u7EA7" : `\u4E00\u952E\u5347\u7EA7\u5230 v${info.latest}`
1738
1748
  )
1739
1749
  ),
1750
+ // 简短更新内容 / Release Notes 亮点展示
1751
+ info?.releaseNotes && React.createElement(
1752
+ "div",
1753
+ {
1754
+ style: {
1755
+ fontSize: 12,
1756
+ color: "var(--dsw-alias-label-secondary,#374151)",
1757
+ background: "rgba(255, 255, 255, 0.75)",
1758
+ border: "1px solid rgba(191, 219, 254, 0.7)",
1759
+ borderRadius: 8,
1760
+ padding: "8px 12px",
1761
+ marginBottom: 10,
1762
+ lineHeight: 1.6,
1763
+ whiteSpace: "pre-line"
1764
+ }
1765
+ },
1766
+ React.createElement("div", { style: { fontWeight: 600, color: "var(--dsw-alias-state-info-primary,#1e40af)", marginBottom: 2 } }, "\u2728 \u66F4\u65B0\u4EAE\u70B9\uFF1A"),
1767
+ info.releaseNotes
1768
+ ),
1740
1769
  upgradeResult && React.createElement("div", {
1741
1770
  style: {
1742
1771
  background: upgradeResult.ok ? "var(--dsw-alias-state-success-bg,#ecfdf5)" : "var(--dsw-alias-state-error-bg,#fef2f2)",
@@ -1785,7 +1814,11 @@ function TabBar({ active, onChange, dots }) {
1785
1814
  display: "flex",
1786
1815
  gap: 4,
1787
1816
  marginBottom: 20,
1788
- borderBottom: "1px solid var(--dsw-alias-border-l2,#e5e7eb)"
1817
+ borderBottom: "1px solid var(--dsw-alias-border-l2,#e5e7eb)",
1818
+ overflowX: "auto",
1819
+ WebkitOverflowScrolling: "touch",
1820
+ maxWidth: "100%",
1821
+ flexWrap: "nowrap"
1789
1822
  }
1790
1823
  },
1791
1824
  TABS.map(({ id, label, icon: TabIcon }) => {
@@ -1801,7 +1834,7 @@ function TabBar({ active, onChange, dots }) {
1801
1834
  cursor: "pointer",
1802
1835
  border: "none",
1803
1836
  background: "none",
1804
- padding: "8px 16px",
1837
+ padding: "8px 14px",
1805
1838
  fontSize: 13,
1806
1839
  fontWeight: isActive ? 600 : 400,
1807
1840
  color: isActive ? "var(--dsw-alias-brand-primary,#4f6ef7)" : "var(--dsw-alias-label-secondary,#6b7280)",
@@ -1809,9 +1842,10 @@ function TabBar({ active, onChange, dots }) {
1809
1842
  marginBottom: -1,
1810
1843
  display: "inline-flex",
1811
1844
  alignItems: "center",
1812
- gap: 7,
1845
+ gap: 6,
1813
1846
  transition: "color .15s, border-color .15s",
1814
- whiteSpace: "nowrap"
1847
+ whiteSpace: "nowrap",
1848
+ flexShrink: 0
1815
1849
  }
1816
1850
  },
1817
1851
  TabIcon && React.createElement(TabIcon, {
@@ -2442,7 +2476,485 @@ function BridgePanel({ rpcCall }) {
2442
2476
  )
2443
2477
  );
2444
2478
  }
2479
+ function injectMobileStyles() {
2480
+ if (typeof document === "undefined") return;
2481
+ if (document.getElementById("dsh-bridge-mobile-styles")) return;
2482
+ const style = document.createElement("style");
2483
+ style.id = "dsh-bridge-mobile-styles";
2484
+ style.textContent = `
2485
+ /* DSH Bridge \u79FB\u52A8\u7AEF\u81EA\u9002\u5E94\u4E0E\u89E6\u63A7\u4EA4\u4E92\u589E\u5F3A\u6837\u5F0F */
2486
+ :root {
2487
+ --dsh-mobile-header-h: 52px;
2488
+ --dsh-mobile-safe-top: env(safe-area-inset-top, 0px);
2489
+ --dsh-mobile-safe-bottom: env(safe-area-inset-bottom, 0px);
2490
+ }
2491
+
2492
+ @media (max-width: 768px) {
2493
+ /* 1. \u4E3B\u6846\u67B6\u4E3A Header \u817E\u51FA\u9876\u90E8\u7A7A\u95F4 */
2494
+ div[class*="_frame"] {
2495
+ display: flex !important;
2496
+ flex-direction: column !important;
2497
+ width: 100vw !important;
2498
+ height: 100dvh !important;
2499
+ margin: 0 !important;
2500
+ padding-top: var(--dsh-mobile-header-h) !important;
2501
+ position: relative !important;
2502
+ grid-template-columns: 1fr !important;
2503
+ overflow: hidden !important;
2504
+ box-sizing: border-box !important;
2505
+ }
2506
+
2507
+ /* 2. \u9876\u90E8\u539F\u751F\u5BFC\u822A\u6761\uFF1A100% \u8FD8\u539F DeepSeek App (\u5DE6\u4FA7\u53CC\u6A2A\u7EBF\uFF0C\u53F3\u4FA7(+)\uFF0C\u4E2D\u95F4\u7559\u767D\uFF0C\u65E0\u591A\u4F59\u8BBE\u7F6E\u6309\u94AE) */
2508
+ .dsh-mobile-app-header {
2509
+ position: fixed !important;
2510
+ top: 0 !important;
2511
+ left: 0 !important;
2512
+ right: 0 !important;
2513
+ height: var(--dsh-mobile-header-h) !important;
2514
+ padding-top: var(--dsh-mobile-safe-top) !important;
2515
+ background: transparent !important;
2516
+ display: flex !important;
2517
+ align-items: center !important;
2518
+ justify-content: space-between !important;
2519
+ padding-left: 16px !important;
2520
+ padding-right: 16px !important;
2521
+ z-index: 9998 !important;
2522
+ box-sizing: border-box !important;
2523
+ user-select: none !important;
2524
+ }
2525
+
2526
+ /* \u5DE6\u4FA7\u53CC\u6A2A\u7EBF\u6309\u94AE (DeepSeek App \u539F\u751F\u56FE\u6807) */
2527
+ .dsh-header-menu-btn {
2528
+ width: 40px;
2529
+ height: 40px;
2530
+ border-radius: 50%;
2531
+ border: none;
2532
+ background: transparent;
2533
+ color: var(--dsw-alias-label-primary, #111827);
2534
+ display: inline-flex;
2535
+ align-items: center;
2536
+ justify-content: flex-start;
2537
+ cursor: pointer;
2538
+ padding: 0;
2539
+ transition: opacity 0.15s;
2540
+ }
2541
+ .dsh-header-menu-btn:active {
2542
+ opacity: 0.6;
2543
+ }
2544
+
2545
+ /* \u53F3\u4FA7 (+) \u65B0\u5EFA\u4F1A\u8BDD\u6309\u94AE (DeepSeek App \u539F\u751F\u56FE\u6807) */
2546
+ .dsh-header-new-btn {
2547
+ width: 40px;
2548
+ height: 40px;
2549
+ border-radius: 50%;
2550
+ border: none;
2551
+ background: transparent;
2552
+ color: var(--dsw-alias-label-primary, #111827);
2553
+ display: inline-flex;
2554
+ align-items: center;
2555
+ justify-content: flex-end;
2556
+ cursor: pointer;
2557
+ padding: 0;
2558
+ transition: opacity 0.15s;
2559
+ }
2560
+ .dsh-header-new-btn:active {
2561
+ opacity: 0.6;
2562
+ }
2563
+
2564
+ /* 3. \u4E2D\u95F4\u4E3B\u5185\u5BB9\u533A\u4E0E\u8F93\u5165\u6846 */
2565
+ div[class*="_centerCol"] {
2566
+ flex: 1 1 100% !important;
2567
+ width: 100% !important;
2568
+ min-width: 0 !important;
2569
+ max-width: 100% !important;
2570
+ display: flex !important;
2571
+ height: 100% !important;
2572
+ }
2573
+
2574
+ div[class*="_detailsCol"],
2575
+ div[class*="toggleCluster"],
2576
+ div[class*="W-zNGW_toggleCluster"] {
2577
+ display: none !important;
2578
+ }
2579
+
2580
+ /* \u8F93\u5165\u6846\u5E95\u5EA7\uFF1ADeepSeek App \u5C45\u4E2D\u53CA\u5E95\u90E8\u56FA\u5B9A */
2581
+ div[class*="wSkVaW_scrollBody"] {
2582
+ padding-bottom: max(16px, env(safe-area-inset-bottom)) !important;
2583
+ }
2584
+
2585
+ /* \u8F93\u5165\u5361\u7247\uFF1ADeepSeek App \u5706\u89D2\u5927\u80F6\u56CA\u9020\u578B */
2586
+ div[class*="uV2eYG_card"] {
2587
+ border-radius: 26px !important;
2588
+ padding: 14px 16px 12px !important;
2589
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05) !important;
2590
+ border: 1px solid rgba(0, 0, 0, 0.07) !important;
2591
+ background: var(--dsw-alias-bg-layer-2, #f4f4f7) !important;
2592
+ }
2593
+
2594
+ /* 4. \u539F\u751F\u4FA7\u8FB9\u680F\u62BD\u5C49\u5316 (Drawer) */
2595
+ div[class*="_sidebarCol"] {
2596
+ position: fixed !important;
2597
+ left: 0 !important;
2598
+ top: 0 !important;
2599
+ bottom: 0 !important;
2600
+ height: 100dvh !important;
2601
+ width: 290px !important;
2602
+ max-width: 82vw !important;
2603
+ z-index: 10000 !important;
2604
+ background: var(--dsw-alias-bg-layer-1, #ffffff) !important;
2605
+ transform: translateX(-105%);
2606
+ transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
2607
+ overflow-y: auto !important;
2608
+ border-right: 1px solid rgba(0, 0, 0, 0.06) !important;
2609
+ }
2610
+ body.dsh-drawer-open div[class*="_sidebarCol"] {
2611
+ transform: translateX(0) !important;
2612
+ box-shadow: 4px 0 28px rgba(0, 0, 0, 0.25) !important;
2613
+ }
2614
+
2615
+ /* \u62BD\u5C49\u5185\u90E8\uFF1A\u5F3A\u5236 100% \u5BBD\u5EA6\uFF0C\u9690\u85CF\u5197\u4F59\u6298\u53E0\u6309\u94AE */
2616
+ body.dsh-drawer-open div[class*="hHd-Xa_root"] {
2617
+ width: 100% !important;
2618
+ max-width: 100% !important;
2619
+ }
2620
+ div[class*="hHd-Xa_logoRow"] button[class*="hHd-Xa_toggle"] {
2621
+ display: none !important;
2622
+ }
2623
+
2624
+ /* \u8BBE\u7F6E\u5F39\u7A97\u6253\u5F00\u65F6\u89E3\u9664\u62BD\u5C49\u9690\u85CF\u9650\u5236 */
2625
+ div[class*="_sidebarCol"]:has(div[class*="VOzbGW_overlay"]) {
2626
+ transform: none !important;
2627
+ width: 100vw !important;
2628
+ max-width: 100vw !important;
2629
+ background: transparent !important;
2630
+ box-shadow: none !important;
2631
+ pointer-events: none !important;
2632
+ }
2633
+
2634
+ /* 5. \u534A\u900F\u660E\u80CC\u666F\u906E\u7F69 */
2635
+ .dsh-mobile-backdrop {
2636
+ position: fixed;
2637
+ inset: 0;
2638
+ background: rgba(0, 0, 0, 0.4);
2639
+ backdrop-filter: blur(4px);
2640
+ -webkit-backdrop-filter: blur(4px);
2641
+ z-index: 9999;
2642
+ display: none !important;
2643
+ }
2644
+ body.dsh-drawer-open .dsh-mobile-backdrop {
2645
+ display: block !important;
2646
+ pointer-events: auto !important;
2647
+ }
2648
+
2649
+ /* 6. \u8BBE\u7F6E\u4E2D\u5FC3\u5168\u81EA\u9002\u5E94\u9002\u914D */
2650
+ div[class*="VOzbGW_overlay"] {
2651
+ position: fixed !important;
2652
+ inset: 0 !important;
2653
+ width: 100vw !important;
2654
+ height: 100dvh !important;
2655
+ display: flex !important;
2656
+ align-items: center !important;
2657
+ justify-content: center !important;
2658
+ background: rgba(0, 0, 0, 0.45) !important;
2659
+ backdrop-filter: blur(4px) !important;
2660
+ -webkit-backdrop-filter: blur(4px) !important;
2661
+ z-index: 10002 !important;
2662
+ padding: 10px !important;
2663
+ box-sizing: border-box !important;
2664
+ pointer-events: auto !important;
2665
+ }
2666
+ div[class*="VOzbGW_panel"] {
2667
+ width: 100% !important;
2668
+ max-width: 100% !important;
2669
+ height: 92dvh !important;
2670
+ max-height: 92dvh !important;
2671
+ display: flex !important;
2672
+ flex-direction: row !important;
2673
+ border-radius: 18px !important;
2674
+ overflow: hidden !important;
2675
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.25) !important;
2676
+ background: var(--dsw-alias-bg-layer-1, #ffffff) !important;
2677
+ }
2678
+ nav[class*="VOzbGW_nav"] {
2679
+ width: 78px !important;
2680
+ min-width: 78px !important;
2681
+ max-width: 78px !important;
2682
+ padding: 10px 4px !important;
2683
+ box-sizing: border-box !important;
2684
+ border-right: 1px solid var(--dsw-alias-border-l2, #e5e7eb) !important;
2685
+ display: flex !important;
2686
+ flex-direction: column !important;
2687
+ gap: 6px !important;
2688
+ overflow-y: auto !important;
2689
+ }
2690
+ nav[class*="VOzbGW_nav"] button[class*="VOzbGW_navCell"],
2691
+ button[class*="VOzbGW_navCell"] {
2692
+ padding: 8px 2px !important;
2693
+ display: flex !important;
2694
+ flex-direction: column !important;
2695
+ align-items: center !important;
2696
+ justify-content: center !important;
2697
+ text-align: center !important;
2698
+ height: auto !important;
2699
+ min-height: 48px !important;
2700
+ gap: 4px !important;
2701
+ border-radius: 10px !important;
2702
+ }
2703
+ span[class*="VOzbGW_navLabel"] {
2704
+ font-size: 10.5px !important;
2705
+ line-height: 1.2 !important;
2706
+ white-space: normal !important;
2707
+ word-break: break-all !important;
2708
+ text-align: center !important;
2709
+ }
2710
+ div[class*="VOzbGW_content"] {
2711
+ flex: 1 1 auto !important;
2712
+ min-width: 0 !important;
2713
+ width: calc(100% - 78px) !important;
2714
+ max-width: calc(100% - 78px) !important;
2715
+ display: flex !important;
2716
+ flex-direction: column !important;
2717
+ overflow: hidden !important;
2718
+ }
2719
+ div[class*="VOzbGW_options"] {
2720
+ flex: 1 1 auto !important;
2721
+ width: 100% !important;
2722
+ max-width: 100% !important;
2723
+ box-sizing: border-box !important;
2724
+ padding: 0 14px 20px !important;
2725
+ overflow-x: hidden !important;
2726
+ overflow-y: auto !important;
2727
+ -webkit-overflow-scrolling: touch !important;
2728
+ }
2729
+
2730
+ /* \u8BBE\u7F6E\u4E2D\u5FC3\u9009\u9879\u884C\u624B\u673A\u81EA\u9002\u5E94\uFF08\u5782\u76F4\u6D41\u5F0F\uFF0C\u9632\u6587\u5B57\u5355\u5B57\u6298\u884C\uFF09 */
2731
+ div[class*="VOzbGW_options"] div[class*="_row"] {
2732
+ display: flex !important;
2733
+ flex-direction: column !important;
2734
+ align-items: stretch !important;
2735
+ gap: 8px !important;
2736
+ width: 100% !important;
2737
+ padding: 12px 0 !important;
2738
+ box-sizing: border-box !important;
2739
+ }
2740
+ div[class*="VOzbGW_options"] div[class*="_rowText"] {
2741
+ width: 100% !important;
2742
+ max-width: 100% !important;
2743
+ }
2744
+ div[class*="VOzbGW_options"] button[class*="_selector"],
2745
+ div[class*="VOzbGW_options"] select,
2746
+ div[class*="VOzbGW_options"] input {
2747
+ width: 100% !important;
2748
+ max-width: 100% !important;
2749
+ box-sizing: border-box !important;
2750
+ }
2751
+
2752
+ /* 7. \u4EE3\u7801\u5757\u3001\u8868\u683C\u4E0E\u5FBD\u6807\u81EA\u9002\u5E94 */
2753
+ pre, code, pre > code, table {
2754
+ max-width: 100% !important;
2755
+ overflow-x: auto !important;
2756
+ -webkit-overflow-scrolling: touch !important;
2757
+ font-size: 12.5px !important;
2758
+ }
2759
+
2760
+ /* \u72B6\u6001\u5FBD\u6807\u4E0E\u836F\u4E38\u6309\u94AE\u6C38\u4E0D\u6298\u5B57 */
2761
+ span[style*="border-radius: 999"],
2762
+ span[style*="border-radius:999"] {
2763
+ white-space: nowrap !important;
2764
+ flex-shrink: 0 !important;
2765
+ min-width: max-content !important;
2766
+ }
2767
+
2768
+ /* \u4E8C\u7EF4\u7801\u4E0E\u56FE\u7247\u79FB\u52A8\u7AEF\u5F39\u6027\u7F29\u653E */
2769
+ img[alt="QR"], img[src^="data:image"] {
2770
+ max-width: 100% !important;
2771
+ box-sizing: border-box !important;
2772
+ }
2773
+
2774
+ /* 8. \u786E\u4FDD\u6240\u6709 Popover \u5F39\u51FA\u83DC\u5355\u3001\u64CD\u4F5C\u6C14\u6CE1\u3001\u4E0B\u62C9\u6846\u4F4D\u4E8E\u62BD\u5C49\u4E4B\u4E0A\u4E14\u652F\u6301\u89E6\u63A7\u4EA4\u4E92 */
2775
+ div[class*="_portal"],
2776
+ div[class*="portal"],
2777
+ div[class*="popup"],
2778
+ div[class*="dropdown"],
2779
+ div[class*="menu"],
2780
+ div[role="menu"],
2781
+ div[role="dialog"] {
2782
+ z-index: 10005 !important;
2783
+ pointer-events: auto !important;
2784
+ }
2785
+
2786
+ /* 9. \u79FB\u52A8\u7AEF\u4FA7\u8FB9\u680F\uFF1A\u4F1A\u8BDD\u4E0E\u5DE5\u4F5C\u533A\u4E09\u70B9\u64CD\u4F5C\u6309\u94AE\u59CB\u7EC8\u6E05\u6670\u53EF\u89C1\u4E14\u6613\u4E8E\u70B9\u51FB */
2787
+ div[class*="sessionRow"] span[class*="rowActions"],
2788
+ div[class*="sessionRow"] button[class*="iconButton"],
2789
+ div[class*="treeBody"] button[class*="iconButton"] {
2790
+ opacity: 0.8 !important;
2791
+ display: inline-flex !important;
2792
+ visibility: visible !important;
2793
+ pointer-events: auto !important;
2794
+ }
2795
+ div[class*="sessionRow"]:active {
2796
+ background: var(--dsw-alias-bg-layer-2, #f3f4f6) !important;
2797
+ }
2798
+
2799
+ /* \u5168\u5C40 overlayLayer \u7EDD\u4E0D\u88AB\u67D3\u9ED1 */
2800
+ div[class*="overlayLayer"],
2801
+ div[class*="uV2eYG_overlayAnchor"] {
2802
+ background: transparent !important;
2803
+ pointer-events: none !important;
2804
+ }
2805
+ div[class*="overlayLayer"] > * {
2806
+ pointer-events: auto !important;
2807
+ }
2808
+ }
2809
+
2810
+ @media (min-width: 769px) {
2811
+ .dsh-mobile-app-header,
2812
+ .dsh-mobile-backdrop {
2813
+ display: none !important;
2814
+ }
2815
+ }
2816
+ `;
2817
+ document.head.appendChild(style);
2818
+ }
2819
+ function setupMobileExperience() {
2820
+ if (typeof document === "undefined" || typeof window === "undefined") return;
2821
+ injectMobileStyles();
2822
+ let header = document.querySelector(".dsh-mobile-app-header");
2823
+ if (!header) {
2824
+ header = document.createElement("header");
2825
+ header.className = "dsh-mobile-app-header";
2826
+ const leftBtn = document.createElement("button");
2827
+ leftBtn.className = "dsh-header-menu-btn";
2828
+ leftBtn.title = "\u6253\u5F00\u83DC\u5355";
2829
+ leftBtn.innerHTML = `
2830
+ <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round">
2831
+ <line x1="3" y1="8" x2="21" y2="8"></line>
2832
+ <line x1="3" y1="15" x2="14" y2="15"></line>
2833
+ </svg>
2834
+ `;
2835
+ leftBtn.onclick = () => {
2836
+ const isOpen = document.body.classList.toggle("dsh-drawer-open");
2837
+ if (isOpen) {
2838
+ const collapsedToggle = document.querySelector('div[class*="hHd-Xa_collapsed"] button[class*="hHd-Xa_toggle"]');
2839
+ if (collapsedToggle) collapsedToggle.click();
2840
+ }
2841
+ };
2842
+ const rightBtn = document.createElement("button");
2843
+ rightBtn.className = "dsh-header-new-btn";
2844
+ rightBtn.title = "\u65B0\u5EFA\u4F1A\u8BDD";
2845
+ rightBtn.innerHTML = `
2846
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
2847
+ <circle cx="12" cy="12" r="9.5"></circle>
2848
+ <line x1="12" y1="8" x2="12" y2="16"></line>
2849
+ <line x1="8" y1="12" x2="16" y2="12"></line>
2850
+ </svg>
2851
+ `;
2852
+ rightBtn.onclick = () => {
2853
+ const dshNewBtn = document.querySelector('button[aria-label="\u65B0\u5EFA\u4F1A\u8BDD"]');
2854
+ if (dshNewBtn) dshNewBtn.click();
2855
+ };
2856
+ header.appendChild(leftBtn);
2857
+ header.appendChild(rightBtn);
2858
+ document.body.appendChild(header);
2859
+ }
2860
+ let backdrop = document.querySelector(".dsh-mobile-backdrop");
2861
+ if (!backdrop) {
2862
+ backdrop = document.createElement("div");
2863
+ backdrop.className = "dsh-mobile-backdrop";
2864
+ backdrop.addEventListener("click", () => {
2865
+ document.body.classList.remove("dsh-drawer-open");
2866
+ });
2867
+ document.body.appendChild(backdrop);
2868
+ }
2869
+ let lastLongPressTime = 0;
2870
+ document.addEventListener("click", (e) => {
2871
+ if (!document.body.classList.contains("dsh-drawer-open")) return;
2872
+ if (Date.now() - lastLongPressTime < 600) {
2873
+ e.stopPropagation();
2874
+ e.preventDefault();
2875
+ return;
2876
+ }
2877
+ if (e.target.closest('div[class*="portal"], div[class*="_portal"], div[role="menu"], div[role="dialog"], div[class*="popup"], div[class*="dropdown"], div[class*="overlay"]')) {
2878
+ return;
2879
+ }
2880
+ const sidebar = document.querySelector('div[class*="_sidebarCol"]');
2881
+ if (sidebar && sidebar.contains(e.target)) {
2882
+ if (e.target.closest('input, select, textarea, div[class*="searchInput"]')) {
2883
+ return;
2884
+ }
2885
+ const btn = e.target.closest('button, [role="button"]');
2886
+ if (btn) {
2887
+ const label = btn.getAttribute("aria-label") || btn.innerText || "";
2888
+ if (label.includes("\u64CD\u4F5C") || label.includes("\u89C6\u56FE") || label.includes("\u6DFB\u52A0") || label.includes("\u641C\u7D22") || label.includes("\u8BBE\u7F6E") || btn.matches('button[class*="toggle"], button[class*="trigger"], button[class*="iconButton"], button[class*="searchButton"]')) {
2889
+ return;
2890
+ }
2891
+ if (label.includes("\u65B0\u4F1A\u8BDD") || btn.matches('button[class*="newSession"]')) {
2892
+ document.body.classList.remove("dsh-drawer-open");
2893
+ return;
2894
+ }
2895
+ }
2896
+ const sessionRow = e.target.closest('div[class*="sessionRow"], div[role="treeitem"]');
2897
+ if (sessionRow) {
2898
+ document.body.classList.remove("dsh-drawer-open");
2899
+ }
2900
+ }
2901
+ }, true);
2902
+ let longPressTimer = null;
2903
+ let touchStartX = 0;
2904
+ let touchStartY = 0;
2905
+ window.addEventListener("touchstart", (e) => {
2906
+ if (e.touches && e.touches.length > 0) {
2907
+ touchStartX = e.touches[0].clientX;
2908
+ touchStartY = e.touches[0].clientY;
2909
+ }
2910
+ if (!document.body.classList.contains("dsh-drawer-open")) return;
2911
+ const sidebar = document.querySelector('div[class*="_sidebarCol"]');
2912
+ if (!sidebar || !sidebar.contains(e.target)) return;
2913
+ const sessionRow = e.target.closest('div[class*="sessionRow"], div[role="treeitem"]');
2914
+ if (!sessionRow) return;
2915
+ longPressTimer = setTimeout(() => {
2916
+ lastLongPressTime = Date.now();
2917
+ try {
2918
+ if (navigator.vibrate) navigator.vibrate(40);
2919
+ } catch (_) {
2920
+ }
2921
+ const actionBtn = sessionRow.querySelector('button[aria-label*="\u64CD\u4F5C"], button[class*="iconButton"], button');
2922
+ if (actionBtn) {
2923
+ actionBtn.click();
2924
+ }
2925
+ }, 380);
2926
+ }, { passive: true });
2927
+ window.addEventListener("touchmove", (e) => {
2928
+ if (longPressTimer && e.touches && e.touches.length > 0) {
2929
+ const moveX = Math.abs(e.touches[0].clientX - touchStartX);
2930
+ const moveY = Math.abs(e.touches[0].clientY - touchStartY);
2931
+ if (moveX > 10 || moveY > 10) {
2932
+ clearTimeout(longPressTimer);
2933
+ longPressTimer = null;
2934
+ }
2935
+ }
2936
+ }, { passive: true });
2937
+ window.addEventListener("touchend", (e) => {
2938
+ if (longPressTimer) {
2939
+ clearTimeout(longPressTimer);
2940
+ longPressTimer = null;
2941
+ }
2942
+ if (!e.changedTouches || e.changedTouches.length === 0) return;
2943
+ const deltaX = e.changedTouches[0].clientX - touchStartX;
2944
+ const deltaY = e.changedTouches[0].clientY - touchStartY;
2945
+ if (Math.abs(deltaX) > 60 && Math.abs(deltaX) > Math.abs(deltaY) * 1.5) {
2946
+ if (deltaX > 0 && touchStartX <= 35) {
2947
+ document.body.classList.add("dsh-drawer-open");
2948
+ const collapsedToggle = document.querySelector('div[class*="hHd-Xa_collapsed"] button[class*="hHd-Xa_toggle"]');
2949
+ if (collapsedToggle) collapsedToggle.click();
2950
+ } else if (deltaX < 0 && document.body.classList.contains("dsh-drawer-open")) {
2951
+ document.body.classList.remove("dsh-drawer-open");
2952
+ }
2953
+ }
2954
+ }, { passive: true });
2955
+ }
2445
2956
  function apply(ctx) {
2957
+ setupMobileExperience();
2446
2958
  const rpcCall = (endpoint, payload, signal) => ctx.connection.rpc.call(BRIDGE_RPC_CHANNEL, endpoint, payload, signal);
2447
2959
  ctx.slots.inject(
2448
2960
  "settings.section",