@artenx/dshb 0.1.26 → 0.1.28
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/lib/client.js +116 -156
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -510,7 +510,8 @@ window.__ModuleLoader__.load({
|
|
|
510
510
|
const dialogStyle = {
|
|
511
511
|
width: "min(92vw, 560px)",
|
|
512
512
|
maxWidth: "100%",
|
|
513
|
-
maxHeight: "
|
|
513
|
+
maxHeight: "80dvh",
|
|
514
|
+
paddingBottom: "max(env(safe-area-inset-bottom), 12px)",
|
|
514
515
|
overflow: "auto",
|
|
515
516
|
overflowX: "hidden",
|
|
516
517
|
background: "var(--dsw-alias-bg-layer-1)",
|
|
@@ -952,7 +953,8 @@ window.__ModuleLoader__.load({
|
|
|
952
953
|
style: {
|
|
953
954
|
width: "min(92vw, 600px)",
|
|
954
955
|
maxWidth: "100%",
|
|
955
|
-
maxHeight: "
|
|
956
|
+
maxHeight: "85dvh",
|
|
957
|
+
paddingBottom: "max(env(safe-area-inset-bottom), 12px)",
|
|
956
958
|
overflow: "auto",
|
|
957
959
|
overflowX: "hidden",
|
|
958
960
|
background: "var(--dsw-alias-bg-layer-1)",
|
|
@@ -1129,7 +1131,7 @@ window.__ModuleLoader__.load({
|
|
|
1129
1131
|
/* footer 容器各项间距 16px 偏松 */
|
|
1130
1132
|
[data-phase] [class*="_root"][class*="osXY9a"] { gap: 8px !important; }
|
|
1131
1133
|
/* footer 统计行窄屏可横向滑动看全,不溢出页面 */
|
|
1132
|
-
[data-phase] [class*="_actions"] { max-width: 100% !important; overflow-x: auto !important; scrollbar-width: none; touch-action: pan-x pan-y !important; }
|
|
1134
|
+
[data-phase] [class*="_actions"] { max-width: 100% !important; overflow-x: auto !important; scrollbar-width: none; touch-action: pan-x pan-y pinch-zoom !important; }
|
|
1133
1135
|
[data-phase] [class*="_actions"]::-webkit-scrollbar { display: none; }
|
|
1134
1136
|
|
|
1135
1137
|
/* 模型切换菜单:名称完整展示,长名称在菜单项内换行。 */
|
|
@@ -1156,19 +1158,8 @@ window.__ModuleLoader__.load({
|
|
|
1156
1158
|
overflow: visible !important;
|
|
1157
1159
|
}
|
|
1158
1160
|
|
|
1159
|
-
/*
|
|
1160
|
-
|
|
1161
|
-
仍从触发按钮左缘向右展开、宽度收进视口)。 */
|
|
1162
|
-
[class*="7KE1Ra_menu"],
|
|
1163
|
-
[class*="_menu"]:has([class*="modelName"]) {
|
|
1164
|
-
left: 0 !important;
|
|
1165
|
-
right: auto !important;
|
|
1166
|
-
width: calc(100vw - 32px) !important;
|
|
1167
|
-
min-width: 0 !important;
|
|
1168
|
-
max-width: calc(100vw - 32px) !important;
|
|
1169
|
-
overflow-y: auto !important;
|
|
1170
|
-
max-height: calc(100vh - 120px) !important;
|
|
1171
|
-
}
|
|
1161
|
+
/* 菜单定位完全交还上游(0.2.1-rc.2 起菜单 position:fixed 且自带视口钳制;
|
|
1162
|
+
此前插件的 left/width !important 兜底会覆盖上游 place() 的计算结果)。 */
|
|
1172
1163
|
|
|
1173
1164
|
/* 工具调用执行结果/代码/JSON:窄屏可横向滑动。details 抽屉宽 min(92%,420px)
|
|
1174
1165
|
较窄,命令行输出/JSON 长行溢出被外层 overflow:hidden 裁剪看不到。命令行输出
|
|
@@ -1183,7 +1174,7 @@ window.__ModuleLoader__.load({
|
|
|
1183
1174
|
overflow-x: auto !important;
|
|
1184
1175
|
-webkit-overflow-scrolling: touch;
|
|
1185
1176
|
scrollbar-width: none;
|
|
1186
|
-
touch-action: pan-x pan-y !important;
|
|
1177
|
+
touch-action: pan-x pan-y pinch-zoom !important;
|
|
1187
1178
|
}
|
|
1188
1179
|
[data-phase] [class*="resultBlockText"]::-webkit-scrollbar,
|
|
1189
1180
|
[data-phase] [class*="payload"]::-webkit-scrollbar,
|
|
@@ -1201,7 +1192,7 @@ window.__ModuleLoader__.load({
|
|
|
1201
1192
|
overflow-x: auto !important;
|
|
1202
1193
|
-webkit-overflow-scrolling: touch;
|
|
1203
1194
|
scrollbar-width: none;
|
|
1204
|
-
touch-action: pan-x pan-y !important;
|
|
1195
|
+
touch-action: pan-x pan-y pinch-zoom !important;
|
|
1205
1196
|
}
|
|
1206
1197
|
[data-phase] [class*="jsonPayload"]::-webkit-scrollbar,
|
|
1207
1198
|
[data-phase] [class*="jsonPreview"]::-webkit-scrollbar,
|
|
@@ -1224,7 +1215,7 @@ window.__ModuleLoader__.load({
|
|
|
1224
1215
|
overflow-x: auto !important;
|
|
1225
1216
|
-webkit-overflow-scrolling: touch;
|
|
1226
1217
|
scrollbar-width: none;
|
|
1227
|
-
touch-action: pan-x pan-y !important;
|
|
1218
|
+
touch-action: pan-x pan-y pinch-zoom !important;
|
|
1228
1219
|
}
|
|
1229
1220
|
/* xterm uses a transparent helper textarea for all terminal input. Keep it
|
|
1230
1221
|
focusable and non-zero-sized so mobile browsers can present their keyboard. */
|
|
@@ -1251,7 +1242,7 @@ window.__ModuleLoader__.load({
|
|
|
1251
1242
|
max-width: 100% !important;
|
|
1252
1243
|
overflow-x: auto !important;
|
|
1253
1244
|
overscroll-behavior-x: contain;
|
|
1254
|
-
touch-action: pan-x pan-y !important;
|
|
1245
|
+
touch-action: pan-x pan-y pinch-zoom !important;
|
|
1255
1246
|
}
|
|
1256
1247
|
[data-phase] [class*="_prompt_1gdtu_"],
|
|
1257
1248
|
[data-phase] [class*="_promptLine_1gdtu_"],
|
|
@@ -1273,7 +1264,7 @@ window.__ModuleLoader__.load({
|
|
|
1273
1264
|
overflow-x: auto !important;
|
|
1274
1265
|
-webkit-overflow-scrolling: touch;
|
|
1275
1266
|
scrollbar-width: none;
|
|
1276
|
-
touch-action: pan-x pan-y !important;
|
|
1267
|
+
touch-action: pan-x pan-y pinch-zoom !important;
|
|
1277
1268
|
}
|
|
1278
1269
|
[data-phase] [class*="_output_1gdtu_"]::-webkit-scrollbar { display: none !important; }
|
|
1279
1270
|
[data-phase] [class*="_line_1gdtu_"] {
|
|
@@ -1286,7 +1277,7 @@ window.__ModuleLoader__.load({
|
|
|
1286
1277
|
[data-phase] [class*="_copyButton_"] { touch-action: manipulation !important; }
|
|
1287
1278
|
[data-phase] [class*="_copyAnchor_"],
|
|
1288
1279
|
[data-phase] [class*="_body_1ye18_"],
|
|
1289
|
-
[data-phase] [class*="_root_4qrvp_"] { touch-action: pan-x pan-y !important; }
|
|
1280
|
+
[data-phase] [class*="_root_4qrvp_"] { touch-action: pan-x pan-y pinch-zoom !important; }
|
|
1290
1281
|
|
|
1291
1282
|
/* 上下文用量弹窗(ContextMeter .JObwrW_panel):上游 dsh-client-ui-trajectory 的
|
|
1292
1283
|
[class*="panel"] 全局规则给它加了 max-width:100%!important,命中本弹窗,使宽度
|
|
@@ -1340,10 +1331,19 @@ window.__ModuleLoader__.load({
|
|
|
1340
1331
|
z-index: 2 !important;
|
|
1341
1332
|
display: inline-flex !important;
|
|
1342
1333
|
align-items: center; justify-content: center;
|
|
1343
|
-
width:
|
|
1334
|
+
width: 32px; height: 32px;
|
|
1344
1335
|
padding: 0; border: none; background: none; cursor: pointer; color: inherit;
|
|
1345
1336
|
-webkit-tap-highlight-color: transparent;
|
|
1346
1337
|
}
|
|
1338
|
+
/* 触控命中区扩展:视觉尺寸不变,可点区域扩到 ~44px(Apple HIG 建议值) */
|
|
1339
|
+
[${FRAME_ATTR}="toggle"]::after,
|
|
1340
|
+
[${FRAME_ATTR}="fab"]::after,
|
|
1341
|
+
[class*="_iconButton"]::after {
|
|
1342
|
+
content: "";
|
|
1343
|
+
position: absolute;
|
|
1344
|
+
inset: -7px;
|
|
1345
|
+
}
|
|
1346
|
+
[class*="_iconButton"] { position: relative !important; }
|
|
1347
1347
|
|
|
1348
1348
|
/* 首页/hero(无活跃会话,session header 不存在)的抽屉切换 FAB:
|
|
1349
1349
|
浮在顶部相机带下方,避免与 hero 头部内容重叠 */
|
|
@@ -1354,7 +1354,7 @@ window.__ModuleLoader__.load({
|
|
|
1354
1354
|
z-index: 21 !important;
|
|
1355
1355
|
display: inline-flex !important;
|
|
1356
1356
|
align-items: center; justify-content: center;
|
|
1357
|
-
width:
|
|
1357
|
+
width: 44px; height: 44px;
|
|
1358
1358
|
padding: 0;
|
|
1359
1359
|
border: 1px solid var(--dsw-alias-border-l1, rgba(0, 0, 0, .12)) !important;
|
|
1360
1360
|
border-radius: 50% !important;
|
|
@@ -1364,6 +1364,30 @@ window.__ModuleLoader__.load({
|
|
|
1364
1364
|
box-shadow: 0 2px 12px rgba(0, 0, 0, .18) !important;
|
|
1365
1365
|
-webkit-tap-highlight-color: transparent;
|
|
1366
1366
|
}
|
|
1367
|
+
|
|
1368
|
+
/* iOS 对 computed font-size <16px 的可编辑元素聚焦时自动放大视口;
|
|
1369
|
+
表单与 composer 提到 16px(消息正文不受影响),聚焦后页面不再错位。 */
|
|
1370
|
+
input, textarea, select, [contenteditable="true"] {
|
|
1371
|
+
font-size: max(16px, 1em) !important;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
/* 底部安全区(iPhone home 条):viewport-fit=cover 后浏览器 UI 退出底部,
|
|
1375
|
+
home 指示条叠在 composer / 抽屉 / 设置 sheet 上,遮挡发送按钮与会话列表末项。 */
|
|
1376
|
+
[class*="composerSeat"], [data-composer-seat] {
|
|
1377
|
+
padding-bottom: max(env(safe-area-inset-bottom, 0px), 4px) !important;
|
|
1378
|
+
}
|
|
1379
|
+
[${FRAME_ATTR}="frame"] > :first-child {
|
|
1380
|
+
padding-bottom: env(safe-area-inset-bottom, 0px) !important;
|
|
1381
|
+
}
|
|
1382
|
+
[aria-modal="true"]:has(> :first-child > :last-child > button):not(:has([role="navigation"])):not(:has([class*="ZuhsRW"])) {
|
|
1383
|
+
max-height: calc(100dvh - 24px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)) !important;
|
|
1384
|
+
}
|
|
1385
|
+
[aria-modal="true"]:has(> :first-child > :last-child > button):not(:has([role="navigation"])):not(:has([class*="ZuhsRW"])) > :last-child > :last-child {
|
|
1386
|
+
padding-bottom: max(env(safe-area-inset-bottom, 0px), 24px) !important;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/* 会话行触控高度 */
|
|
1390
|
+
[class*="sessionRow"] { min-height: 44px !important; }
|
|
1367
1391
|
}
|
|
1368
1392
|
|
|
1369
1393
|
/* 宽屏 / 鼠标指针:隐藏切换按钮 */
|
|
@@ -1385,7 +1409,7 @@ window.__ModuleLoader__.load({
|
|
|
1385
1409
|
if (viewport === null) return () => {};
|
|
1386
1410
|
const original = viewport.content;
|
|
1387
1411
|
const sync = () => {
|
|
1388
|
-
viewport.content = narrow.matches ? "width=device-width, initial-scale=1, viewport-fit=cover" : original;
|
|
1412
|
+
viewport.content = narrow.matches ? "width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content" : original;
|
|
1389
1413
|
};
|
|
1390
1414
|
sync();
|
|
1391
1415
|
narrow.addEventListener("change", sync);
|
|
@@ -1560,69 +1584,11 @@ window.__ModuleLoader__.load({
|
|
|
1560
1584
|
};
|
|
1561
1585
|
}, "dshb-mobile: stats line");
|
|
1562
1586
|
}
|
|
1563
|
-
/** 浮层 fixed 定位需管理的内联样式键,清理时逐一移除以交还上游 CSS。 */
|
|
1564
|
-
const SHEET_PROPS = [
|
|
1565
|
-
"position",
|
|
1566
|
-
"width",
|
|
1567
|
-
"left",
|
|
1568
|
-
"right",
|
|
1569
|
-
"top",
|
|
1570
|
-
"bottom",
|
|
1571
|
-
"min-width",
|
|
1572
|
-
"max-width",
|
|
1573
|
-
"max-height",
|
|
1574
|
-
"overflow-y",
|
|
1575
|
-
"box-sizing"
|
|
1576
|
-
];
|
|
1577
1587
|
/** 幂等写入 important 内联样式:值未变化时跳过,避免 MutationObserver(attributes) 自触发循环。 */
|
|
1578
1588
|
function setImportantIfChanged(el, prop, value) {
|
|
1579
1589
|
if (el.style.getPropertyValue(prop) === value && el.style.getPropertyPriority(prop) === "important") return;
|
|
1580
1590
|
el.style.setProperty(prop, value, "important");
|
|
1581
1591
|
}
|
|
1582
|
-
/** 当前视口下的可视区域(手机键盘弹出时 visualViewport 与布局视口错位)。 */
|
|
1583
|
-
function visibleViewport() {
|
|
1584
|
-
const vv = window.visualViewport;
|
|
1585
|
-
if (vv) return {
|
|
1586
|
-
vw: vv.width,
|
|
1587
|
-
vh: vv.offsetTop + vv.height,
|
|
1588
|
-
top: vv.offsetTop
|
|
1589
|
-
};
|
|
1590
|
-
return {
|
|
1591
|
-
vw: window.innerWidth,
|
|
1592
|
-
vh: window.innerHeight,
|
|
1593
|
-
top: 0
|
|
1594
|
-
};
|
|
1595
|
-
}
|
|
1596
|
-
/** Keep the model menu anchored to its trigger while fitting it in the viewport. */
|
|
1597
|
-
function positionAnchoredMenu(el, triggerRect, maxWidth, maxHeight) {
|
|
1598
|
-
const margin = 8;
|
|
1599
|
-
const { vw, vh } = visibleViewport();
|
|
1600
|
-
setImportantIfChanged(el, "position", "fixed");
|
|
1601
|
-
setImportantIfChanged(el, "box-sizing", "border-box");
|
|
1602
|
-
setImportantIfChanged(el, "left", "0");
|
|
1603
|
-
setImportantIfChanged(el, "right", "auto");
|
|
1604
|
-
setImportantIfChanged(el, "top", "0");
|
|
1605
|
-
setImportantIfChanged(el, "bottom", "auto");
|
|
1606
|
-
setImportantIfChanged(el, "min-width", "0");
|
|
1607
|
-
setImportantIfChanged(el, "max-width", `${Math.max(0, Math.min(maxWidth, vw - 16))}px`);
|
|
1608
|
-
setImportantIfChanged(el, "max-height", `${Math.max(0, Math.min(maxHeight, vh - 16))}px`);
|
|
1609
|
-
setImportantIfChanged(el, "overflow-y", "auto");
|
|
1610
|
-
let width = el.offsetWidth;
|
|
1611
|
-
let height = el.offsetHeight;
|
|
1612
|
-
const { top: viewportTop } = visibleViewport();
|
|
1613
|
-
const spaceAbove = Math.max(0, triggerRect.top - viewportTop - 16);
|
|
1614
|
-
const spaceBelow = Math.max(0, vh - triggerRect.bottom - 16);
|
|
1615
|
-
const expandUp = height <= spaceAbove || spaceAbove >= spaceBelow;
|
|
1616
|
-
const available = expandUp ? spaceAbove : spaceBelow;
|
|
1617
|
-
if (height > available) {
|
|
1618
|
-
setImportantIfChanged(el, "max-height", `${Math.max(0, available - margin)}px`);
|
|
1619
|
-
height = el.offsetHeight;
|
|
1620
|
-
width = el.offsetWidth;
|
|
1621
|
-
}
|
|
1622
|
-
const top = expandUp ? triggerRect.top - margin - height : triggerRect.bottom + margin;
|
|
1623
|
-
setImportantIfChanged(el, "left", `${Math.max(margin, Math.min(triggerRect.right - width, vw - width - margin))}px`);
|
|
1624
|
-
setImportantIfChanged(el, "top", `${Math.max(viewportTop + margin, Math.min(top, vh - height - margin))}px`);
|
|
1625
|
-
}
|
|
1626
1592
|
/**
|
|
1627
1593
|
* 模型名多为纯连字符词(DeepSeek-V4-Flash-Vision-Exp);white-space:normal 下
|
|
1628
1594
|
* 每个 "-" 都是软断点,名字一旦超列宽就在第一个连字符处断行("换行太早")。
|
|
@@ -1674,18 +1640,13 @@ window.__ModuleLoader__.load({
|
|
|
1674
1640
|
n.style.removeProperty("font-size");
|
|
1675
1641
|
}
|
|
1676
1642
|
}
|
|
1677
|
-
/** 清除 anchored menu 写入的内联样式,交还上游 CSS。 */
|
|
1678
|
-
function clearFixedSheet(el) {
|
|
1679
|
-
if (el === null || el === void 0) return;
|
|
1680
|
-
for (const key of SHEET_PROPS) el.style.removeProperty(key);
|
|
1681
|
-
}
|
|
1682
1643
|
/**
|
|
1683
|
-
* 模型选择弹窗(dsh-client-ui-model-selection
|
|
1684
|
-
*
|
|
1685
|
-
*
|
|
1686
|
-
*
|
|
1687
|
-
*
|
|
1688
|
-
*
|
|
1644
|
+
* 模型选择弹窗(dsh-client-ui-model-selection):上游 0.2.1-rc.2 起菜单已是
|
|
1645
|
+
* `position:fixed` 并自带 place() 视口钳制定位(portal 到 body,ResizeObserver
|
|
1646
|
+
* 跟随尺寸变化)。插件不再接管定位——此前写入的 fixed/left/top 与上游 menuPos
|
|
1647
|
+
* 内联样式互相拉扯;且对自动聚焦搜索框的 blur 拦截会触发上游 onBlur 的
|
|
1648
|
+
* close()(焦点移出菜单即关闭),手机上表现为菜单刚打开就被关掉("弹不出来")。
|
|
1649
|
+
* 这里只保留窄屏下的视觉适配:模型名不换行连字符 + 按最宽名字缩放字号。
|
|
1689
1650
|
*/
|
|
1690
1651
|
function installModelMenuPosition(ctx) {
|
|
1691
1652
|
ctx.effect(() => {
|
|
@@ -1699,45 +1660,27 @@ window.__ModuleLoader__.load({
|
|
|
1699
1660
|
fallbackLast = now;
|
|
1700
1661
|
return Array.from(document.querySelectorAll("[class*=\"_menu\"]")).filter((el) => el.querySelector("[class*=\"cellLabel\"], [class*=\"modelName\"]") !== null);
|
|
1701
1662
|
};
|
|
1702
|
-
const findTrigger = (menu) => {
|
|
1703
|
-
if (menu.id) {
|
|
1704
|
-
const controlled = Array.from(document.querySelectorAll("[aria-controls]")).find((el) => el.getAttribute("aria-controls") === menu.id);
|
|
1705
|
-
if (controlled) return controlled;
|
|
1706
|
-
}
|
|
1707
|
-
return document.querySelector("[class*=\"7KE1Ra_trigger\"][aria-expanded=\"true\"]");
|
|
1708
|
-
};
|
|
1709
1663
|
let fittedVw = 0;
|
|
1710
1664
|
let fittedSig = -1;
|
|
1711
1665
|
let fittedMenus = [];
|
|
1712
|
-
let positionedMenus = [];
|
|
1713
1666
|
const sync = () => {
|
|
1714
|
-
const menus = findMenus();
|
|
1715
1667
|
let vw = 0;
|
|
1716
1668
|
let sig = 0;
|
|
1717
1669
|
const modelMenus = [];
|
|
1718
|
-
const
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
if (menu.querySelector("[class*=\"modelName\"]")) {
|
|
1727
|
-
modelMenus.push(menu);
|
|
1728
|
-
if (narrow.matches) {
|
|
1729
|
-
applyNonBreakingHyphens(menu);
|
|
1730
|
-
vw = window.innerWidth;
|
|
1731
|
-
for (const n of menu.querySelectorAll("[class*=\"modelName\"]")) sig += n.textContent?.length ?? 0;
|
|
1732
|
-
}
|
|
1670
|
+
for (const menu of findMenus()) {
|
|
1671
|
+
if (!menu.querySelector("[class*=\"modelName\"]")) continue;
|
|
1672
|
+
if (menu.getBoundingClientRect().width === 0) continue;
|
|
1673
|
+
modelMenus.push(menu);
|
|
1674
|
+
if (narrow.matches) {
|
|
1675
|
+
applyNonBreakingHyphens(menu);
|
|
1676
|
+
vw = window.innerWidth;
|
|
1677
|
+
for (const n of menu.querySelectorAll("[class*=\"modelName\"]")) sig += n.textContent?.length ?? 0;
|
|
1733
1678
|
}
|
|
1734
1679
|
}
|
|
1735
|
-
for (const previous of
|
|
1736
|
-
if (
|
|
1737
|
-
clearFixedSheet(previous);
|
|
1680
|
+
for (const previous of fittedMenus) {
|
|
1681
|
+
if (modelMenus.includes(previous)) continue;
|
|
1738
1682
|
clearModelNameFit(previous);
|
|
1739
1683
|
}
|
|
1740
|
-
positionedMenus = visibleMenus;
|
|
1741
1684
|
if (!narrow.matches) {
|
|
1742
1685
|
for (const menu of modelMenus) clearModelNameFit(menu);
|
|
1743
1686
|
fittedVw = 0;
|
|
@@ -1757,42 +1700,14 @@ window.__ModuleLoader__.load({
|
|
|
1757
1700
|
const mo = new MutationObserver(() => requestAnimationFrame(sync));
|
|
1758
1701
|
mo.observe(document.documentElement, {
|
|
1759
1702
|
childList: true,
|
|
1760
|
-
subtree: true
|
|
1761
|
-
attributes: true,
|
|
1762
|
-
attributeFilter: ["style"]
|
|
1703
|
+
subtree: true
|
|
1763
1704
|
});
|
|
1764
1705
|
narrow.addEventListener("change", sync);
|
|
1765
1706
|
window.addEventListener("resize", sync);
|
|
1766
|
-
window.addEventListener("scroll", sync, true);
|
|
1767
|
-
window.visualViewport?.addEventListener("resize", sync);
|
|
1768
|
-
window.visualViewport?.addEventListener("scroll", sync);
|
|
1769
|
-
let lastPointerTarget = null;
|
|
1770
|
-
const keyboardLikelyOpen = () => {
|
|
1771
|
-
const vv = window.visualViewport;
|
|
1772
|
-
if (!vv) return false;
|
|
1773
|
-
return window.innerHeight - vv.height > 150;
|
|
1774
|
-
};
|
|
1775
|
-
const onPointerDown = (event) => {
|
|
1776
|
-
lastPointerTarget = event.target instanceof Element ? event.target : null;
|
|
1777
|
-
};
|
|
1778
|
-
const onFocusIn = (event) => {
|
|
1779
|
-
if (!narrow.matches || !(event.target instanceof Element) || keyboardLikelyOpen()) return;
|
|
1780
|
-
const input = event.target.closest("input");
|
|
1781
|
-
if (!input || input.closest("[class*=\"7KE1Ra_menu\"], [class*=\"_menu\"]") === null) return;
|
|
1782
|
-
if (lastPointerTarget !== null && (lastPointerTarget === input || input.contains(lastPointerTarget))) return;
|
|
1783
|
-
input.blur();
|
|
1784
|
-
};
|
|
1785
|
-
document.addEventListener("pointerdown", onPointerDown, true);
|
|
1786
|
-
document.addEventListener("focusin", onFocusIn, true);
|
|
1787
1707
|
return () => {
|
|
1788
1708
|
mo.disconnect();
|
|
1789
1709
|
narrow.removeEventListener("change", sync);
|
|
1790
1710
|
window.removeEventListener("resize", sync);
|
|
1791
|
-
window.removeEventListener("scroll", sync, true);
|
|
1792
|
-
window.visualViewport?.removeEventListener("resize", sync);
|
|
1793
|
-
window.visualViewport?.removeEventListener("scroll", sync);
|
|
1794
|
-
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
1795
|
-
document.removeEventListener("focusin", onFocusIn, true);
|
|
1796
1711
|
};
|
|
1797
1712
|
}, "dshb-mobile: model menu position");
|
|
1798
1713
|
}
|
|
@@ -1858,6 +1773,47 @@ window.__ModuleLoader__.load({
|
|
|
1858
1773
|
return () => document.removeEventListener("pointerdown", focusInput, true);
|
|
1859
1774
|
}, "dshb-mobile: terminal input focus");
|
|
1860
1775
|
}
|
|
1776
|
+
/**
|
|
1777
|
+
* iOS 键盘只缩小 visualViewport,布局视口不动,sticky 在滚动容器底部的
|
|
1778
|
+
* composer 会整个留在键盘后面(发送按钮不可达、最新消息被遮)。监听
|
|
1779
|
+
* visualViewport,键盘开启时把 composer seat 上移键盘高度并在下一帧把
|
|
1780
|
+
* 会话滚动补到最底;Android 由 meta 的 interactive-widget=resizes-content
|
|
1781
|
+
* 让布局视口直接收缩,无需此补偿。
|
|
1782
|
+
*/
|
|
1783
|
+
function installComposerKeyboardLift(ctx) {
|
|
1784
|
+
ctx.effect(() => {
|
|
1785
|
+
const mobile = window.matchMedia(MOBILE_QUERY);
|
|
1786
|
+
const vv = window.visualViewport;
|
|
1787
|
+
if (!vv) return () => {};
|
|
1788
|
+
let raf = 0;
|
|
1789
|
+
const seat = () => document.querySelector("[class*=\"composerSeat\"]") ?? document.querySelector("[data-composer-seat]");
|
|
1790
|
+
const sync = () => {
|
|
1791
|
+
if (raf !== 0) return;
|
|
1792
|
+
raf = requestAnimationFrame(() => {
|
|
1793
|
+
raf = 0;
|
|
1794
|
+
if (!mobile.matches) return;
|
|
1795
|
+
const el = seat();
|
|
1796
|
+
if (el === null) return;
|
|
1797
|
+
const occluded = window.innerHeight - vv.height - vv.offsetTop;
|
|
1798
|
+
if (occluded > 150) {
|
|
1799
|
+
el.style.transform = `translateY(${-occluded}px)`;
|
|
1800
|
+
const body = document.querySelector("[class*=\"scrollBody\"]");
|
|
1801
|
+
body?.scrollTo({ top: body.scrollHeight });
|
|
1802
|
+
} else if (el.style.transform !== "") el.style.transform = "";
|
|
1803
|
+
});
|
|
1804
|
+
};
|
|
1805
|
+
sync();
|
|
1806
|
+
vv.addEventListener("resize", sync);
|
|
1807
|
+
vv.addEventListener("scroll", sync);
|
|
1808
|
+
return () => {
|
|
1809
|
+
if (raf !== 0) cancelAnimationFrame(raf);
|
|
1810
|
+
const el = seat();
|
|
1811
|
+
if (el !== null) el.style.transform = "";
|
|
1812
|
+
vv.removeEventListener("resize", sync);
|
|
1813
|
+
vv.removeEventListener("scroll", sync);
|
|
1814
|
+
};
|
|
1815
|
+
}, "dshb-mobile: composer keyboard lift");
|
|
1816
|
+
}
|
|
1861
1817
|
/** 目录抽屉切换按钮(仅切换,不含文件浏览/日志导出等功能按钮)。 */
|
|
1862
1818
|
function DrawerToggle({ toggleSidebar }) {
|
|
1863
1819
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -1948,6 +1904,7 @@ window.__ModuleLoader__.load({
|
|
|
1948
1904
|
function installMobile(ctx) {
|
|
1949
1905
|
installStyles(ctx);
|
|
1950
1906
|
installMobileTerminalInputFocus(ctx);
|
|
1907
|
+
installComposerKeyboardLift(ctx);
|
|
1951
1908
|
installViewport(ctx);
|
|
1952
1909
|
installFrameMarker(ctx);
|
|
1953
1910
|
installStatsLine(ctx);
|
|
@@ -1988,7 +1945,7 @@ window.__ModuleLoader__.load({
|
|
|
1988
1945
|
const dialog = document.createElement("div");
|
|
1989
1946
|
dialog.setAttribute("role", "dialog");
|
|
1990
1947
|
dialog.setAttribute("aria-label", `修改 ${workspaceTitle} 的项目指令`);
|
|
1991
|
-
dialog.style.cssText = "box-sizing:border-box;width:min(92vw,600px);max-height:
|
|
1948
|
+
dialog.style.cssText = "box-sizing:border-box;width:min(92vw,600px);max-height:85dvh;overflow:auto;padding:20px;padding-bottom:max(env(safe-area-inset-bottom),20px);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)";
|
|
1992
1949
|
const title = document.createElement("h2");
|
|
1993
1950
|
title.textContent = `项目指令 - ${workspaceTitle}`;
|
|
1994
1951
|
title.style.cssText = "margin:0 0 10px;font-size:16px";
|
|
@@ -3226,9 +3183,9 @@ window.__ModuleLoader__.load({
|
|
|
3226
3183
|
onClick: () => copyText(archive.originSessionId),
|
|
3227
3184
|
style: {
|
|
3228
3185
|
...secondaryBtn,
|
|
3229
|
-
height:
|
|
3230
|
-
padding: "0
|
|
3231
|
-
fontSize:
|
|
3186
|
+
height: 30,
|
|
3187
|
+
padding: "0 10px",
|
|
3188
|
+
fontSize: 11
|
|
3232
3189
|
},
|
|
3233
3190
|
children: "复制 ID"
|
|
3234
3191
|
})]
|
|
@@ -4643,7 +4600,10 @@ window.__ModuleLoader__.load({
|
|
|
4643
4600
|
依赖祖先 overflow:visible 才能展开到输入框之外,禁止给任何中间祖先加裁剪。 */
|
|
4644
4601
|
html, body { overflow-x: hidden !important; max-width: 100vw !important }
|
|
4645
4602
|
* { min-width: 0 !important; }
|
|
4646
|
-
|
|
4603
|
+
/* 表格不设 display:block:上游 markdown 表格已自带滚动容器(tableScroll),
|
|
4604
|
+
display:block 会破坏 caption/sticky 语义且与上游 width:max-content 冲突;
|
|
4605
|
+
这里仅保留溢出约束,宽表由上游 wrapper 横向滚动。 */
|
|
4606
|
+
table { max-width: 100% !important; overflow-x: auto !important; }
|
|
4647
4607
|
img, video, canvas, svg { max-width: 100% !important; height: auto !important }
|
|
4648
4608
|
pre, code { white-space: pre-wrap !important; word-break: break-all !important }
|
|
4649
4609
|
input, select, textarea { max-width: 100% !important; }
|