dsh-bridge-gateway 0.1.5 → 0.1.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 +20 -0
- package/client/client.js +266 -18
- package/client/index.js +282 -18
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
本项目 `dsh-bridge-gateway` 是基于 [dsh-bridge](https://github.com/wenbin-wb/dsh-bridge) 的移植增强分支,在保留原版能力之外,重点新增「公网直连网关」。
|
|
4
4
|
|
|
5
|
+
## [0.1.7] - 2026-09-12
|
|
6
|
+
|
|
7
|
+
### 变更(移动端第三批:标题行密度)
|
|
8
|
+
- 对话/轨迹/上下文 改为标题行内的「对话 ▾」下拉按钮(弃用胶囊方案):插在标准模式与访达图标之间,原生样式观感,点开下拉切换视图,文案动态读取、语言无关。
|
|
9
|
+
- 修复 tabs 胶囊与标题行折成两行的问题:删除级联中残留的 titleRow wrap 规则,标题行强制单行。
|
|
10
|
+
- 原生 corner 按钮(打开右侧边栏)负边距归零,单行布局下不再被裁切。
|
|
11
|
+
|
|
12
|
+
### 修复
|
|
13
|
+
- workbuddy-connect 的 Reasoning levels 按钮:移动端删除文字节点只留图标(此前裁切露字),悬停宽度锁定不再引起工具栏抖动。
|
|
14
|
+
- 修复标签文案同步无条件写入 textContent 触发 MutationObserver 死循环导致页面卡死的问题。
|
|
15
|
+
|
|
16
|
+
## [0.1.6] - 2026-09-12
|
|
17
|
+
|
|
18
|
+
### 修复(移动端第二批:布局密度与面板)
|
|
19
|
+
- 输入框贴底:收掉 scrollBody 的 16px 底部衬距,只保留 6px 呼吸位 + 安全区,底部统计药丸完整可见。
|
|
20
|
+
- workbuddy-connect 的 Reasoning levels 按钮收成纯图标(26px,结构锚点不依赖语言),不再把左侧按钮挤到上一行;工具栏恢复单行。
|
|
21
|
+
- 对话/轨迹/上下文标签行折叠为标题行下缘的悬浮胶囊(原生 tooltip 灰配色),不再独占一行,中间内容区净增约 33px。
|
|
22
|
+
- 底部面板(better-sidebar panel-host)不再被一刀切隐藏:展开时以底部面板形态显示内容(zsh 会话等),收起时隐藏;收掉展开时原生预留的 220px 空白。展开信号用语言无关的 aria-pressed 锚点(body.dsh-workbench-open 在收起后残留,不可用)。
|
|
23
|
+
- 抽屉化侧边栏顶部对齐到标签条之下(top: 38px),不再与最上面的栏重叠。
|
|
24
|
+
|
|
5
25
|
## [0.1.5] - 2026-09-12
|
|
6
26
|
|
|
7
27
|
### 变更
|
package/client/client.js
CHANGED
|
@@ -3829,24 +3829,97 @@ function injectMobileStyles() {
|
|
|
3829
3829
|
display: none !important;
|
|
3830
3830
|
}
|
|
3831
3831
|
|
|
3832
|
+
/* ---- \u5BF9\u8BDD/\u8F68\u8FF9/\u4E0A\u4E0B\u6587 \u6807\u7B7E\u6298\u53E0\u8FDB\u6807\u9898\u884C\uFF08\u540C\u4E00\u884C\uFF09 ----
|
|
3833
|
+
\u539F\u751F tablist \u6574\u884C\u9690\u85CF\uFF1B\u7531 setupMobileExperience \u6CE8\u5165\u4E00\u4E2A\u539F\u751F\u6837\u5F0F\u7684
|
|
3834
|
+
\u300C\u5BF9\u8BDD\u300D\u6309\u94AE\uFF08\u63D2\u5728\u6807\u51C6\u6A21\u5F0F\u4E0E\u8BBF\u8FBE\u56FE\u6807\u4E4B\u95F4\uFF09\uFF0C\u70B9\u51FB\u5F39\u4E0B\u62C9\u5207\u6362\u4E09\u4E2A\u89C6\u56FE\u3002
|
|
3835
|
+
\u6309\u94AE\u6587\u6848\u4E0E\u9009\u9879\u6587\u6848\u90FD\u4ECE\u539F\u751F tab \u52A8\u6001\u8BFB\u53D6\uFF0C\u8BED\u8A00\u65E0\u5173\u3002 */
|
|
3836
|
+
div[class*="wSkVaW_tabs"] {
|
|
3837
|
+
display: none !important;
|
|
3838
|
+
}
|
|
3839
|
+
.dsh-mobile-tab-btn {
|
|
3840
|
+
display: inline-flex !important;
|
|
3841
|
+
align-items: center !important;
|
|
3842
|
+
gap: 5px !important;
|
|
3843
|
+
position: relative !important;
|
|
3844
|
+
height: 28px !important;
|
|
3845
|
+
min-height: 28px !important;
|
|
3846
|
+
padding: 0 10px !important;
|
|
3847
|
+
border-radius: 999px !important;
|
|
3848
|
+
background: var(--dsw-alias-bg-layer-2, rgba(127, 127, 127, 0.12)) !important;
|
|
3849
|
+
color: var(--dsw-alias-label-primary, inherit) !important;
|
|
3850
|
+
font-size: 12.5px !important;
|
|
3851
|
+
line-height: 28px !important;
|
|
3852
|
+
white-space: nowrap !important;
|
|
3853
|
+
cursor: pointer !important;
|
|
3854
|
+
}
|
|
3855
|
+
.dsh-mobile-tab-btn svg {
|
|
3856
|
+
flex: 0 0 auto !important;
|
|
3857
|
+
}
|
|
3858
|
+
.dsh-mobile-tab-dropdown {
|
|
3859
|
+
position: absolute !important;
|
|
3860
|
+
top: calc(100% + 6px) !important;
|
|
3861
|
+
left: 0 !important;
|
|
3862
|
+
min-width: 132px !important;
|
|
3863
|
+
z-index: 60 !important;
|
|
3864
|
+
padding: 4px !important;
|
|
3865
|
+
border-radius: 12px !important;
|
|
3866
|
+
background: var(--dsw-alias-bg-layer-2, #2c2c2e) !important;
|
|
3867
|
+
border: 1px solid var(--dsw-alias-border-l2, transparent) !important;
|
|
3868
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35) !important;
|
|
3869
|
+
}
|
|
3870
|
+
.dsh-mobile-tab-dropdown .dsh-mobile-tab-option {
|
|
3871
|
+
display: flex !important;
|
|
3872
|
+
align-items: center !important;
|
|
3873
|
+
justify-content: space-between !important;
|
|
3874
|
+
gap: 8px !important;
|
|
3875
|
+
width: 100% !important;
|
|
3876
|
+
padding: 7px 10px !important;
|
|
3877
|
+
border: 0 !important;
|
|
3878
|
+
border-radius: 8px !important;
|
|
3879
|
+
background: transparent !important;
|
|
3880
|
+
color: var(--dsw-alias-label-primary, inherit) !important;
|
|
3881
|
+
font-size: 13px !important;
|
|
3882
|
+
line-height: 18px !important;
|
|
3883
|
+
cursor: pointer !important;
|
|
3884
|
+
text-align: left !important;
|
|
3885
|
+
}
|
|
3886
|
+
.dsh-mobile-tab-dropdown .dsh-mobile-tab-option:hover {
|
|
3887
|
+
background: var(--dsw-alias-interactive-bg-hover, rgba(127, 127, 127, 0.15)) !important;
|
|
3888
|
+
}
|
|
3889
|
+
.dsh-mobile-tab-dropdown .dsh-mobile-tab-option[data-active='true'] {
|
|
3890
|
+
color: var(--dsw-alias-brand-text, var(--dsw-alias-label-primary, inherit)) !important;
|
|
3891
|
+
font-weight: 600 !important;
|
|
3892
|
+
}
|
|
3893
|
+
|
|
3832
3894
|
/* ---- \u9876\u680F\u300C\u6807\u51C6\u6A21\u5F0F\u300D\u4E0E\u300C\u5BF9\u8BDD\u7BA1\u7406\u300D\u91CD\u53E0\u4FEE\u590D ----
|
|
3833
3895
|
\u5B9E\u6D4B\uFF08390px\uFF09\uFF1A\u6807\u51C6\u6A21\u5F0F(\u5728 titleCluster \u5185) \u53F3\u8FB9\u754C 102\uFF0C
|
|
3834
3896
|
\u5BF9\u8BDD\u7BA1\u7406(\u5728 headerUtilities \u5185) \u5DE6\u8FB9\u754C 91 \u2192 \u6C34\u5E73\u91CD\u53E0 11px\u3002
|
|
3835
|
-
\
|
|
3836
|
-
\
|
|
3837
|
-
\u4FEE\u590D\uFF1A\u5141\u8BB8 titleRow \u6362\u884C + \u8BA9\u4E24\u4FA7\u5404\u81EA\u53EF\u6536\u7F29\u5E76\u9650\u5BBD\u3002 */
|
|
3897
|
+
\u4FEE\u590D\uFF1AtitleRow \u5F3A\u5236\u5355\u884C\uFF08tabs \u5DF2\u5E76\u5165\u540C\u4E00\u884C\uFF09\uFF0C\u8D85\u5BBD\u65F6 titleCluster
|
|
3898
|
+
\u5185\u90E8\u622A\u65AD\u800C\u4E0D\u662F\u6362\u884C\u2014\u2014\u6362\u884C\u4F1A\u8BA9 header \u53D8\u4E24\u884C\u3001\u6324\u538B\u4E2D\u95F4\u7A7A\u95F4\u3002 */
|
|
3838
3899
|
div[class*="wSkVaW_titleRow"],
|
|
3839
3900
|
div[class*="_titleRow"] {
|
|
3840
|
-
|
|
3841
|
-
|
|
3901
|
+
display: flex !important;
|
|
3902
|
+
flex-direction: row !important;
|
|
3903
|
+
flex-wrap: nowrap !important;
|
|
3904
|
+
align-items: center !important;
|
|
3905
|
+
flex: 1 1 auto !important;
|
|
3906
|
+
min-width: 0 !important;
|
|
3842
3907
|
column-gap: 8px !important;
|
|
3843
|
-
overflow:
|
|
3908
|
+
overflow: hidden !important;
|
|
3844
3909
|
}
|
|
3845
3910
|
div[class*="wSkVaW_titleCluster"],
|
|
3846
3911
|
div[class*="_titleCluster"] {
|
|
3847
|
-
flex:
|
|
3912
|
+
flex: 0 1 auto !important;
|
|
3848
3913
|
min-width: 0 !important;
|
|
3849
3914
|
max-width: 100% !important;
|
|
3915
|
+
overflow: hidden !important;
|
|
3916
|
+
}
|
|
3917
|
+
/* \u539F\u751F corner \u6309\u94AE\u5E26 margin-right:-16px \u60AC\u6302\u8BBE\u8BA1\uFF0C\u5728\u5355\u884C + overflow:hidden \u4E0B
|
|
3918
|
+
\u4F1A\u88AB\u88C1\u6389 16px\u2014\u2014\u5F52\u96F6\u540E\u6574\u884C\u521A\u597D\u653E\u4E0B\uFF1Acluster69 + utilities123 + corner28 */
|
|
3919
|
+
div[class*="wSkVaW_headerCorner"] {
|
|
3920
|
+
margin-right: 0 !important;
|
|
3921
|
+
margin-left: 0 !important;
|
|
3922
|
+
flex: 0 0 auto !important;
|
|
3850
3923
|
}
|
|
3851
3924
|
div[class*="wSkVaW_headerActions"],
|
|
3852
3925
|
div[class*="_headerActions"] {
|
|
@@ -4017,13 +4090,9 @@ function injectMobileStyles() {
|
|
|
4017
4090
|
box-sizing: border-box !important;
|
|
4018
4091
|
}
|
|
4019
4092
|
|
|
4020
|
-
/* ---- \u9876\u90E8\u63A7\u4EF6\u9632\u6EA2\u51FA\u88C1\u5207\uFF08320px \u4E0B main \u5206\u652F chip \u6EA2\u51FA 39px \u88AB\u88C1\uFF09 ----
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
flex-wrap: wrap !important;
|
|
4024
|
-
row-gap: 6px !important;
|
|
4025
|
-
overflow: visible !important;
|
|
4026
|
-
}
|
|
4093
|
+
/* ---- \u9876\u90E8\u63A7\u4EF6\u9632\u6EA2\u51FA\u88C1\u5207\uFF08320px \u4E0B main \u5206\u652F chip \u6EA2\u51FA 39px \u88AB\u88C1\uFF09 ----
|
|
4094
|
+
\u6CE8\u610F\uFF1AtitleRow \u7684 wrap \u89C4\u5219\u5DF2\u5220\u9664\u2014\u2014tabs \u6298\u53E0\u8FDB\u6807\u9898\u884C\u540E\u5FC5\u987B\u5355\u884C\uFF0C
|
|
4095
|
+
\u8FD9\u91CC\u7684 wrap \u4F1A\u5728\u7EA7\u8054\u4E2D\u8D62\u8FC7\u524D\u9762\u7684 nowrap\uFF0C\u5BFC\u81F4\u6807\u9898\u884C\u91CD\u65B0\u6298\u6210\u4E24\u884C\u3002 */
|
|
4027
4096
|
button[class*="_7rgC5q_chip"],
|
|
4028
4097
|
button[class*="cubgiG_seat"],
|
|
4029
4098
|
div[class*="_7rgC5q_chipWrap"] {
|
|
@@ -4101,11 +4170,34 @@ function injectMobileStyles() {
|
|
|
4101
4170
|
\u5E38\u9A7B\u5C4F\u5E55\u53F3\u4E0B\u89D2\uFF0C\u89C6\u89C9\u4E0A\u5C31\u662F\u90A3\u4E2A"\u5C0F\u65B9\u5757"\u3002
|
|
4102
4171
|
\u4FEE\u590D\uFF1A\u79FB\u52A8\u7AEF\u9690\u85CF panel-host \u906E\u7F69\u4E0E glass \u6E10\u53D8\u88C5\u9970\u6761\uFF0C\u5E76\u9501\u5B9A\u8F93\u5165\u6846 sticky \u4E8E\u5E95\u90E8\u3002 */
|
|
4103
4172
|
|
|
4104
|
-
/*
|
|
4173
|
+
/* better-sidebar \u9762\u677F\u5BBF\u4E3B\uFF1A\u9ED8\u8BA4\u9690\u85CF\uFF08\u65E7\u7684\u5168\u5C4F fixed \u906E\u7F69\u4F1A\u76D6\u4F4F\u8F93\u5165\u6846\u5E76\u62E6\u622A\u70B9\u51FB\uFF09\uFF1B
|
|
4174
|
+
\u5E95\u90E8\u9762\u677F\u5C55\u5F00\u65F6\uFF08\u5F00\u5173 aria-pressed=true / body.dsh-workbench-open\uFF09\u6539\u4E3A
|
|
4175
|
+
\u5E95\u90E8\u9762\u677F\u5F62\u6001\u663E\u793A\u2014\u2014\u4E0D\u906E\u8F93\u5165\u6846\u3001\u4E0D\u9876\u72B6\u6001\u680F\uFF0C\u5185\u5BB9\uFF08zsh \u4F1A\u8BDD\u7B49\uFF09\u53EF\u89C1\u3002
|
|
4176
|
+
aria-pressed \u4E0E data-active \u90FD\u662F\u8BED\u8A00\u65E0\u5173\u951A\u70B9\uFF0C\u4E2D\u82F1\u6587\u73AF\u5883\u901A\u7528\u3002 */
|
|
4105
4177
|
div[data-dsh-panel-host],
|
|
4106
4178
|
div[data-dsh-better-sidebar] {
|
|
4107
4179
|
display: none !important;
|
|
4108
4180
|
}
|
|
4181
|
+
body:has(button[data-dsh-bottom-toggle][aria-pressed='true']) div[data-dsh-panel-host],
|
|
4182
|
+
body:has(button[data-dsh-bottom-toggle][aria-pressed='true']) div[data-dsh-better-sidebar] {
|
|
4183
|
+
display: block !important;
|
|
4184
|
+
top: 42px !important;
|
|
4185
|
+
bottom: calc(var(--dsh-composer-height, 171px) + 34px) !important;
|
|
4186
|
+
left: 8px !important;
|
|
4187
|
+
right: 8px !important;
|
|
4188
|
+
width: auto !important;
|
|
4189
|
+
height: auto !important;
|
|
4190
|
+
z-index: 20 !important;
|
|
4191
|
+
border-radius: 12px !important;
|
|
4192
|
+
overflow: auto !important;
|
|
4193
|
+
background: var(--dsw-alias-bg-layer-2, #2c2c2e) !important;
|
|
4194
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35) !important;
|
|
4195
|
+
}
|
|
4196
|
+
/* \u5E95\u90E8\u9762\u677F\u5C55\u5F00\u65F6\u539F\u751F\u7ED9\u4E2D\u680F\u9884\u7559\u7684 220px \u5E95\u90E8\u7A7A\u767D\u6536\u6389\uFF0C\u8F93\u5165\u6846\u56DE\u5230\u5C4F\u5E55\u5E95\u3002
|
|
4197
|
+
\u6CE8\u610F body.dsh-workbench-open \u5728\u6536\u8D77\u540E\u4ECD\u6B8B\u7559\uFF0C\u4E0D\u80FD\u5F53\u5C55\u5F00\u4FE1\u53F7\u3002 */
|
|
4198
|
+
body:has(button[data-dsh-bottom-toggle][aria-pressed='true']) div[class*="pI_x6G_centerCol"] {
|
|
4199
|
+
margin-bottom: 0 !important;
|
|
4200
|
+
}
|
|
4109
4201
|
/* \u9690\u85CF\u4E3B\u9898\u88C5\u9970\u6027\u6E10\u53D8\u6761\uFF08\u53F3\u4E0B\u89D2\u5C0F\u65B9\u5757\uFF09 */
|
|
4110
4202
|
span[data-dsh-glass-fade] {
|
|
4111
4203
|
display: none !important;
|
|
@@ -4122,12 +4214,48 @@ function injectMobileStyles() {
|
|
|
4122
4214
|
display: flex !important;
|
|
4123
4215
|
align-items: center !important;
|
|
4124
4216
|
justify-content: space-between !important;
|
|
4217
|
+
flex-wrap: nowrap !important;
|
|
4125
4218
|
gap: 6px !important;
|
|
4126
4219
|
width: 100% !important;
|
|
4127
4220
|
padding: 2px 2px 4px !important;
|
|
4128
4221
|
box-sizing: border-box !important;
|
|
4129
4222
|
}
|
|
4130
4223
|
|
|
4224
|
+
/* \u8F93\u5165\u6846\u8D34\u5E95\uFF1AscrollBody \u7684 16px \u5E95\u90E8\u886C\u8DDD\u662F\u7A7A\u9699\u6765\u6E90\uFF0C\u6536\u6389\u53EA\u7559\u5B89\u5168\u533A\uFF1B
|
|
4225
|
+
\u518D\u57AB 6px \u8BA9\u7EDF\u8BA1\u836F\u4E38\u5B8C\u6574\u53EF\u89C1 */
|
|
4226
|
+
div[class*="wSkVaW_scrollBody"] {
|
|
4227
|
+
padding-bottom: calc(6px + env(safe-area-inset-bottom, 0px)) !important;
|
|
4228
|
+
}
|
|
4229
|
+
div[class*="wSkVaW_composerStack"] {
|
|
4230
|
+
padding-bottom: env(safe-area-inset-bottom, 0px) !important;
|
|
4231
|
+
}
|
|
4232
|
+
|
|
4233
|
+
/* workbuddy-connect \u7684 Reasoning levels \u6309\u94AE\uFF08uV2eYG_trailing \u91CC\u552F\u4E00\u7684\u65E0 class
|
|
4234
|
+
\u6309\u94AE\uFF0C\u7ED3\u6784\u951A\u70B9 span>button\uFF09\uFF1A\u79FB\u52A8\u7AEF\u6536\u6210\u7EAF\u56FE\u6807\uFF0C\u6587\u5B57\u88AB\u88C1\u6389\uFF0C
|
|
4235
|
+
\u4E0D\u518D\u628A\u5DE6\u4FA7\u6309\u94AE\u6324\u5230\u4E0A\u4E00\u884C */
|
|
4236
|
+
div[class*="uV2eYG_trailing"] span > button:not([class]) {
|
|
4237
|
+
flex: 0 0 26px !important;
|
|
4238
|
+
width: 26px !important;
|
|
4239
|
+
min-width: 26px !important;
|
|
4240
|
+
padding: 0 2px !important;
|
|
4241
|
+
overflow: hidden !important;
|
|
4242
|
+
justify-content: center !important;
|
|
4243
|
+
gap: 0 !important;
|
|
4244
|
+
font-size: 0 !important;
|
|
4245
|
+
/* \u60AC\u505C\u9501\u5B9A\uFF1A\u5BBD\u5EA6\u4E0E\u4F4D\u79FB\u90FD\u4E0D\u53D8\uFF0C\u675C\u7EDD\u5DE5\u5177\u680F/\u5BF9\u8BDD\u6846\u6296\u52A8 */
|
|
4246
|
+
transition: none !important;
|
|
4247
|
+
border-radius: 8px !important;
|
|
4248
|
+
}
|
|
4249
|
+
div[class*="uV2eYG_trailing"] span > button:not([class]):hover {
|
|
4250
|
+
width: 26px !important;
|
|
4251
|
+
min-width: 26px !important;
|
|
4252
|
+
padding: 0 2px !important;
|
|
4253
|
+
background: var(--dsw-alias-interactive-bg-hover, rgba(127, 127, 127, 0.15)) !important;
|
|
4254
|
+
}
|
|
4255
|
+
div[class*="uV2eYG_trailing"] span > button:not([class]) svg {
|
|
4256
|
+
flex: 0 0 auto !important;
|
|
4257
|
+
}
|
|
4258
|
+
|
|
4131
4259
|
div[class*="uV2eYG_tools"] {
|
|
4132
4260
|
display: flex !important;
|
|
4133
4261
|
align-items: center !important;
|
|
@@ -4210,7 +4338,8 @@ function injectMobileStyles() {
|
|
|
4210
4338
|
div[class*="_sidebarCol"] {
|
|
4211
4339
|
position: fixed !important;
|
|
4212
4340
|
left: 0 !important;
|
|
4213
|
-
|
|
4341
|
+
/* \u9876\u5230\u9876\u90E8\u6807\u7B7E\u6761(38px)\u4E4B\u4E0B\uFF0C\u4E0D\u518D\u4E0E\u6700\u4E0A\u9762\u7684\u680F\u91CD\u53E0 */
|
|
4342
|
+
top: 38px !important;
|
|
4214
4343
|
bottom: auto !important;
|
|
4215
4344
|
/* \u4FA7\u8FB9\u680F\u5E95\u90E8\u6EA2\u51FA\u5C4F\u5E55\u4FEE\u590D\uFF1A
|
|
4216
4345
|
\u5B9E\u6D4B 390x844 \u4E0B\uFF0C\u4FA7\u8FB9\u680F\u5B9E\u9645\u76D2\u5B50\u4E3A T=12 B=882\uFF08\u9AD8\u5EA6 870 > \u89C6\u53E3 844\uFF09\uFF0C\u5E95\u90E8\u6EA2\u51FA 38px\u3002
|
|
@@ -4218,8 +4347,8 @@ function injectMobileStyles() {
|
|
|
4218
4347
|
\u4E8E\u662F padding(10px+14px) \u4E0E margin(12px) \u88AB\u52A0\u5728 height:100dvh \u4E4B\u5916\u3002
|
|
4219
4348
|
\u6539\u4E3A border-box \u5E76\u7528 100dvh \u76F4\u63A5\u7EA6\u675F\u9AD8\u5EA6\uFF0Cpadding \u5373\u88AB\u5305\u542B\u5728\u9AD8\u5EA6\u5185\u3002 */
|
|
4220
4349
|
box-sizing: border-box !important;
|
|
4221
|
-
height: 100dvh !important;
|
|
4222
|
-
max-height: 100dvh !important;
|
|
4350
|
+
height: calc(100dvh - 38px) !important;
|
|
4351
|
+
max-height: calc(100dvh - 38px) !important;
|
|
4223
4352
|
margin: 0 !important;
|
|
4224
4353
|
width: 290px !important;
|
|
4225
4354
|
max-width: 82vw !important;
|
|
@@ -4686,6 +4815,125 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
4686
4815
|
const panelObserver = new MutationObserver(ensurePanelCloseButton);
|
|
4687
4816
|
panelObserver.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ["class"] });
|
|
4688
4817
|
window.addEventListener("resize", ensurePanelCloseButton);
|
|
4818
|
+
const mobileTabState = { btn: null, dropdown: null };
|
|
4819
|
+
const nativeTabs = () => [...document.querySelectorAll('[role="tablist"] [role="tab"]')];
|
|
4820
|
+
const closeTabDropdown = () => {
|
|
4821
|
+
if (mobileTabState.dropdown) {
|
|
4822
|
+
mobileTabState.dropdown.remove();
|
|
4823
|
+
mobileTabState.dropdown = null;
|
|
4824
|
+
}
|
|
4825
|
+
};
|
|
4826
|
+
const renderTabDropdown = () => {
|
|
4827
|
+
closeTabDropdown();
|
|
4828
|
+
if (!mobileTabState.btn) return;
|
|
4829
|
+
const dropdown = document.createElement("div");
|
|
4830
|
+
dropdown.className = "dsh-mobile-tab-dropdown";
|
|
4831
|
+
const tabs = nativeTabs();
|
|
4832
|
+
tabs.forEach((tabEl) => {
|
|
4833
|
+
const isActive = tabEl.getAttribute("aria-selected") === "true";
|
|
4834
|
+
const option = document.createElement("button");
|
|
4835
|
+
option.type = "button";
|
|
4836
|
+
option.className = "dsh-mobile-tab-option";
|
|
4837
|
+
option.setAttribute("data-active", isActive ? "true" : "false");
|
|
4838
|
+
const name2 = document.createElement("span");
|
|
4839
|
+
name2.textContent = tabEl.textContent.replace(/\s+/g, " ").trim();
|
|
4840
|
+
option.appendChild(name2);
|
|
4841
|
+
if (isActive) {
|
|
4842
|
+
const check = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
4843
|
+
check.setAttribute("width", "14");
|
|
4844
|
+
check.setAttribute("height", "14");
|
|
4845
|
+
check.setAttribute("viewBox", "0 0 24 24");
|
|
4846
|
+
check.setAttribute("fill", "none");
|
|
4847
|
+
check.setAttribute("stroke", "currentColor");
|
|
4848
|
+
check.setAttribute("stroke-width", "2.5");
|
|
4849
|
+
check.setAttribute("stroke-linecap", "round");
|
|
4850
|
+
check.setAttribute("stroke-linejoin", "round");
|
|
4851
|
+
check.innerHTML = '<polyline points="20 6 9 17 4 12"></polyline>';
|
|
4852
|
+
option.appendChild(check);
|
|
4853
|
+
}
|
|
4854
|
+
option.onclick = (e) => {
|
|
4855
|
+
e.stopPropagation();
|
|
4856
|
+
tabEl.click();
|
|
4857
|
+
closeTabDropdown();
|
|
4858
|
+
syncTabButtonLabel();
|
|
4859
|
+
};
|
|
4860
|
+
dropdown.appendChild(option);
|
|
4861
|
+
});
|
|
4862
|
+
mobileTabState.btn.appendChild(dropdown);
|
|
4863
|
+
mobileTabState.dropdown = dropdown;
|
|
4864
|
+
};
|
|
4865
|
+
const syncTabButtonLabel = () => {
|
|
4866
|
+
if (!mobileTabState.btn || !mobileTabState.btn.isConnected) return;
|
|
4867
|
+
const active = nativeTabs().find((t) => t.getAttribute("aria-selected") === "true");
|
|
4868
|
+
const labelEl = mobileTabState.btn.querySelector(".dsh-mobile-tab-btn-label");
|
|
4869
|
+
if (!labelEl || !active) return;
|
|
4870
|
+
const name2 = active.textContent.replace(/\s+/g, " ").trim();
|
|
4871
|
+
if (labelEl.textContent !== name2) labelEl.textContent = name2;
|
|
4872
|
+
};
|
|
4873
|
+
const ensureTabButton = () => {
|
|
4874
|
+
if (typeof window === "undefined" || window.innerWidth > 768) return;
|
|
4875
|
+
const titleRow = document.querySelector('div[class*="wSkVaW_titleRow"]');
|
|
4876
|
+
const cluster = titleRow ? titleRow.querySelector('div[class*="wSkVaW_titleCluster"]') : null;
|
|
4877
|
+
if (!titleRow || !cluster) {
|
|
4878
|
+
closeTabDropdown();
|
|
4879
|
+
if (mobileTabState.btn) {
|
|
4880
|
+
mobileTabState.btn.remove();
|
|
4881
|
+
mobileTabState.btn = null;
|
|
4882
|
+
}
|
|
4883
|
+
return;
|
|
4884
|
+
}
|
|
4885
|
+
if (mobileTabState.btn && mobileTabState.btn.isConnected && titleRow.contains(mobileTabState.btn)) {
|
|
4886
|
+
syncTabButtonLabel();
|
|
4887
|
+
return;
|
|
4888
|
+
}
|
|
4889
|
+
document.querySelectorAll(".dsh-mobile-tab-btn").forEach((el) => el.remove());
|
|
4890
|
+
const tabBtn = document.createElement("button");
|
|
4891
|
+
tabBtn.type = "button";
|
|
4892
|
+
const pillBtn = titleRow.querySelector('div[class*="wSkVaW_titleCluster"] button');
|
|
4893
|
+
const utilBtn = titleRow.querySelector('div[class*="wSkVaW_headerUtilities"] button');
|
|
4894
|
+
const mimic = pillBtn && pillBtn.className || utilBtn && utilBtn.className || "";
|
|
4895
|
+
tabBtn.className = (mimic ? mimic + " " : "") + "dsh-mobile-tab-btn";
|
|
4896
|
+
tabBtn.innerHTML = `<span class="dsh-mobile-tab-btn-label">\u5BF9\u8BDD</span><svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>`;
|
|
4897
|
+
tabBtn.onclick = (e) => {
|
|
4898
|
+
e.stopPropagation();
|
|
4899
|
+
if (mobileTabState.dropdown) closeTabDropdown();
|
|
4900
|
+
else renderTabDropdown();
|
|
4901
|
+
};
|
|
4902
|
+
titleRow.insertBefore(tabBtn, cluster.nextSibling);
|
|
4903
|
+
mobileTabState.btn = tabBtn;
|
|
4904
|
+
syncTabButtonLabel();
|
|
4905
|
+
};
|
|
4906
|
+
const cleanReasoningButtons = () => {
|
|
4907
|
+
if (typeof window === "undefined" || window.innerWidth > 768) return;
|
|
4908
|
+
document.querySelectorAll('div[class*="uV2eYG_trailing"] span > button:not([class])').forEach((btn) => {
|
|
4909
|
+
if (btn.dataset.dshTextCleaned === "1") return;
|
|
4910
|
+
[...btn.childNodes].forEach((node) => {
|
|
4911
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
4912
|
+
if (node.tagName.toLowerCase() === "svg" || typeof node.querySelector === "function" && node.querySelector("svg")) return;
|
|
4913
|
+
}
|
|
4914
|
+
node.remove();
|
|
4915
|
+
});
|
|
4916
|
+
btn.dataset.dshTextCleaned = "1";
|
|
4917
|
+
});
|
|
4918
|
+
};
|
|
4919
|
+
const titleExtrasObserver = new MutationObserver(() => {
|
|
4920
|
+
ensureTabButton();
|
|
4921
|
+
cleanReasoningButtons();
|
|
4922
|
+
});
|
|
4923
|
+
titleExtrasObserver.observe(document.body, { childList: true, subtree: true });
|
|
4924
|
+
window.addEventListener("resize", () => {
|
|
4925
|
+
if (window.innerWidth > 768) closeTabDropdown();
|
|
4926
|
+
});
|
|
4927
|
+
document.addEventListener(
|
|
4928
|
+
"click",
|
|
4929
|
+
(e) => {
|
|
4930
|
+
if (!mobileTabState.dropdown) return;
|
|
4931
|
+
if (!mobileTabState.dropdown.contains(e.target) && !e.target.closest(".dsh-mobile-tab-btn")) closeTabDropdown();
|
|
4932
|
+
},
|
|
4933
|
+
true
|
|
4934
|
+
);
|
|
4935
|
+
ensureTabButton();
|
|
4936
|
+
cleanReasoningButtons();
|
|
4689
4937
|
document.addEventListener("click", (e) => {
|
|
4690
4938
|
if (typeof window === "undefined" || window.innerWidth > 768) return;
|
|
4691
4939
|
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');
|
package/client/index.js
CHANGED
|
@@ -3426,24 +3426,97 @@ function injectMobileStyles() {
|
|
|
3426
3426
|
display: none !important;
|
|
3427
3427
|
}
|
|
3428
3428
|
|
|
3429
|
+
/* ---- 对话/轨迹/上下文 标签折叠进标题行(同一行) ----
|
|
3430
|
+
原生 tablist 整行隐藏;由 setupMobileExperience 注入一个原生样式的
|
|
3431
|
+
「对话」按钮(插在标准模式与访达图标之间),点击弹下拉切换三个视图。
|
|
3432
|
+
按钮文案与选项文案都从原生 tab 动态读取,语言无关。 */
|
|
3433
|
+
div[class*="wSkVaW_tabs"] {
|
|
3434
|
+
display: none !important;
|
|
3435
|
+
}
|
|
3436
|
+
.dsh-mobile-tab-btn {
|
|
3437
|
+
display: inline-flex !important;
|
|
3438
|
+
align-items: center !important;
|
|
3439
|
+
gap: 5px !important;
|
|
3440
|
+
position: relative !important;
|
|
3441
|
+
height: 28px !important;
|
|
3442
|
+
min-height: 28px !important;
|
|
3443
|
+
padding: 0 10px !important;
|
|
3444
|
+
border-radius: 999px !important;
|
|
3445
|
+
background: var(--dsw-alias-bg-layer-2, rgba(127, 127, 127, 0.12)) !important;
|
|
3446
|
+
color: var(--dsw-alias-label-primary, inherit) !important;
|
|
3447
|
+
font-size: 12.5px !important;
|
|
3448
|
+
line-height: 28px !important;
|
|
3449
|
+
white-space: nowrap !important;
|
|
3450
|
+
cursor: pointer !important;
|
|
3451
|
+
}
|
|
3452
|
+
.dsh-mobile-tab-btn svg {
|
|
3453
|
+
flex: 0 0 auto !important;
|
|
3454
|
+
}
|
|
3455
|
+
.dsh-mobile-tab-dropdown {
|
|
3456
|
+
position: absolute !important;
|
|
3457
|
+
top: calc(100% + 6px) !important;
|
|
3458
|
+
left: 0 !important;
|
|
3459
|
+
min-width: 132px !important;
|
|
3460
|
+
z-index: 60 !important;
|
|
3461
|
+
padding: 4px !important;
|
|
3462
|
+
border-radius: 12px !important;
|
|
3463
|
+
background: var(--dsw-alias-bg-layer-2, #2c2c2e) !important;
|
|
3464
|
+
border: 1px solid var(--dsw-alias-border-l2, transparent) !important;
|
|
3465
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35) !important;
|
|
3466
|
+
}
|
|
3467
|
+
.dsh-mobile-tab-dropdown .dsh-mobile-tab-option {
|
|
3468
|
+
display: flex !important;
|
|
3469
|
+
align-items: center !important;
|
|
3470
|
+
justify-content: space-between !important;
|
|
3471
|
+
gap: 8px !important;
|
|
3472
|
+
width: 100% !important;
|
|
3473
|
+
padding: 7px 10px !important;
|
|
3474
|
+
border: 0 !important;
|
|
3475
|
+
border-radius: 8px !important;
|
|
3476
|
+
background: transparent !important;
|
|
3477
|
+
color: var(--dsw-alias-label-primary, inherit) !important;
|
|
3478
|
+
font-size: 13px !important;
|
|
3479
|
+
line-height: 18px !important;
|
|
3480
|
+
cursor: pointer !important;
|
|
3481
|
+
text-align: left !important;
|
|
3482
|
+
}
|
|
3483
|
+
.dsh-mobile-tab-dropdown .dsh-mobile-tab-option:hover {
|
|
3484
|
+
background: var(--dsw-alias-interactive-bg-hover, rgba(127, 127, 127, 0.15)) !important;
|
|
3485
|
+
}
|
|
3486
|
+
.dsh-mobile-tab-dropdown .dsh-mobile-tab-option[data-active='true'] {
|
|
3487
|
+
color: var(--dsw-alias-brand-text, var(--dsw-alias-label-primary, inherit)) !important;
|
|
3488
|
+
font-weight: 600 !important;
|
|
3489
|
+
}
|
|
3490
|
+
|
|
3429
3491
|
/* ---- 顶栏「标准模式」与「对话管理」重叠修复 ----
|
|
3430
3492
|
实测(390px):标准模式(在 titleCluster 内) 右边界 102,
|
|
3431
3493
|
对话管理(在 headerUtilities 内) 左边界 91 → 水平重叠 11px。
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
修复:允许 titleRow 换行 + 让两侧各自可收缩并限宽。 */
|
|
3494
|
+
修复:titleRow 强制单行(tabs 已并入同一行),超宽时 titleCluster
|
|
3495
|
+
内部截断而不是换行——换行会让 header 变两行、挤压中间空间。 */
|
|
3435
3496
|
div[class*="wSkVaW_titleRow"],
|
|
3436
3497
|
div[class*="_titleRow"] {
|
|
3437
|
-
|
|
3438
|
-
|
|
3498
|
+
display: flex !important;
|
|
3499
|
+
flex-direction: row !important;
|
|
3500
|
+
flex-wrap: nowrap !important;
|
|
3501
|
+
align-items: center !important;
|
|
3502
|
+
flex: 1 1 auto !important;
|
|
3503
|
+
min-width: 0 !important;
|
|
3439
3504
|
column-gap: 8px !important;
|
|
3440
|
-
overflow:
|
|
3505
|
+
overflow: hidden !important;
|
|
3441
3506
|
}
|
|
3442
3507
|
div[class*="wSkVaW_titleCluster"],
|
|
3443
3508
|
div[class*="_titleCluster"] {
|
|
3444
|
-
flex:
|
|
3509
|
+
flex: 0 1 auto !important;
|
|
3445
3510
|
min-width: 0 !important;
|
|
3446
3511
|
max-width: 100% !important;
|
|
3512
|
+
overflow: hidden !important;
|
|
3513
|
+
}
|
|
3514
|
+
/* 原生 corner 按钮带 margin-right:-16px 悬挂设计,在单行 + overflow:hidden 下
|
|
3515
|
+
会被裁掉 16px——归零后整行刚好放下:cluster69 + utilities123 + corner28 */
|
|
3516
|
+
div[class*="wSkVaW_headerCorner"] {
|
|
3517
|
+
margin-right: 0 !important;
|
|
3518
|
+
margin-left: 0 !important;
|
|
3519
|
+
flex: 0 0 auto !important;
|
|
3447
3520
|
}
|
|
3448
3521
|
div[class*="wSkVaW_headerActions"],
|
|
3449
3522
|
div[class*="_headerActions"] {
|
|
@@ -3614,13 +3687,9 @@ function injectMobileStyles() {
|
|
|
3614
3687
|
box-sizing: border-box !important;
|
|
3615
3688
|
}
|
|
3616
3689
|
|
|
3617
|
-
/* ---- 顶部控件防溢出裁切(320px 下 main 分支 chip 溢出 39px 被裁) ----
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
flex-wrap: wrap !important;
|
|
3621
|
-
row-gap: 6px !important;
|
|
3622
|
-
overflow: visible !important;
|
|
3623
|
-
}
|
|
3690
|
+
/* ---- 顶部控件防溢出裁切(320px 下 main 分支 chip 溢出 39px 被裁) ----
|
|
3691
|
+
注意:titleRow 的 wrap 规则已删除——tabs 折叠进标题行后必须单行,
|
|
3692
|
+
这里的 wrap 会在级联中赢过前面的 nowrap,导致标题行重新折成两行。 */
|
|
3624
3693
|
button[class*="_7rgC5q_chip"],
|
|
3625
3694
|
button[class*="cubgiG_seat"],
|
|
3626
3695
|
div[class*="_7rgC5q_chipWrap"] {
|
|
@@ -3698,11 +3767,34 @@ function injectMobileStyles() {
|
|
|
3698
3767
|
常驻屏幕右下角,视觉上就是那个"小方块"。
|
|
3699
3768
|
修复:移动端隐藏 panel-host 遮罩与 glass 渐变装饰条,并锁定输入框 sticky 于底部。 */
|
|
3700
3769
|
|
|
3701
|
-
/*
|
|
3770
|
+
/* better-sidebar 面板宿主:默认隐藏(旧的全屏 fixed 遮罩会盖住输入框并拦截点击);
|
|
3771
|
+
底部面板展开时(开关 aria-pressed=true / body.dsh-workbench-open)改为
|
|
3772
|
+
底部面板形态显示——不遮输入框、不顶状态栏,内容(zsh 会话等)可见。
|
|
3773
|
+
aria-pressed 与 data-active 都是语言无关锚点,中英文环境通用。 */
|
|
3702
3774
|
div[data-dsh-panel-host],
|
|
3703
3775
|
div[data-dsh-better-sidebar] {
|
|
3704
3776
|
display: none !important;
|
|
3705
3777
|
}
|
|
3778
|
+
body:has(button[data-dsh-bottom-toggle][aria-pressed='true']) div[data-dsh-panel-host],
|
|
3779
|
+
body:has(button[data-dsh-bottom-toggle][aria-pressed='true']) div[data-dsh-better-sidebar] {
|
|
3780
|
+
display: block !important;
|
|
3781
|
+
top: 42px !important;
|
|
3782
|
+
bottom: calc(var(--dsh-composer-height, 171px) + 34px) !important;
|
|
3783
|
+
left: 8px !important;
|
|
3784
|
+
right: 8px !important;
|
|
3785
|
+
width: auto !important;
|
|
3786
|
+
height: auto !important;
|
|
3787
|
+
z-index: 20 !important;
|
|
3788
|
+
border-radius: 12px !important;
|
|
3789
|
+
overflow: auto !important;
|
|
3790
|
+
background: var(--dsw-alias-bg-layer-2, #2c2c2e) !important;
|
|
3791
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35) !important;
|
|
3792
|
+
}
|
|
3793
|
+
/* 底部面板展开时原生给中栏预留的 220px 底部空白收掉,输入框回到屏幕底。
|
|
3794
|
+
注意 body.dsh-workbench-open 在收起后仍残留,不能当展开信号。 */
|
|
3795
|
+
body:has(button[data-dsh-bottom-toggle][aria-pressed='true']) div[class*="pI_x6G_centerCol"] {
|
|
3796
|
+
margin-bottom: 0 !important;
|
|
3797
|
+
}
|
|
3706
3798
|
/* 隐藏主题装饰性渐变条(右下角小方块) */
|
|
3707
3799
|
span[data-dsh-glass-fade] {
|
|
3708
3800
|
display: none !important;
|
|
@@ -3719,12 +3811,48 @@ function injectMobileStyles() {
|
|
|
3719
3811
|
display: flex !important;
|
|
3720
3812
|
align-items: center !important;
|
|
3721
3813
|
justify-content: space-between !important;
|
|
3814
|
+
flex-wrap: nowrap !important;
|
|
3722
3815
|
gap: 6px !important;
|
|
3723
3816
|
width: 100% !important;
|
|
3724
3817
|
padding: 2px 2px 4px !important;
|
|
3725
3818
|
box-sizing: border-box !important;
|
|
3726
3819
|
}
|
|
3727
3820
|
|
|
3821
|
+
/* 输入框贴底:scrollBody 的 16px 底部衬距是空隙来源,收掉只留安全区;
|
|
3822
|
+
再垫 6px 让统计药丸完整可见 */
|
|
3823
|
+
div[class*="wSkVaW_scrollBody"] {
|
|
3824
|
+
padding-bottom: calc(6px + env(safe-area-inset-bottom, 0px)) !important;
|
|
3825
|
+
}
|
|
3826
|
+
div[class*="wSkVaW_composerStack"] {
|
|
3827
|
+
padding-bottom: env(safe-area-inset-bottom, 0px) !important;
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
/* workbuddy-connect 的 Reasoning levels 按钮(uV2eYG_trailing 里唯一的无 class
|
|
3831
|
+
按钮,结构锚点 span>button):移动端收成纯图标,文字被裁掉,
|
|
3832
|
+
不再把左侧按钮挤到上一行 */
|
|
3833
|
+
div[class*="uV2eYG_trailing"] span > button:not([class]) {
|
|
3834
|
+
flex: 0 0 26px !important;
|
|
3835
|
+
width: 26px !important;
|
|
3836
|
+
min-width: 26px !important;
|
|
3837
|
+
padding: 0 2px !important;
|
|
3838
|
+
overflow: hidden !important;
|
|
3839
|
+
justify-content: center !important;
|
|
3840
|
+
gap: 0 !important;
|
|
3841
|
+
font-size: 0 !important;
|
|
3842
|
+
/* 悬停锁定:宽度与位移都不变,杜绝工具栏/对话框抖动 */
|
|
3843
|
+
transition: none !important;
|
|
3844
|
+
border-radius: 8px !important;
|
|
3845
|
+
}
|
|
3846
|
+
div[class*="uV2eYG_trailing"] span > button:not([class]):hover {
|
|
3847
|
+
width: 26px !important;
|
|
3848
|
+
min-width: 26px !important;
|
|
3849
|
+
padding: 0 2px !important;
|
|
3850
|
+
background: var(--dsw-alias-interactive-bg-hover, rgba(127, 127, 127, 0.15)) !important;
|
|
3851
|
+
}
|
|
3852
|
+
div[class*="uV2eYG_trailing"] span > button:not([class]) svg {
|
|
3853
|
+
flex: 0 0 auto !important;
|
|
3854
|
+
}
|
|
3855
|
+
|
|
3728
3856
|
div[class*="uV2eYG_tools"] {
|
|
3729
3857
|
display: flex !important;
|
|
3730
3858
|
align-items: center !important;
|
|
@@ -3807,7 +3935,8 @@ function injectMobileStyles() {
|
|
|
3807
3935
|
div[class*="_sidebarCol"] {
|
|
3808
3936
|
position: fixed !important;
|
|
3809
3937
|
left: 0 !important;
|
|
3810
|
-
|
|
3938
|
+
/* 顶到顶部标签条(38px)之下,不再与最上面的栏重叠 */
|
|
3939
|
+
top: 38px !important;
|
|
3811
3940
|
bottom: auto !important;
|
|
3812
3941
|
/* 侧边栏底部溢出屏幕修复:
|
|
3813
3942
|
实测 390x844 下,侧边栏实际盒子为 T=12 B=882(高度 870 > 视口 844),底部溢出 38px。
|
|
@@ -3815,8 +3944,8 @@ function injectMobileStyles() {
|
|
|
3815
3944
|
于是 padding(10px+14px) 与 margin(12px) 被加在 height:100dvh 之外。
|
|
3816
3945
|
改为 border-box 并用 100dvh 直接约束高度,padding 即被包含在高度内。 */
|
|
3817
3946
|
box-sizing: border-box !important;
|
|
3818
|
-
height: 100dvh !important;
|
|
3819
|
-
max-height: 100dvh !important;
|
|
3947
|
+
height: calc(100dvh - 38px) !important;
|
|
3948
|
+
max-height: calc(100dvh - 38px) !important;
|
|
3820
3949
|
margin: 0 !important;
|
|
3821
3950
|
width: 290px !important;
|
|
3822
3951
|
max-width: 82vw !important;
|
|
@@ -4301,6 +4430,141 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
4301
4430
|
panelObserver.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['class'] });
|
|
4302
4431
|
window.addEventListener('resize', ensurePanelCloseButton);
|
|
4303
4432
|
|
|
4433
|
+
// 1.5 移动端标题行「对话」下拉:隐藏原生 tablist,在标准模式右边注入一个
|
|
4434
|
+
// 原生样式的「对话 ▾」按钮,点开下拉选择 对话/轨迹/上下文 切换视图。
|
|
4435
|
+
// 文案从原生 tab 动态读取(语言无关);按钮类名复刻原生标题行按钮。
|
|
4436
|
+
const mobileTabState = { btn: null, dropdown: null };
|
|
4437
|
+
|
|
4438
|
+
const nativeTabs = () => [...document.querySelectorAll('[role="tablist"] [role="tab"]')];
|
|
4439
|
+
|
|
4440
|
+
const closeTabDropdown = () => {
|
|
4441
|
+
if (mobileTabState.dropdown) {
|
|
4442
|
+
mobileTabState.dropdown.remove();
|
|
4443
|
+
mobileTabState.dropdown = null;
|
|
4444
|
+
}
|
|
4445
|
+
};
|
|
4446
|
+
|
|
4447
|
+
const renderTabDropdown = () => {
|
|
4448
|
+
closeTabDropdown();
|
|
4449
|
+
if (!mobileTabState.btn) return;
|
|
4450
|
+
const dropdown = document.createElement('div');
|
|
4451
|
+
dropdown.className = 'dsh-mobile-tab-dropdown';
|
|
4452
|
+
const tabs = nativeTabs();
|
|
4453
|
+
tabs.forEach((tabEl) => {
|
|
4454
|
+
const isActive = tabEl.getAttribute('aria-selected') === 'true';
|
|
4455
|
+
const option = document.createElement('button');
|
|
4456
|
+
option.type = 'button';
|
|
4457
|
+
option.className = 'dsh-mobile-tab-option';
|
|
4458
|
+
option.setAttribute('data-active', isActive ? 'true' : 'false');
|
|
4459
|
+
const name = document.createElement('span');
|
|
4460
|
+
name.textContent = tabEl.textContent.replace(/\s+/g, ' ').trim();
|
|
4461
|
+
option.appendChild(name);
|
|
4462
|
+
if (isActive) {
|
|
4463
|
+
const check = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
4464
|
+
check.setAttribute('width', '14');
|
|
4465
|
+
check.setAttribute('height', '14');
|
|
4466
|
+
check.setAttribute('viewBox', '0 0 24 24');
|
|
4467
|
+
check.setAttribute('fill', 'none');
|
|
4468
|
+
check.setAttribute('stroke', 'currentColor');
|
|
4469
|
+
check.setAttribute('stroke-width', '2.5');
|
|
4470
|
+
check.setAttribute('stroke-linecap', 'round');
|
|
4471
|
+
check.setAttribute('stroke-linejoin', 'round');
|
|
4472
|
+
check.innerHTML = '<polyline points="20 6 9 17 4 12"></polyline>';
|
|
4473
|
+
option.appendChild(check);
|
|
4474
|
+
}
|
|
4475
|
+
option.onclick = (e) => {
|
|
4476
|
+
e.stopPropagation();
|
|
4477
|
+
tabEl.click();
|
|
4478
|
+
closeTabDropdown();
|
|
4479
|
+
syncTabButtonLabel();
|
|
4480
|
+
};
|
|
4481
|
+
dropdown.appendChild(option);
|
|
4482
|
+
});
|
|
4483
|
+
mobileTabState.btn.appendChild(dropdown);
|
|
4484
|
+
mobileTabState.dropdown = dropdown;
|
|
4485
|
+
};
|
|
4486
|
+
|
|
4487
|
+
const syncTabButtonLabel = () => {
|
|
4488
|
+
if (!mobileTabState.btn || !mobileTabState.btn.isConnected) return;
|
|
4489
|
+
const active = nativeTabs().find((t) => t.getAttribute('aria-selected') === 'true');
|
|
4490
|
+
const labelEl = mobileTabState.btn.querySelector('.dsh-mobile-tab-btn-label');
|
|
4491
|
+
if (!labelEl || !active) return;
|
|
4492
|
+
// 只有文案真的变化才写入:textContent 无条件赋值会移除并重建文本节点,
|
|
4493
|
+
// 触发 MutationObserver → 无限循环,页面卡死。
|
|
4494
|
+
const name = active.textContent.replace(/\s+/g, ' ').trim();
|
|
4495
|
+
if (labelEl.textContent !== name) labelEl.textContent = name;
|
|
4496
|
+
};
|
|
4497
|
+
|
|
4498
|
+
const ensureTabButton = () => {
|
|
4499
|
+
if (typeof window === 'undefined' || window.innerWidth > 768) return;
|
|
4500
|
+
const titleRow = document.querySelector('div[class*="wSkVaW_titleRow"]');
|
|
4501
|
+
const cluster = titleRow ? titleRow.querySelector('div[class*="wSkVaW_titleCluster"]') : null;
|
|
4502
|
+
if (!titleRow || !cluster) {
|
|
4503
|
+
closeTabDropdown();
|
|
4504
|
+
if (mobileTabState.btn) {
|
|
4505
|
+
mobileTabState.btn.remove();
|
|
4506
|
+
mobileTabState.btn = null;
|
|
4507
|
+
}
|
|
4508
|
+
return;
|
|
4509
|
+
}
|
|
4510
|
+
if (mobileTabState.btn && mobileTabState.btn.isConnected && titleRow.contains(mobileTabState.btn)) {
|
|
4511
|
+
syncTabButtonLabel();
|
|
4512
|
+
return;
|
|
4513
|
+
}
|
|
4514
|
+
document.querySelectorAll('.dsh-mobile-tab-btn').forEach((el) => el.remove());
|
|
4515
|
+
const tabBtn = document.createElement('button');
|
|
4516
|
+
tabBtn.type = 'button';
|
|
4517
|
+
// 观感对齐:优先复刻标准模式胶囊的类,其次访达图标按钮,最后自有样式兜底
|
|
4518
|
+
const pillBtn = titleRow.querySelector('div[class*="wSkVaW_titleCluster"] button');
|
|
4519
|
+
const utilBtn = titleRow.querySelector('div[class*="wSkVaW_headerUtilities"] button');
|
|
4520
|
+
const mimic = (pillBtn && pillBtn.className) || (utilBtn && utilBtn.className) || '';
|
|
4521
|
+
tabBtn.className = (mimic ? mimic + ' ' : '') + 'dsh-mobile-tab-btn';
|
|
4522
|
+
tabBtn.innerHTML = `<span class="dsh-mobile-tab-btn-label">对话</span><svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>`;
|
|
4523
|
+
tabBtn.onclick = (e) => {
|
|
4524
|
+
e.stopPropagation();
|
|
4525
|
+
if (mobileTabState.dropdown) closeTabDropdown();
|
|
4526
|
+
else renderTabDropdown();
|
|
4527
|
+
};
|
|
4528
|
+
titleRow.insertBefore(tabBtn, cluster.nextSibling);
|
|
4529
|
+
mobileTabState.btn = tabBtn;
|
|
4530
|
+
syncTabButtonLabel();
|
|
4531
|
+
};
|
|
4532
|
+
|
|
4533
|
+
// workbuddy-connect 的 Reasoning 按钮:移动端删掉文字节点只留图标(svg 保留),
|
|
4534
|
+
// 插件重渲染后新按钮由观察器重新清理
|
|
4535
|
+
const cleanReasoningButtons = () => {
|
|
4536
|
+
if (typeof window === 'undefined' || window.innerWidth > 768) return;
|
|
4537
|
+
document.querySelectorAll('div[class*="uV2eYG_trailing"] span > button:not([class])').forEach((btn) => {
|
|
4538
|
+
if (btn.dataset.dshTextCleaned === '1') return;
|
|
4539
|
+
[...btn.childNodes].forEach((node) => {
|
|
4540
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
4541
|
+
if (node.tagName.toLowerCase() === 'svg' || (typeof node.querySelector === 'function' && node.querySelector('svg'))) return;
|
|
4542
|
+
}
|
|
4543
|
+
node.remove();
|
|
4544
|
+
});
|
|
4545
|
+
btn.dataset.dshTextCleaned = '1';
|
|
4546
|
+
});
|
|
4547
|
+
};
|
|
4548
|
+
|
|
4549
|
+
const titleExtrasObserver = new MutationObserver(() => {
|
|
4550
|
+
ensureTabButton();
|
|
4551
|
+
cleanReasoningButtons();
|
|
4552
|
+
});
|
|
4553
|
+
titleExtrasObserver.observe(document.body, { childList: true, subtree: true });
|
|
4554
|
+
window.addEventListener('resize', () => {
|
|
4555
|
+
if (window.innerWidth > 768) closeTabDropdown();
|
|
4556
|
+
});
|
|
4557
|
+
document.addEventListener(
|
|
4558
|
+
'click',
|
|
4559
|
+
(e) => {
|
|
4560
|
+
if (!mobileTabState.dropdown) return;
|
|
4561
|
+
if (!mobileTabState.dropdown.contains(e.target) && !e.target.closest('.dsh-mobile-tab-btn')) closeTabDropdown();
|
|
4562
|
+
},
|
|
4563
|
+
true,
|
|
4564
|
+
);
|
|
4565
|
+
ensureTabButton();
|
|
4566
|
+
cleanReasoningButtons();
|
|
4567
|
+
|
|
4304
4568
|
// 移动端点击面板/工作区触发按钮时,自动激活 dsh-workbench-open
|
|
4305
4569
|
document.addEventListener('click', (e) => {
|
|
4306
4570
|
if (typeof window === 'undefined' || window.innerWidth > 768) return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-bridge-gateway",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "以 dsh-bridge 为根基、融合 remote-gateway 能力的 DSH 远程访问网关:局域网 / Cloudflare 隧道 / 自建隧道之外,新增「公网直连网关」(0.0.0.0 监听 + 自带 HTTPS 自签证书 + 强制登录门禁),解决移动端外网直连操控电脑。",
|
|
5
5
|
"releaseNotes": "【dsh-bridge-gateway 0.1.5】\n• 🔧 适配 DSH 0.1.5:RPC 通道迁移到 webServer 直注册 + requestRejection 鉴权\n• 📱 移动端深度适配:顶栏防重叠、分支 chip 不再裁切、输入框宽度对齐并 sticky 固定、44px 点击热区、侧边栏焦点陷阱消除\n• 默认不启用,安装后原有局域网/隧道/IM 行为完全不变",
|
|
6
6
|
"type": "module",
|