dsh-bridge-gateway 0.2.1 → 0.3.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/CHANGELOG.md +106 -0
- package/README.md +25 -3
- package/README.zh.md +35 -2
- package/assets/apple-touch-icon-180.png +0 -0
- package/assets/icon-192.png +0 -0
- package/assets/icon-512.png +0 -0
- package/assets/icon-maskable-192.png +0 -0
- package/assets/icon-maskable-512.png +0 -0
- package/client/client.js +302 -41
- package/client/index.js +438 -42
- package/docs/banner.jpg +0 -0
- package/docs/custom-tunnel.md +5 -5
- package/docs/platform-abstraction-design.md +1 -1
- package/docs/qq-usage.md +6 -6
- package/docs/screenshots/remote-auth-login-light.jpg +0 -0
- package/docs/screenshots/remote-auth-login.jpg +0 -0
- package/docs/wechat-usage.md +1 -1
- package/lib/auth/brand-assets.js +131 -0
- package/lib/auth/login-template.js +503 -361
- package/lib/auth/manager.js +47 -12
- package/lib/auth/theme-tokens.js +142 -0
- package/lib/bridge-rpc.js +2 -2
- package/lib/cloudflared-manager.mjs +1 -1
- package/lib/feishu/gateway.js +17 -17
- package/lib/feishu/index.js +3 -3
- package/lib/feishu/lark-bundled.mjs +284 -446
- package/lib/feishu/node.js +7 -7
- package/lib/gateway/cert.js +1 -1
- package/lib/index.js +289 -80
- package/lib/paths.js +43 -14
- package/lib/platform/base.js +2 -2
- package/lib/platform/conversation-bridge.js +17 -17
- package/lib/platform/index.js +1 -1
- package/lib/platform/manager.js +4 -4
- package/lib/qq/gateway.js +10 -10
- package/lib/qq/index.js +11 -11
- package/lib/qq/node.js +17 -17
- package/lib/telegram/gateway.js +10 -10
- package/lib/telegram/index.js +3 -3
- package/lib/telegram/node.js +5 -5
- package/lib/wechat/gateway.js +6 -6
- package/lib/wechat/index.js +4 -4
- package/lib/wechat/media.js +1 -1
- package/lib/wechat/node.js +13 -13
- package/package.json +6 -3
package/client/client.js
CHANGED
|
@@ -2639,7 +2639,7 @@ function BackupRestoreWidget({ rpcCall, onUpdate }) {
|
|
|
2639
2639
|
const now = /* @__PURE__ */ new Date();
|
|
2640
2640
|
const dateStr = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, "0")}${String(now.getDate()).padStart(2, "0")}`;
|
|
2641
2641
|
a.href = url;
|
|
2642
|
-
a.download = `dsh-bridge-backup-${dateStr}.json`;
|
|
2642
|
+
a.download = `dsh-bridge-gateway-backup-${dateStr}.json`;
|
|
2643
2643
|
document.body.appendChild(a);
|
|
2644
2644
|
a.click();
|
|
2645
2645
|
document.body.removeChild(a);
|
|
@@ -3935,11 +3935,165 @@ function BridgePanel({ rpcCall }) {
|
|
|
3935
3935
|
)
|
|
3936
3936
|
);
|
|
3937
3937
|
}
|
|
3938
|
+
function setupMobileDiag() {
|
|
3939
|
+
if (document.getElementById("dsh-mobile-diag")) return;
|
|
3940
|
+
const box = document.createElement("div");
|
|
3941
|
+
box.id = "dsh-mobile-diag";
|
|
3942
|
+
box.style.cssText = [
|
|
3943
|
+
"position:fixed",
|
|
3944
|
+
"left:0",
|
|
3945
|
+
"right:0",
|
|
3946
|
+
"top:0",
|
|
3947
|
+
"z-index:2147483647",
|
|
3948
|
+
"background:rgba(0,0,0,.86)",
|
|
3949
|
+
"color:#0f0",
|
|
3950
|
+
"pointer-events:none",
|
|
3951
|
+
"font:11px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace",
|
|
3952
|
+
"padding:5px 7px",
|
|
3953
|
+
"white-space:pre-wrap",
|
|
3954
|
+
"word-break:break-all"
|
|
3955
|
+
].join(";");
|
|
3956
|
+
document.body.appendChild(box);
|
|
3957
|
+
const tick = () => {
|
|
3958
|
+
const sb = document.querySelector('[class*="wSkVaW_scrollBody"]');
|
|
3959
|
+
const seat = document.querySelector('[class*="wSkVaW_composerSeat"]');
|
|
3960
|
+
const vv = window.visualViewport;
|
|
3961
|
+
const L = [];
|
|
3962
|
+
if (sb) {
|
|
3963
|
+
const r = sb.getBoundingClientRect();
|
|
3964
|
+
const max = sb.scrollHeight - sb.clientHeight;
|
|
3965
|
+
L.push("scrollBody top=" + Math.round(r.top) + " h=" + Math.round(r.height) + " pad=" + getComputedStyle(sb).paddingBottom);
|
|
3966
|
+
L.push(" scrollTop=" + Math.round(sb.scrollTop) + " max=" + max + " atBottom=" + (sb.scrollTop >= max - 2));
|
|
3967
|
+
L.push(" scrollH=" + sb.scrollHeight + " clientH=" + sb.clientHeight + " children=" + sb.children.length);
|
|
3968
|
+
const idx = sb.querySelectorAll("[data-index]");
|
|
3969
|
+
L.push(" virtItems=" + idx.length);
|
|
3970
|
+
} else {
|
|
3971
|
+
L.push("scrollBody: NOT FOUND");
|
|
3972
|
+
}
|
|
3973
|
+
if (seat) {
|
|
3974
|
+
const r = seat.getBoundingClientRect();
|
|
3975
|
+
L.push("composer pos=" + getComputedStyle(seat).position + " top=" + Math.round(r.top) + " h=" + Math.round(r.height));
|
|
3976
|
+
}
|
|
3977
|
+
L.push("inner=" + window.innerHeight + " vv=" + (vv ? Math.round(vv.height) : "-") + " vvTop=" + (vv ? Math.round(vv.offsetTop) : "-") + " dpr=" + window.devicePixelRatio + " w=" + window.innerWidth);
|
|
3978
|
+
L.push("body=" + Array.from(document.body.classList).join("."));
|
|
3979
|
+
box.textContent = L.join("\n");
|
|
3980
|
+
};
|
|
3981
|
+
tick();
|
|
3982
|
+
window.setInterval(tick, 500);
|
|
3983
|
+
window.addEventListener("scroll", tick, true);
|
|
3984
|
+
window.addEventListener("resize", tick);
|
|
3985
|
+
}
|
|
3986
|
+
var SUSPECT_CSS = {
|
|
3987
|
+
// _frame 规则 —— 真机二分结论(2026-10-17):
|
|
3988
|
+
// ?dsh-mobile=no-frameSize (去掉 width:100vw + height:100dvh)→ scrollH 恢复正常
|
|
3989
|
+
// ?dsh-mobile=no-frameOverflow(去掉 overflow:hidden) → scrollH 恢复正常
|
|
3990
|
+
// 两个属性各自都能触发,说明是「固定高度 + 裁剪」这个组合在作怪:
|
|
3991
|
+
// height:100dvh 把主框架钉成固定高、overflow:hidden 又让它成为裁剪容器,
|
|
3992
|
+
// DSH 的布局测量因此算错,导致只渲染约 4 条消息(scrollH≈795,正常应 10 万+)。
|
|
3993
|
+
// 故**这两个属性组已删除**,不再注入。只保留 padding-top(本规则的目的:
|
|
3994
|
+
// 为固定顶栏腾出空间)与 display/flex-direction/position(抽屉化的前提)。
|
|
3995
|
+
// 注意 grid-template-columns:1fr 也已去掉 —— 它是 grid 属性,在 flex 容器里无效。
|
|
3996
|
+
// padding-top / box-sizing 是这条规则的**目的**(为固定顶栏腾空间),任何分组都保留
|
|
3997
|
+
frameBase: `
|
|
3998
|
+
div[class*="_frame"] {
|
|
3999
|
+
padding-top: var(--dsh-mobile-header-h) !important;
|
|
4000
|
+
margin: 0 !important;
|
|
4001
|
+
box-sizing: border-box !important;
|
|
4002
|
+
}`,
|
|
4003
|
+
frameLayout: `
|
|
4004
|
+
div[class*="_frame"] {
|
|
4005
|
+
display: flex !important;
|
|
4006
|
+
flex-direction: column !important;
|
|
4007
|
+
position: relative !important;
|
|
4008
|
+
}`,
|
|
4009
|
+
centercol: ` div[class*="_centerCol"] {
|
|
4010
|
+
flex: 1 1 100% !important;
|
|
4011
|
+
width: 100% !important;
|
|
4012
|
+
min-width: 0 !important;
|
|
4013
|
+
max-width: 100% !important;
|
|
4014
|
+
display: flex !important;
|
|
4015
|
+
height: 100% !important;
|
|
4016
|
+
}`,
|
|
4017
|
+
pad: ` div[class*="wSkVaW_scrollBody"] {
|
|
4018
|
+
padding-bottom: max(16px, env(safe-area-inset-bottom)) !important;
|
|
4019
|
+
}
|
|
4020
|
+
div[class*="wSkVaW_scrollBody"] {
|
|
4021
|
+
padding-bottom: calc(6px + env(safe-area-inset-bottom, 0px)) !important;
|
|
4022
|
+
}`
|
|
4023
|
+
};
|
|
4024
|
+
function injectSuspectStyles(disabled) {
|
|
4025
|
+
const parts = Object.entries(SUSPECT_CSS).filter(([k]) => !disabled.has(k)).map(([, v]) => v);
|
|
4026
|
+
if (parts.length === 0) return;
|
|
4027
|
+
if (document.getElementById("dsh-bridge-gateway-mobile-styles-suspect")) return;
|
|
4028
|
+
const style = document.createElement("style");
|
|
4029
|
+
style.id = "dsh-bridge-gateway-mobile-styles-suspect";
|
|
4030
|
+
style.textContent = "@media (max-width: 768px) {\n" + parts.join("\n") + "\n}";
|
|
4031
|
+
document.head.appendChild(style);
|
|
4032
|
+
}
|
|
4033
|
+
var NEW_MOBILE_CSS = `
|
|
4034
|
+
/* #2 \u9762\u677F\u6253\u5F00\u65F6\u9876\u680F\u8BA9\u4F4D\uFF08body.dsh-panel-open \u7531 setupPanelAwareness \u6253\u4E0A\uFF09\u3002
|
|
4035
|
+
\u5B9E\u6D4B\uFF1A\u6E20\u9053\u4E2D\u5FC3\u9762\u677F\u6807\u9898\u5728 y19\uFF0C\u800C\u9876\u680F\u5360 y0-40 \u2192 \u4E0D\u6539\u5C31\u662F\u6807\u9898\u88AB\u76D6\u4F4F\u3002
|
|
4036
|
+
\u4E0D\u7528 :has() \u662F\u56E0\u4E3A\u6784\u5EFA\u76EE\u6807\u662F chrome100\uFF08:has() \u8981 105+\uFF09\u3002 */
|
|
4037
|
+
body.dsh-panel-open .dsh-mobile-app-header {
|
|
4038
|
+
display: none !important;
|
|
4039
|
+
}
|
|
4040
|
+
|
|
4041
|
+
/* #6 \u53CC\u5C42\u5934\u538B\u7F29\uFF1ADSH \u81EA\u5E26 min-height:76px\uFF0C\u53EA\u6539 padding \u538B\u4E0D\u4E0B\u53BB \u2014\u2014 \u5B9E\u6D4B
|
|
4042
|
+
76px \u4E00\u76F4\u751F\u6548\u3001titleRow \u88AB\u62C9\u4F38\u586B\u6EE1\uFF0869px\uFF09\uFF0C\u4E24\u5C42\u5934\u5408\u8BA1\u5403\u6389 128px\uFF08\u5C4F\u5E55 15%\uFF09\u3002
|
|
4043
|
+
\u663E\u5F0F\u6E05\u96F6 + \u628A padding \u6536\u5230 2px\uFF0C\u5B9E\u6D4B\u5185\u5BB9\u533A +51px\u3002 */
|
|
4044
|
+
div[class*="_centerCol"] header,
|
|
4045
|
+
header[class*="wSkVaW_header"] {
|
|
4046
|
+
min-height: 0 !important;
|
|
4047
|
+
padding: 2px 16px !important;
|
|
4048
|
+
}
|
|
4049
|
+
div[class*="wSkVaW_titleRow"] {
|
|
4050
|
+
min-height: 0 !important;
|
|
4051
|
+
height: 32px !important;
|
|
4052
|
+
}
|
|
4053
|
+
|
|
4054
|
+
/* #4-C \u8868\u683C\u6A2A\u5411\u6EDA\u52A8\uFF1Atable \u5143\u7D20\u7684 overflow \u5728 CSS \u91CC\u662F**\u88AB\u5FFD\u7565**\u7684\uFF0C\u5FC5\u987B\u914D
|
|
4055
|
+
display:block \u624D\u4F1A\u53D8\u6210\u53EF\u6EDA\u5757\u76D2\uFF08\u63D2\u4EF6\u539F\u6765\u53EA\u5199\u4E86 overflow-x:auto\uFF0C\u6240\u4EE5\u65E0\u6548\uFF09\u3002 */
|
|
4056
|
+
div[class*="wSkVaW_scrollBody"] table {
|
|
4057
|
+
display: block !important;
|
|
4058
|
+
max-width: 100% !important;
|
|
4059
|
+
width: 100% !important;
|
|
4060
|
+
overflow-x: auto !important;
|
|
4061
|
+
-webkit-overflow-scrolling: touch !important;
|
|
4062
|
+
}
|
|
4063
|
+
|
|
4064
|
+
/* #4-E \u8F68\u8FF9\u91CC\u7684\u5DE5\u5177\u8C03\u7528\u53C2\u6570\u6362\u884C\uFF1A\u8BE5\u5217\u5185\u5BB9\u5BBD 3049px \u5374\u53EA\u6709 180px \u53EF\u89C1\uFF0817\xD7\uFF09\uFF0C
|
|
4065
|
+
\u6A2A\u6ED1\u8981\u5212 17 \u5C4F\u3001\u5B9E\u9645\u8BFB\u4E0D\u4E86\u3002overflow-wrap:anywhere \u662F\u5FC5\u987B\u7684 \u2014\u2014 bash \u547D\u4EE4\u91CC
|
|
4066
|
+
\u5E38\u6709\u8D85\u957F\u65E0\u7A7A\u683C token\u3002 */
|
|
4067
|
+
div[class*="wSkVaW_scrollBody"] [class*="resultRequest"] {
|
|
4068
|
+
white-space: normal !important;
|
|
4069
|
+
overflow-wrap: anywhere !important;
|
|
4070
|
+
word-break: break-word !important;
|
|
4071
|
+
text-overflow: clip !important;
|
|
4072
|
+
overflow: visible !important;
|
|
4073
|
+
}
|
|
4074
|
+
|
|
4075
|
+
/* #7 \u4E0B\u62C9\u6539 body \u7EA7 portal\uFF08position:fixed\uFF09\u3002\u4E3A\u4EC0\u4E48\u4E0D\u80FD absolute \u6302\u5728\u6309\u94AE\u91CC\uFF1A
|
|
4076
|
+
\u7956\u5148\u94FE titleRow \u4E0E wSkVaW_root \u90FD\u662F overflow:hidden\uFF08titleRow \u90A3\u6761\u8FD8\u662F\u63D2\u4EF6
|
|
4077
|
+
\u81EA\u5DF1\u4E3A\u4E86\u7701\u7565\u53F7\u8BBE\u7684\uFF09\u2192 \u4E0B\u62C9\u843D\u5728\u5934\u90E8\u4E0B\u65B9 y78 \u4F1A\u88AB**\u6574\u5757\u88C1\u6389**\uFF0C\u5B9E\u6D4B\u4E2D\u5FC3\u70B9\u547D\u4E2D
|
|
4078
|
+
\u7684\u662F\u6D88\u606F\u6587\u672C\u3002z-index \u518D\u9AD8\u4E5F\u6CA1\u7528\uFF0C\u88C1\u526A\u53D1\u751F\u5728\u5C42\u53E0\u4E4B\u524D\u3002
|
|
4079
|
+
\u6CE8\u610F\uFF1A**\u4E0D\u80FD**\u5199 top/left \u7684 !important \u2014\u2014 \u90A3\u4F1A\u538B\u8FC7 positionTabDropdown()
|
|
4080
|
+
\u5199\u7684\u5185\u8054\u5750\u6807\uFF0C\u628A\u4E0B\u62C9\u9489\u5728\u5DE6\u4E0A\u89D2\u3002 */
|
|
4081
|
+
.dsh-mobile-tab-dropdown {
|
|
4082
|
+
position: fixed !important;
|
|
4083
|
+
}
|
|
4084
|
+
`;
|
|
4085
|
+
function injectNewMobileStyles() {
|
|
4086
|
+
if (document.getElementById("dsh-bridge-gateway-mobile-styles-new")) return;
|
|
4087
|
+
const style = document.createElement("style");
|
|
4088
|
+
style.id = "dsh-bridge-gateway-mobile-styles-new";
|
|
4089
|
+
style.textContent = "@media (max-width: 768px) {\n" + NEW_MOBILE_CSS + "\n}";
|
|
4090
|
+
document.head.appendChild(style);
|
|
4091
|
+
}
|
|
3938
4092
|
function injectMobileStyles() {
|
|
3939
4093
|
if (typeof document === "undefined") return;
|
|
3940
|
-
if (document.getElementById("dsh-bridge-mobile-styles")) return;
|
|
4094
|
+
if (document.getElementById("dsh-bridge-gateway-mobile-styles")) return;
|
|
3941
4095
|
const style = document.createElement("style");
|
|
3942
|
-
style.id = "dsh-bridge-mobile-styles";
|
|
4096
|
+
style.id = "dsh-bridge-gateway-mobile-styles";
|
|
3943
4097
|
style.textContent = `
|
|
3944
4098
|
/* DSH Bridge \u9690\u85CF Tab \u680F\u539F\u751F\u6EDA\u52A8\u6761\u5E76\u4FDD\u6301\u5E73\u6ED1\u6ED1\u52A8 */
|
|
3945
4099
|
.dsh-tabbar-container {
|
|
@@ -3954,25 +4108,16 @@ function injectMobileStyles() {
|
|
|
3954
4108
|
|
|
3955
4109
|
/* DSH Bridge \u79FB\u52A8\u7AEF\u81EA\u9002\u5E94\u4E0E\u89E6\u63A7\u4EA4\u4E92\u589E\u5F3A\u6837\u5F0F */
|
|
3956
4110
|
:root {
|
|
3957
|
-
|
|
4111
|
+
/* \u9876\u680F\u9AD8\u5EA6 52 -> 40\uFF082026-10-16 \u771F\u673A\u53CD\u9988\uFF1A"\u4E0A\u9762\u9AD8\u5EA6\u592A\u9AD8\u4E86\uFF0C\u628A\u5BF9\u8BDD\u6846\u7684\u7A7A\u95F4\u538B\u7F29\u4E86"\uFF09\u3002
|
|
4112
|
+
40px \u4ECD\u80FD\u5BB9\u7EB3 32px \u7684 \u2630/\u2295 \u6309\u94AE\u4E0E\u4E00\u884C\u4F1A\u8BDD\u540D\u3002 */
|
|
4113
|
+
--dsh-mobile-header-h: 40px;
|
|
3958
4114
|
--dsh-mobile-safe-top: env(safe-area-inset-top, 0px);
|
|
3959
4115
|
--dsh-mobile-safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
3960
4116
|
}
|
|
3961
4117
|
|
|
3962
4118
|
@media (max-width: 768px) {
|
|
3963
4119
|
/* 1. \u4E3B\u6846\u67B6\u4E3A Header \u817E\u51FA\u9876\u90E8\u7A7A\u95F4 */
|
|
3964
|
-
|
|
3965
|
-
display: flex !important;
|
|
3966
|
-
flex-direction: column !important;
|
|
3967
|
-
width: 100vw !important;
|
|
3968
|
-
height: 100dvh !important;
|
|
3969
|
-
margin: 0 !important;
|
|
3970
|
-
padding-top: var(--dsh-mobile-header-h) !important;
|
|
3971
|
-
position: relative !important;
|
|
3972
|
-
grid-template-columns: 1fr !important;
|
|
3973
|
-
overflow: hidden !important;
|
|
3974
|
-
box-sizing: border-box !important;
|
|
3975
|
-
}
|
|
4120
|
+
|
|
3976
4121
|
|
|
3977
4122
|
/* 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) */
|
|
3978
4123
|
.dsh-mobile-app-header {
|
|
@@ -4052,14 +4197,7 @@ function injectMobileStyles() {
|
|
|
4052
4197
|
}
|
|
4053
4198
|
|
|
4054
4199
|
/* 3. \u4E2D\u95F4\u4E3B\u5185\u5BB9\u533A\u4E0E\u8F93\u5165\u6846 */
|
|
4055
|
-
|
|
4056
|
-
flex: 1 1 100% !important;
|
|
4057
|
-
width: 100% !important;
|
|
4058
|
-
min-width: 0 !important;
|
|
4059
|
-
max-width: 100% !important;
|
|
4060
|
-
display: flex !important;
|
|
4061
|
-
height: 100% !important;
|
|
4062
|
-
}
|
|
4200
|
+
|
|
4063
4201
|
|
|
4064
4202
|
div[class*="_detailsCol"],
|
|
4065
4203
|
div[class*="toggleCluster"],
|
|
@@ -4450,9 +4588,7 @@ function injectMobileStyles() {
|
|
|
4450
4588
|
}
|
|
4451
4589
|
|
|
4452
4590
|
/* \u8F93\u5165\u6846\u5E95\u5EA7\uFF1ADeepSeek App \u5C45\u4E2D\u53CA\u5E95\u90E8\u56FA\u5B9A */
|
|
4453
|
-
|
|
4454
|
-
padding-bottom: max(16px, env(safe-area-inset-bottom)) !important;
|
|
4455
|
-
}
|
|
4591
|
+
|
|
4456
4592
|
|
|
4457
4593
|
/* \u8F93\u5165\u5361\u7247\uFF1ADeepSeek App \u5706\u89D2\u5927\u80F6\u56CA\u9020\u578B */
|
|
4458
4594
|
div[class*="uV2eYG_card"] {
|
|
@@ -4646,11 +4782,20 @@ function injectMobileStyles() {
|
|
|
4646
4782
|
}
|
|
4647
4783
|
|
|
4648
4784
|
/* \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
|
|
4649
|
-
\u518D\u57AB 6px \u8BA9\u7EDF\u8BA1\u836F\u4E38\u5B8C\u6574\u53EF\u89C1
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4785
|
+
\u518D\u57AB 6px \u8BA9\u7EDF\u8BA1\u836F\u4E38\u5B8C\u6574\u53EF\u89C1\u3002
|
|
4786
|
+
|
|
4787
|
+
\u26A0\uFE0F **\u4E0D\u8981**\u518D\u8BD5\u56FE\u5728\u8FD9\u91CC\u52A0 --dsh-composer-height\u3001\u4E5F\u4E0D\u8981\u7ED9 composerSeat \u52A0
|
|
4788
|
+
position:fixed\uFF082026-10-16 \u4E24\u6B21\u5C1D\u8BD5\uFF0C\u5747\u5DF2\u56DE\u9000\uFF09\u3002\u539F\u56E0\uFF1ADSH \u7684\u6EDA\u52A8\u951A\u5B9A
|
|
4789
|
+
\uFF08dsh-client-ui-conversation\uFF09\u662F**\u6309 DOM \u6D41\u5185\u4F4D\u7F6E**\u904D\u5386\u7956\u5148\u7B97\u504F\u79FB\u6765\u4FEE\u6B63
|
|
4790
|
+
scrollTop \u7684\uFF1B\u628A composer \u6458\u51FA\u6587\u6863\u6D41\u3001\u6216\u7ED9\u6EDA\u52A8\u5185\u5BB9\u52A0 padding\uFF0C\u951A\u5B9A\u5C31\u7B97\u9519\uFF0C
|
|
4791
|
+
\u771F\u673A\u75C7\u72B6\u662F\u300C\u8FDB\u53BB\u505C\u5728\u5F88\u4E45\u4EE5\u524D\u7684\u67D0\u6761\uFF0C\u70B9\u300E\u52A0\u8F7D\u66F4\u65E9\u300F\u540E\u518D\u4E5F\u56DE\u4E0D\u5230\u6700\u65B0\u300D\u3002
|
|
4792
|
+
\u8FD9\u4E2A\u906E\u6321\u662F DSH \u5BF9\u8BDD\u89C6\u56FE sticky \u5438\u5E95\u8BBE\u8BA1\u7684\u56FA\u6709\u4EE3\u4EF7\uFF1BDSH \u53E6\u6709"\u8986\u76D6\u5C42\u6A21\u5F0F"
|
|
4793
|
+
\uFF08:has([data-conversation-composer-overlay])\uFF1AcomposerSeat \u8F6C absolute\u3001
|
|
4794
|
+
viewArea \u81EA\u5DF1\u6EDA\uFF09\uFF0C\u4F46\u90A3\u662F **dsh-client-ui-trajectory\uFF08\u8F68\u8FF9\u89C6\u56FE\uFF09** \u5728\u7528\u7684\uFF0C
|
|
4795
|
+
\u5BF9\u8BDD\u89C6\u56FE\u6CA1\u6709\u5F00\u3002\u8981\u6839\u6CBB\u5F97\u8D70 DSH \u4FA7\uFF0C\u4E0D\u662F\u63D2\u4EF6 CSS \u80FD\u8865\u7684\u3002 */
|
|
4796
|
+
|
|
4797
|
+
|
|
4798
|
+
div[class*="wSkVaW_composerStack"] {
|
|
4654
4799
|
padding-bottom: env(safe-area-inset-bottom, 0px) !important;
|
|
4655
4800
|
}
|
|
4656
4801
|
|
|
@@ -4957,15 +5102,15 @@ function injectMobileStyles() {
|
|
|
4957
5102
|
box-sizing: border-box !important;
|
|
4958
5103
|
}
|
|
4959
5104
|
|
|
4960
|
-
/* 7. \u4EE3\u7801\u5757\
|
|
4961
|
-
pre, code, pre > code
|
|
5105
|
+
/* 7. \u4EE3\u7801\u5757\u4E0E\u5FBD\u6807\u81EA\u9002\u5E94 */
|
|
5106
|
+
pre, code, pre > code {
|
|
4962
5107
|
max-width: 100% !important;
|
|
4963
5108
|
overflow-x: auto !important;
|
|
4964
5109
|
-webkit-overflow-scrolling: touch !important;
|
|
4965
5110
|
font-size: 12.5px !important;
|
|
4966
5111
|
}
|
|
4967
5112
|
|
|
4968
|
-
|
|
5113
|
+
/* \u72B6\u6001\u5FBD\u6807\u4E0E\u836F\u4E38\u6309\u94AE\u6C38\u4E0D\u6298\u5B57 */
|
|
4969
5114
|
span[style*="border-radius: 999"],
|
|
4970
5115
|
span[style*="border-radius:999"] {
|
|
4971
5116
|
white-space: nowrap !important;
|
|
@@ -5181,10 +5326,82 @@ function createUpstreamBridge(ctx) {
|
|
|
5181
5326
|
}
|
|
5182
5327
|
};
|
|
5183
5328
|
}
|
|
5329
|
+
function setupPanelAwareness(ctx) {
|
|
5330
|
+
if (typeof document === "undefined") return () => {
|
|
5331
|
+
};
|
|
5332
|
+
const PANEL_SELECTORS = [
|
|
5333
|
+
".dshc-center-backdrop",
|
|
5334
|
+
// dsh-chanhub 渠道中心
|
|
5335
|
+
"[data-dsh-panel-host]",
|
|
5336
|
+
// dsh-better-sidebar(注意:常驻 DOM,需判可见)
|
|
5337
|
+
"[data-dsh-better-sidebar]"
|
|
5338
|
+
];
|
|
5339
|
+
const isPanelOpen = () => PANEL_SELECTORS.some((sel) => {
|
|
5340
|
+
const el = document.querySelector(sel);
|
|
5341
|
+
if (!el) return false;
|
|
5342
|
+
const cs = getComputedStyle(el);
|
|
5343
|
+
if (cs.display === "none" || cs.visibility === "hidden") return false;
|
|
5344
|
+
const r = el.getBoundingClientRect();
|
|
5345
|
+
return r.width > 0 && r.height > 0;
|
|
5346
|
+
});
|
|
5347
|
+
const sync = () => {
|
|
5348
|
+
const open = isPanelOpen();
|
|
5349
|
+
if (document.body.classList.contains("dsh-panel-open") !== open) {
|
|
5350
|
+
document.body.classList.toggle("dsh-panel-open", open);
|
|
5351
|
+
}
|
|
5352
|
+
};
|
|
5353
|
+
sync();
|
|
5354
|
+
const observer = new MutationObserver(sync);
|
|
5355
|
+
observer.observe(document.body, { childList: true });
|
|
5356
|
+
const timer = setInterval(sync, 1e3);
|
|
5357
|
+
const dispose = () => {
|
|
5358
|
+
observer.disconnect();
|
|
5359
|
+
clearInterval(timer);
|
|
5360
|
+
};
|
|
5361
|
+
ctx?.effect?.(() => dispose);
|
|
5362
|
+
return dispose;
|
|
5363
|
+
}
|
|
5184
5364
|
function setupMobileExperience(rpcCall, ctx) {
|
|
5185
5365
|
if (typeof document === "undefined" || typeof window === "undefined") return;
|
|
5186
|
-
|
|
5366
|
+
const MOBILE_FLAG_KEY = "dsh-bridge-gateway:mobile";
|
|
5367
|
+
const flag = new URLSearchParams(window.location.search).get("dsh-mobile");
|
|
5368
|
+
if (flag !== null) {
|
|
5369
|
+
try {
|
|
5370
|
+
window.localStorage.setItem(MOBILE_FLAG_KEY, flag);
|
|
5371
|
+
} catch {
|
|
5372
|
+
}
|
|
5373
|
+
}
|
|
5374
|
+
let mobileFlag = "on";
|
|
5375
|
+
try {
|
|
5376
|
+
mobileFlag = window.localStorage.getItem(MOBILE_FLAG_KEY) || "on";
|
|
5377
|
+
} catch {
|
|
5378
|
+
}
|
|
5379
|
+
document.documentElement.dataset.dshMobile = mobileFlag;
|
|
5380
|
+
const diagOn = new URLSearchParams(window.location.search).get("dsh-diag") === "1";
|
|
5381
|
+
if (diagOn) window.setTimeout(setupMobileDiag, 1500);
|
|
5382
|
+
const flagSet = new Set(String(mobileFlag).split(",").map((x) => x.trim()).filter(Boolean));
|
|
5383
|
+
const disabledSuspects = new Set(
|
|
5384
|
+
[...flagSet].filter((f) => f.startsWith("no-")).map((f) => f.slice(3))
|
|
5385
|
+
);
|
|
5386
|
+
if (disabledSuspects.has("frame")) {
|
|
5387
|
+
for (const k of ["frameLayout", "frameSize", "frameOverflow"]) disabledSuspects.add(k);
|
|
5388
|
+
}
|
|
5389
|
+
const withCss = !flagSet.has("off") && !flagSet.has("no-css");
|
|
5390
|
+
const withJs = !flagSet.has("off") && !flagSet.has("no-js");
|
|
5391
|
+
const withNew = withCss && !flagSet.has("no-new");
|
|
5392
|
+
const MOBILE_NO_OBSERVER = flagSet.has("no-observer");
|
|
5393
|
+
if (!withCss && !withJs) {
|
|
5394
|
+
if (diagOn) window.setTimeout(setupMobileDiag, 1500);
|
|
5395
|
+
return;
|
|
5396
|
+
}
|
|
5397
|
+
if (withCss) {
|
|
5398
|
+
injectMobileStyles();
|
|
5399
|
+
injectSuspectStyles(disabledSuspects);
|
|
5400
|
+
}
|
|
5401
|
+
if (withNew) injectNewMobileStyles();
|
|
5402
|
+
if (!withJs) return;
|
|
5187
5403
|
const U = createUpstreamBridge(ctx);
|
|
5404
|
+
setupPanelAwareness(ctx);
|
|
5188
5405
|
let header = document.querySelector(".dsh-mobile-app-header");
|
|
5189
5406
|
let titleEl = document.querySelector(".dsh-mobile-header-title");
|
|
5190
5407
|
if (!header) {
|
|
@@ -5229,17 +5446,39 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
5229
5446
|
header.appendChild(rightBtn);
|
|
5230
5447
|
document.body.appendChild(header);
|
|
5231
5448
|
}
|
|
5449
|
+
if (header && !header.dataset.dshVisibilityBound) {
|
|
5450
|
+
header.dataset.dshVisibilityBound = "1";
|
|
5451
|
+
header.style.display = "none";
|
|
5452
|
+
try {
|
|
5453
|
+
const mq = window.matchMedia("(max-width: 768px)");
|
|
5454
|
+
const syncHeaderVisibility = () => {
|
|
5455
|
+
header.style.display = mq.matches ? "" : "none";
|
|
5456
|
+
};
|
|
5457
|
+
syncHeaderVisibility();
|
|
5458
|
+
if (typeof mq.addEventListener === "function") mq.addEventListener("change", syncHeaderVisibility);
|
|
5459
|
+
else if (typeof mq.addListener === "function") mq.addListener(syncHeaderVisibility);
|
|
5460
|
+
} catch {
|
|
5461
|
+
}
|
|
5462
|
+
}
|
|
5463
|
+
const pickCurrentSession = (snap) => {
|
|
5464
|
+
const list = snap?.byId ? Object.values(snap.byId) : [];
|
|
5465
|
+
if (!list.length) return null;
|
|
5466
|
+
const retained = list.find((x) => (x?.retainedBy?.mainView ?? 0) > 0);
|
|
5467
|
+
if (retained) return retained;
|
|
5468
|
+
return list.find((x) => !x?.blank) || null;
|
|
5469
|
+
};
|
|
5232
5470
|
const syncMobileTitle = () => {
|
|
5233
5471
|
if (!titleEl) titleEl = document.querySelector(".dsh-mobile-header-title");
|
|
5234
5472
|
if (!titleEl) return;
|
|
5235
5473
|
const snap = ctx?.sessions?.list?.getSnapshot?.();
|
|
5236
5474
|
if (!snap) return;
|
|
5237
|
-
const cur = snap
|
|
5475
|
+
const cur = pickCurrentSession(snap);
|
|
5238
5476
|
if (!cur || cur.blank) {
|
|
5239
5477
|
titleEl.innerText = "\u65B0\u4F1A\u8BDD";
|
|
5240
5478
|
} else {
|
|
5241
5479
|
titleEl.innerText = cur.displayTitle || cur.title || "\u4F1A\u8BDD";
|
|
5242
5480
|
}
|
|
5481
|
+
titleEl.title = titleEl.innerText;
|
|
5243
5482
|
};
|
|
5244
5483
|
syncMobileTitle();
|
|
5245
5484
|
if (typeof ctx?.sessions?.list?.subscribe === "function") {
|
|
@@ -5279,9 +5518,21 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
5279
5518
|
}
|
|
5280
5519
|
});
|
|
5281
5520
|
};
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5521
|
+
let panelCloseRaf = 0;
|
|
5522
|
+
const schedulePanelCloseButton = () => {
|
|
5523
|
+
if (panelCloseRaf) return;
|
|
5524
|
+
panelCloseRaf = window.requestAnimationFrame(() => {
|
|
5525
|
+
panelCloseRaf = 0;
|
|
5526
|
+
ensurePanelCloseButton();
|
|
5527
|
+
});
|
|
5528
|
+
};
|
|
5529
|
+
if (MOBILE_NO_OBSERVER) {
|
|
5530
|
+
document.documentElement.dataset.dshMobileObserver = "off";
|
|
5531
|
+
} else {
|
|
5532
|
+
const panelObserver = new MutationObserver(schedulePanelCloseButton);
|
|
5533
|
+
panelObserver.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ["class"] });
|
|
5534
|
+
}
|
|
5535
|
+
window.addEventListener("resize", schedulePanelCloseButton);
|
|
5285
5536
|
const mobileTabState = { btn: null, dropdown: null };
|
|
5286
5537
|
const nativeTabs = () => [...document.querySelectorAll('[role="tablist"] [role="tab"]')];
|
|
5287
5538
|
const closeTabDropdown = () => {
|
|
@@ -5290,6 +5541,14 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
5290
5541
|
mobileTabState.dropdown = null;
|
|
5291
5542
|
}
|
|
5292
5543
|
};
|
|
5544
|
+
const positionTabDropdown = () => {
|
|
5545
|
+
const dd = mobileTabState.dropdown;
|
|
5546
|
+
const btn = mobileTabState.btn;
|
|
5547
|
+
if (!dd || !btn || !btn.isConnected) return;
|
|
5548
|
+
const r = btn.getBoundingClientRect();
|
|
5549
|
+
dd.style.top = Math.round(r.bottom + 6) + "px";
|
|
5550
|
+
dd.style.left = Math.round(r.left) + "px";
|
|
5551
|
+
};
|
|
5293
5552
|
const renderTabDropdown = () => {
|
|
5294
5553
|
closeTabDropdown();
|
|
5295
5554
|
if (!mobileTabState.btn) return;
|
|
@@ -5326,8 +5585,9 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
5326
5585
|
};
|
|
5327
5586
|
dropdown.appendChild(option);
|
|
5328
5587
|
});
|
|
5329
|
-
|
|
5588
|
+
document.body.appendChild(dropdown);
|
|
5330
5589
|
mobileTabState.dropdown = dropdown;
|
|
5590
|
+
positionTabDropdown();
|
|
5331
5591
|
};
|
|
5332
5592
|
const syncTabButtonLabel = () => {
|
|
5333
5593
|
if (!mobileTabState.btn || !mobileTabState.btn.isConnected) return;
|
|
@@ -5390,6 +5650,7 @@ function setupMobileExperience(rpcCall, ctx) {
|
|
|
5390
5650
|
titleExtrasObserver.observe(document.body, { childList: true, subtree: true });
|
|
5391
5651
|
window.addEventListener("resize", () => {
|
|
5392
5652
|
if (window.innerWidth > 768) closeTabDropdown();
|
|
5653
|
+
else positionTabDropdown();
|
|
5393
5654
|
});
|
|
5394
5655
|
document.addEventListener(
|
|
5395
5656
|
"click",
|