@artenx/dshb 0.1.25 → 0.1.27
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 +211 -61
- 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
|
/* 模型切换菜单:名称完整展示,长名称在菜单项内换行。 */
|
|
@@ -1183,7 +1185,7 @@ window.__ModuleLoader__.load({
|
|
|
1183
1185
|
overflow-x: auto !important;
|
|
1184
1186
|
-webkit-overflow-scrolling: touch;
|
|
1185
1187
|
scrollbar-width: none;
|
|
1186
|
-
touch-action: pan-x pan-y !important;
|
|
1188
|
+
touch-action: pan-x pan-y pinch-zoom !important;
|
|
1187
1189
|
}
|
|
1188
1190
|
[data-phase] [class*="resultBlockText"]::-webkit-scrollbar,
|
|
1189
1191
|
[data-phase] [class*="payload"]::-webkit-scrollbar,
|
|
@@ -1201,7 +1203,7 @@ window.__ModuleLoader__.load({
|
|
|
1201
1203
|
overflow-x: auto !important;
|
|
1202
1204
|
-webkit-overflow-scrolling: touch;
|
|
1203
1205
|
scrollbar-width: none;
|
|
1204
|
-
touch-action: pan-x pan-y !important;
|
|
1206
|
+
touch-action: pan-x pan-y pinch-zoom !important;
|
|
1205
1207
|
}
|
|
1206
1208
|
[data-phase] [class*="jsonPayload"]::-webkit-scrollbar,
|
|
1207
1209
|
[data-phase] [class*="jsonPreview"]::-webkit-scrollbar,
|
|
@@ -1224,7 +1226,7 @@ window.__ModuleLoader__.load({
|
|
|
1224
1226
|
overflow-x: auto !important;
|
|
1225
1227
|
-webkit-overflow-scrolling: touch;
|
|
1226
1228
|
scrollbar-width: none;
|
|
1227
|
-
touch-action: pan-x pan-y !important;
|
|
1229
|
+
touch-action: pan-x pan-y pinch-zoom !important;
|
|
1228
1230
|
}
|
|
1229
1231
|
/* xterm uses a transparent helper textarea for all terminal input. Keep it
|
|
1230
1232
|
focusable and non-zero-sized so mobile browsers can present their keyboard. */
|
|
@@ -1251,7 +1253,7 @@ window.__ModuleLoader__.load({
|
|
|
1251
1253
|
max-width: 100% !important;
|
|
1252
1254
|
overflow-x: auto !important;
|
|
1253
1255
|
overscroll-behavior-x: contain;
|
|
1254
|
-
touch-action: pan-x pan-y !important;
|
|
1256
|
+
touch-action: pan-x pan-y pinch-zoom !important;
|
|
1255
1257
|
}
|
|
1256
1258
|
[data-phase] [class*="_prompt_1gdtu_"],
|
|
1257
1259
|
[data-phase] [class*="_promptLine_1gdtu_"],
|
|
@@ -1273,7 +1275,7 @@ window.__ModuleLoader__.load({
|
|
|
1273
1275
|
overflow-x: auto !important;
|
|
1274
1276
|
-webkit-overflow-scrolling: touch;
|
|
1275
1277
|
scrollbar-width: none;
|
|
1276
|
-
touch-action: pan-x pan-y !important;
|
|
1278
|
+
touch-action: pan-x pan-y pinch-zoom !important;
|
|
1277
1279
|
}
|
|
1278
1280
|
[data-phase] [class*="_output_1gdtu_"]::-webkit-scrollbar { display: none !important; }
|
|
1279
1281
|
[data-phase] [class*="_line_1gdtu_"] {
|
|
@@ -1286,7 +1288,7 @@ window.__ModuleLoader__.load({
|
|
|
1286
1288
|
[data-phase] [class*="_copyButton_"] { touch-action: manipulation !important; }
|
|
1287
1289
|
[data-phase] [class*="_copyAnchor_"],
|
|
1288
1290
|
[data-phase] [class*="_body_1ye18_"],
|
|
1289
|
-
[data-phase] [class*="_root_4qrvp_"] { touch-action: pan-x pan-y !important; }
|
|
1291
|
+
[data-phase] [class*="_root_4qrvp_"] { touch-action: pan-x pan-y pinch-zoom !important; }
|
|
1290
1292
|
|
|
1291
1293
|
/* 上下文用量弹窗(ContextMeter .JObwrW_panel):上游 dsh-client-ui-trajectory 的
|
|
1292
1294
|
[class*="panel"] 全局规则给它加了 max-width:100%!important,命中本弹窗,使宽度
|
|
@@ -1340,10 +1342,19 @@ window.__ModuleLoader__.load({
|
|
|
1340
1342
|
z-index: 2 !important;
|
|
1341
1343
|
display: inline-flex !important;
|
|
1342
1344
|
align-items: center; justify-content: center;
|
|
1343
|
-
width:
|
|
1345
|
+
width: 32px; height: 32px;
|
|
1344
1346
|
padding: 0; border: none; background: none; cursor: pointer; color: inherit;
|
|
1345
1347
|
-webkit-tap-highlight-color: transparent;
|
|
1346
1348
|
}
|
|
1349
|
+
/* 触控命中区扩展:视觉尺寸不变,可点区域扩到 ~44px(Apple HIG 建议值) */
|
|
1350
|
+
[${FRAME_ATTR}="toggle"]::after,
|
|
1351
|
+
[${FRAME_ATTR}="fab"]::after,
|
|
1352
|
+
[class*="_iconButton"]::after {
|
|
1353
|
+
content: "";
|
|
1354
|
+
position: absolute;
|
|
1355
|
+
inset: -7px;
|
|
1356
|
+
}
|
|
1357
|
+
[class*="_iconButton"] { position: relative !important; }
|
|
1347
1358
|
|
|
1348
1359
|
/* 首页/hero(无活跃会话,session header 不存在)的抽屉切换 FAB:
|
|
1349
1360
|
浮在顶部相机带下方,避免与 hero 头部内容重叠 */
|
|
@@ -1354,7 +1365,7 @@ window.__ModuleLoader__.load({
|
|
|
1354
1365
|
z-index: 21 !important;
|
|
1355
1366
|
display: inline-flex !important;
|
|
1356
1367
|
align-items: center; justify-content: center;
|
|
1357
|
-
width:
|
|
1368
|
+
width: 44px; height: 44px;
|
|
1358
1369
|
padding: 0;
|
|
1359
1370
|
border: 1px solid var(--dsw-alias-border-l1, rgba(0, 0, 0, .12)) !important;
|
|
1360
1371
|
border-radius: 50% !important;
|
|
@@ -1364,6 +1375,30 @@ window.__ModuleLoader__.load({
|
|
|
1364
1375
|
box-shadow: 0 2px 12px rgba(0, 0, 0, .18) !important;
|
|
1365
1376
|
-webkit-tap-highlight-color: transparent;
|
|
1366
1377
|
}
|
|
1378
|
+
|
|
1379
|
+
/* iOS 对 computed font-size <16px 的可编辑元素聚焦时自动放大视口;
|
|
1380
|
+
表单与 composer 提到 16px(消息正文不受影响),聚焦后页面不再错位。 */
|
|
1381
|
+
input, textarea, select, [contenteditable="true"] {
|
|
1382
|
+
font-size: max(16px, 1em) !important;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
/* 底部安全区(iPhone home 条):viewport-fit=cover 后浏览器 UI 退出底部,
|
|
1386
|
+
home 指示条叠在 composer / 抽屉 / 设置 sheet 上,遮挡发送按钮与会话列表末项。 */
|
|
1387
|
+
[class*="composerSeat"], [data-composer-seat] {
|
|
1388
|
+
padding-bottom: max(env(safe-area-inset-bottom, 0px), 4px) !important;
|
|
1389
|
+
}
|
|
1390
|
+
[${FRAME_ATTR}="frame"] > :first-child {
|
|
1391
|
+
padding-bottom: env(safe-area-inset-bottom, 0px) !important;
|
|
1392
|
+
}
|
|
1393
|
+
[aria-modal="true"]:has(> :first-child > :last-child > button):not(:has([role="navigation"])):not(:has([class*="ZuhsRW"])) {
|
|
1394
|
+
max-height: calc(100dvh - 24px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)) !important;
|
|
1395
|
+
}
|
|
1396
|
+
[aria-modal="true"]:has(> :first-child > :last-child > button):not(:has([role="navigation"])):not(:has([class*="ZuhsRW"])) > :last-child > :last-child {
|
|
1397
|
+
padding-bottom: max(env(safe-area-inset-bottom, 0px), 24px) !important;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
/* 会话行触控高度 */
|
|
1401
|
+
[class*="sessionRow"] { min-height: 44px !important; }
|
|
1367
1402
|
}
|
|
1368
1403
|
|
|
1369
1404
|
/* 宽屏 / 鼠标指针:隐藏切换按钮 */
|
|
@@ -1385,7 +1420,7 @@ window.__ModuleLoader__.load({
|
|
|
1385
1420
|
if (viewport === null) return () => {};
|
|
1386
1421
|
const original = viewport.content;
|
|
1387
1422
|
const sync = () => {
|
|
1388
|
-
viewport.content = narrow.matches ? "width=device-width, initial-scale=1, viewport-fit=cover" : original;
|
|
1423
|
+
viewport.content = narrow.matches ? "width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content" : original;
|
|
1389
1424
|
};
|
|
1390
1425
|
sync();
|
|
1391
1426
|
narrow.addEventListener("change", sync);
|
|
@@ -1516,7 +1551,8 @@ window.__ModuleLoader__.load({
|
|
|
1516
1551
|
document.querySelectorAll(`[${FRAME_ATTR}="stats"]`).forEach((el) => {
|
|
1517
1552
|
if (!el.isConnected || !STATS_LINE_RE.test((el.textContent ?? "").trim())) el.removeAttribute(FRAME_ATTR);
|
|
1518
1553
|
});
|
|
1519
|
-
const
|
|
1554
|
+
const scope = document.querySelector("[class*=\"composerStack\"]") ?? document.querySelector("[class*=\"composer\"]") ?? document;
|
|
1555
|
+
const cands = Array.from(scope.querySelectorAll("span, div")).filter((el) => {
|
|
1520
1556
|
if (!isStatsText(el)) return false;
|
|
1521
1557
|
if (getComputedStyle(el).display === "contents") return false;
|
|
1522
1558
|
return true;
|
|
@@ -1538,15 +1574,22 @@ window.__ModuleLoader__.load({
|
|
|
1538
1574
|
}
|
|
1539
1575
|
};
|
|
1540
1576
|
mark();
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1577
|
+
let raf = 0;
|
|
1578
|
+
const scheduleMark = () => {
|
|
1579
|
+
if (raf !== 0 || !narrow.matches) return;
|
|
1580
|
+
raf = requestAnimationFrame(() => {
|
|
1581
|
+
raf = 0;
|
|
1582
|
+
mark();
|
|
1583
|
+
});
|
|
1584
|
+
};
|
|
1585
|
+
const mo = new MutationObserver(scheduleMark);
|
|
1544
1586
|
mo.observe(document.documentElement, {
|
|
1545
1587
|
childList: true,
|
|
1546
1588
|
subtree: true
|
|
1547
1589
|
});
|
|
1548
1590
|
narrow.addEventListener("change", mark);
|
|
1549
1591
|
return () => {
|
|
1592
|
+
if (raf !== 0) cancelAnimationFrame(raf);
|
|
1550
1593
|
mo.disconnect();
|
|
1551
1594
|
narrow.removeEventListener("change", mark);
|
|
1552
1595
|
};
|
|
@@ -1566,36 +1609,54 @@ window.__ModuleLoader__.load({
|
|
|
1566
1609
|
"overflow-y",
|
|
1567
1610
|
"box-sizing"
|
|
1568
1611
|
];
|
|
1612
|
+
/** 幂等写入 important 内联样式:值未变化时跳过,避免 MutationObserver(attributes) 自触发循环。 */
|
|
1613
|
+
function setImportantIfChanged(el, prop, value) {
|
|
1614
|
+
if (el.style.getPropertyValue(prop) === value && el.style.getPropertyPriority(prop) === "important") return;
|
|
1615
|
+
el.style.setProperty(prop, value, "important");
|
|
1616
|
+
}
|
|
1617
|
+
/** 当前视口下的可视区域(手机键盘弹出时 visualViewport 与布局视口错位)。 */
|
|
1618
|
+
function visibleViewport() {
|
|
1619
|
+
const vv = window.visualViewport;
|
|
1620
|
+
if (vv) return {
|
|
1621
|
+
vw: vv.width,
|
|
1622
|
+
vh: vv.offsetTop + vv.height,
|
|
1623
|
+
top: vv.offsetTop
|
|
1624
|
+
};
|
|
1625
|
+
return {
|
|
1626
|
+
vw: window.innerWidth,
|
|
1627
|
+
vh: window.innerHeight,
|
|
1628
|
+
top: 0
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1569
1631
|
/** Keep the model menu anchored to its trigger while fitting it in the viewport. */
|
|
1570
1632
|
function positionAnchoredMenu(el, triggerRect, maxWidth, maxHeight) {
|
|
1571
1633
|
const margin = 8;
|
|
1572
|
-
const vw =
|
|
1573
|
-
|
|
1574
|
-
el
|
|
1575
|
-
el
|
|
1576
|
-
el
|
|
1577
|
-
el
|
|
1578
|
-
el
|
|
1579
|
-
el
|
|
1580
|
-
el
|
|
1581
|
-
el
|
|
1582
|
-
el
|
|
1583
|
-
el.style.setProperty("overflow-y", "auto", "important");
|
|
1634
|
+
const { vw, vh } = visibleViewport();
|
|
1635
|
+
setImportantIfChanged(el, "position", "fixed");
|
|
1636
|
+
setImportantIfChanged(el, "box-sizing", "border-box");
|
|
1637
|
+
setImportantIfChanged(el, "left", "0");
|
|
1638
|
+
setImportantIfChanged(el, "right", "auto");
|
|
1639
|
+
setImportantIfChanged(el, "top", "0");
|
|
1640
|
+
setImportantIfChanged(el, "bottom", "auto");
|
|
1641
|
+
setImportantIfChanged(el, "min-width", "0");
|
|
1642
|
+
setImportantIfChanged(el, "max-width", `${Math.max(0, Math.min(maxWidth, vw - 16))}px`);
|
|
1643
|
+
setImportantIfChanged(el, "max-height", `${Math.max(0, Math.min(maxHeight, vh - 16))}px`);
|
|
1644
|
+
setImportantIfChanged(el, "overflow-y", "auto");
|
|
1584
1645
|
let width = el.offsetWidth;
|
|
1585
1646
|
let height = el.offsetHeight;
|
|
1586
|
-
const
|
|
1647
|
+
const { top: viewportTop } = visibleViewport();
|
|
1648
|
+
const spaceAbove = Math.max(0, triggerRect.top - viewportTop - 16);
|
|
1587
1649
|
const spaceBelow = Math.max(0, vh - triggerRect.bottom - 16);
|
|
1588
1650
|
const expandUp = height <= spaceAbove || spaceAbove >= spaceBelow;
|
|
1589
1651
|
const available = expandUp ? spaceAbove : spaceBelow;
|
|
1590
1652
|
if (height > available) {
|
|
1591
|
-
el
|
|
1653
|
+
setImportantIfChanged(el, "max-height", `${Math.max(0, available - margin)}px`);
|
|
1592
1654
|
height = el.offsetHeight;
|
|
1593
1655
|
width = el.offsetWidth;
|
|
1594
1656
|
}
|
|
1595
1657
|
const top = expandUp ? triggerRect.top - margin - height : triggerRect.bottom + margin;
|
|
1596
|
-
|
|
1597
|
-
el
|
|
1598
|
-
el.style.setProperty("top", `${Math.max(margin, Math.min(top, vh - height - margin))}px`, "important");
|
|
1658
|
+
setImportantIfChanged(el, "left", `${Math.max(margin, Math.min(triggerRect.right - width, vw - width - margin))}px`);
|
|
1659
|
+
setImportantIfChanged(el, "top", `${Math.max(viewportTop + margin, Math.min(top, vh - height - margin))}px`);
|
|
1599
1660
|
}
|
|
1600
1661
|
/**
|
|
1601
1662
|
* 模型名多为纯连字符词(DeepSeek-V4-Flash-Vision-Exp);white-space:normal 下
|
|
@@ -1664,9 +1725,13 @@ window.__ModuleLoader__.load({
|
|
|
1664
1725
|
function installModelMenuPosition(ctx) {
|
|
1665
1726
|
ctx.effect(() => {
|
|
1666
1727
|
const narrow = window.matchMedia(NARROW_QUERY);
|
|
1728
|
+
let fallbackLast = 0;
|
|
1667
1729
|
const findMenus = () => {
|
|
1668
1730
|
const byHash = Array.from(document.querySelectorAll("[class*=\"7KE1Ra_menu\"]"));
|
|
1669
1731
|
if (byHash.length > 0) return byHash;
|
|
1732
|
+
const now = Date.now();
|
|
1733
|
+
if (now - fallbackLast < 500) return [];
|
|
1734
|
+
fallbackLast = now;
|
|
1670
1735
|
return Array.from(document.querySelectorAll("[class*=\"_menu\"]")).filter((el) => el.querySelector("[class*=\"cellLabel\"], [class*=\"modelName\"]") !== null);
|
|
1671
1736
|
};
|
|
1672
1737
|
const findTrigger = (menu) => {
|
|
@@ -1727,16 +1792,42 @@ window.__ModuleLoader__.load({
|
|
|
1727
1792
|
const mo = new MutationObserver(() => requestAnimationFrame(sync));
|
|
1728
1793
|
mo.observe(document.documentElement, {
|
|
1729
1794
|
childList: true,
|
|
1730
|
-
subtree: true
|
|
1795
|
+
subtree: true,
|
|
1796
|
+
attributes: true,
|
|
1797
|
+
attributeFilter: ["style"]
|
|
1731
1798
|
});
|
|
1732
1799
|
narrow.addEventListener("change", sync);
|
|
1733
1800
|
window.addEventListener("resize", sync);
|
|
1734
1801
|
window.addEventListener("scroll", sync, true);
|
|
1802
|
+
window.visualViewport?.addEventListener("resize", sync);
|
|
1803
|
+
window.visualViewport?.addEventListener("scroll", sync);
|
|
1804
|
+
let lastPointerTarget = null;
|
|
1805
|
+
const keyboardLikelyOpen = () => {
|
|
1806
|
+
const vv = window.visualViewport;
|
|
1807
|
+
if (!vv) return false;
|
|
1808
|
+
return window.innerHeight - vv.height > 150;
|
|
1809
|
+
};
|
|
1810
|
+
const onPointerDown = (event) => {
|
|
1811
|
+
lastPointerTarget = event.target instanceof Element ? event.target : null;
|
|
1812
|
+
};
|
|
1813
|
+
const onFocusIn = (event) => {
|
|
1814
|
+
if (!narrow.matches || !(event.target instanceof Element) || keyboardLikelyOpen()) return;
|
|
1815
|
+
const input = event.target.closest("input");
|
|
1816
|
+
if (!input || input.closest("[class*=\"7KE1Ra_menu\"], [class*=\"_menu\"]") === null) return;
|
|
1817
|
+
if (lastPointerTarget !== null && (lastPointerTarget === input || input.contains(lastPointerTarget))) return;
|
|
1818
|
+
input.blur();
|
|
1819
|
+
};
|
|
1820
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
1821
|
+
document.addEventListener("focusin", onFocusIn, true);
|
|
1735
1822
|
return () => {
|
|
1736
1823
|
mo.disconnect();
|
|
1737
1824
|
narrow.removeEventListener("change", sync);
|
|
1738
1825
|
window.removeEventListener("resize", sync);
|
|
1739
1826
|
window.removeEventListener("scroll", sync, true);
|
|
1827
|
+
window.visualViewport?.removeEventListener("resize", sync);
|
|
1828
|
+
window.visualViewport?.removeEventListener("scroll", sync);
|
|
1829
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
1830
|
+
document.removeEventListener("focusin", onFocusIn, true);
|
|
1740
1831
|
};
|
|
1741
1832
|
}, "dshb-mobile: model menu position");
|
|
1742
1833
|
}
|
|
@@ -1757,20 +1848,22 @@ window.__ModuleLoader__.load({
|
|
|
1757
1848
|
const rootRect = root.getBoundingClientRect();
|
|
1758
1849
|
if (rootRect.width === 0 && rootRect.height === 0) continue;
|
|
1759
1850
|
const gap = 8;
|
|
1760
|
-
panel
|
|
1761
|
-
panel
|
|
1762
|
-
panel
|
|
1763
|
-
panel
|
|
1764
|
-
panel
|
|
1765
|
-
panel
|
|
1766
|
-
panel
|
|
1851
|
+
setImportantIfChanged(panel, "position", "fixed");
|
|
1852
|
+
setImportantIfChanged(panel, "top", "auto");
|
|
1853
|
+
setImportantIfChanged(panel, "bottom", `${window.innerHeight - rootRect.top + gap}px`);
|
|
1854
|
+
setImportantIfChanged(panel, "left", "auto");
|
|
1855
|
+
setImportantIfChanged(panel, "right", `${Math.max(gap, window.innerWidth - rootRect.right)}px`);
|
|
1856
|
+
setImportantIfChanged(panel, "max-height", `${Math.max(160, rootRect.top - 16)}px`);
|
|
1857
|
+
setImportantIfChanged(panel, "overflow-y", "auto");
|
|
1767
1858
|
}
|
|
1768
1859
|
};
|
|
1769
1860
|
sync();
|
|
1770
1861
|
const mo = new MutationObserver(() => requestAnimationFrame(sync));
|
|
1771
1862
|
mo.observe(document.documentElement, {
|
|
1772
1863
|
childList: true,
|
|
1773
|
-
subtree: true
|
|
1864
|
+
subtree: true,
|
|
1865
|
+
attributes: true,
|
|
1866
|
+
attributeFilter: ["style"]
|
|
1774
1867
|
});
|
|
1775
1868
|
narrow.addEventListener("change", sync);
|
|
1776
1869
|
window.addEventListener("resize", sync);
|
|
@@ -1800,6 +1893,47 @@ window.__ModuleLoader__.load({
|
|
|
1800
1893
|
return () => document.removeEventListener("pointerdown", focusInput, true);
|
|
1801
1894
|
}, "dshb-mobile: terminal input focus");
|
|
1802
1895
|
}
|
|
1896
|
+
/**
|
|
1897
|
+
* iOS 键盘只缩小 visualViewport,布局视口不动,sticky 在滚动容器底部的
|
|
1898
|
+
* composer 会整个留在键盘后面(发送按钮不可达、最新消息被遮)。监听
|
|
1899
|
+
* visualViewport,键盘开启时把 composer seat 上移键盘高度并在下一帧把
|
|
1900
|
+
* 会话滚动补到最底;Android 由 meta 的 interactive-widget=resizes-content
|
|
1901
|
+
* 让布局视口直接收缩,无需此补偿。
|
|
1902
|
+
*/
|
|
1903
|
+
function installComposerKeyboardLift(ctx) {
|
|
1904
|
+
ctx.effect(() => {
|
|
1905
|
+
const mobile = window.matchMedia(MOBILE_QUERY);
|
|
1906
|
+
const vv = window.visualViewport;
|
|
1907
|
+
if (!vv) return () => {};
|
|
1908
|
+
let raf = 0;
|
|
1909
|
+
const seat = () => document.querySelector("[class*=\"composerSeat\"]") ?? document.querySelector("[data-composer-seat]");
|
|
1910
|
+
const sync = () => {
|
|
1911
|
+
if (raf !== 0) return;
|
|
1912
|
+
raf = requestAnimationFrame(() => {
|
|
1913
|
+
raf = 0;
|
|
1914
|
+
if (!mobile.matches) return;
|
|
1915
|
+
const el = seat();
|
|
1916
|
+
if (el === null) return;
|
|
1917
|
+
const occluded = window.innerHeight - vv.height - vv.offsetTop;
|
|
1918
|
+
if (occluded > 150) {
|
|
1919
|
+
el.style.transform = `translateY(${-occluded}px)`;
|
|
1920
|
+
const body = document.querySelector("[class*=\"scrollBody\"]");
|
|
1921
|
+
body?.scrollTo({ top: body.scrollHeight });
|
|
1922
|
+
} else if (el.style.transform !== "") el.style.transform = "";
|
|
1923
|
+
});
|
|
1924
|
+
};
|
|
1925
|
+
sync();
|
|
1926
|
+
vv.addEventListener("resize", sync);
|
|
1927
|
+
vv.addEventListener("scroll", sync);
|
|
1928
|
+
return () => {
|
|
1929
|
+
if (raf !== 0) cancelAnimationFrame(raf);
|
|
1930
|
+
const el = seat();
|
|
1931
|
+
if (el !== null) el.style.transform = "";
|
|
1932
|
+
vv.removeEventListener("resize", sync);
|
|
1933
|
+
vv.removeEventListener("scroll", sync);
|
|
1934
|
+
};
|
|
1935
|
+
}, "dshb-mobile: composer keyboard lift");
|
|
1936
|
+
}
|
|
1803
1937
|
/** 目录抽屉切换按钮(仅切换,不含文件浏览/日志导出等功能按钮)。 */
|
|
1804
1938
|
function DrawerToggle({ toggleSidebar }) {
|
|
1805
1939
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -1890,6 +2024,7 @@ window.__ModuleLoader__.load({
|
|
|
1890
2024
|
function installMobile(ctx) {
|
|
1891
2025
|
installStyles(ctx);
|
|
1892
2026
|
installMobileTerminalInputFocus(ctx);
|
|
2027
|
+
installComposerKeyboardLift(ctx);
|
|
1893
2028
|
installViewport(ctx);
|
|
1894
2029
|
installFrameMarker(ctx);
|
|
1895
2030
|
installStatsLine(ctx);
|
|
@@ -1930,7 +2065,7 @@ window.__ModuleLoader__.load({
|
|
|
1930
2065
|
const dialog = document.createElement("div");
|
|
1931
2066
|
dialog.setAttribute("role", "dialog");
|
|
1932
2067
|
dialog.setAttribute("aria-label", `修改 ${workspaceTitle} 的项目指令`);
|
|
1933
|
-
dialog.style.cssText = "box-sizing:border-box;width:min(92vw,600px);max-height:
|
|
2068
|
+
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)";
|
|
1934
2069
|
const title = document.createElement("h2");
|
|
1935
2070
|
title.textContent = `项目指令 - ${workspaceTitle}`;
|
|
1936
2071
|
title.style.cssText = "margin:0 0 10px;font-size:16px";
|
|
@@ -2112,7 +2247,14 @@ window.__ModuleLoader__.load({
|
|
|
2112
2247
|
}
|
|
2113
2248
|
}
|
|
2114
2249
|
};
|
|
2115
|
-
|
|
2250
|
+
let raf = 0;
|
|
2251
|
+
new MutationObserver(() => {
|
|
2252
|
+
if (raf !== 0) return;
|
|
2253
|
+
raf = requestAnimationFrame(() => {
|
|
2254
|
+
raf = 0;
|
|
2255
|
+
scan();
|
|
2256
|
+
});
|
|
2257
|
+
}).observe(document.body, {
|
|
2116
2258
|
childList: true,
|
|
2117
2259
|
subtree: true
|
|
2118
2260
|
});
|
|
@@ -3161,9 +3303,9 @@ window.__ModuleLoader__.load({
|
|
|
3161
3303
|
onClick: () => copyText(archive.originSessionId),
|
|
3162
3304
|
style: {
|
|
3163
3305
|
...secondaryBtn,
|
|
3164
|
-
height:
|
|
3165
|
-
padding: "0
|
|
3166
|
-
fontSize:
|
|
3306
|
+
height: 30,
|
|
3307
|
+
padding: "0 10px",
|
|
3308
|
+
fontSize: 11
|
|
3167
3309
|
},
|
|
3168
3310
|
children: "复制 ID"
|
|
3169
3311
|
})]
|
|
@@ -4578,7 +4720,10 @@ window.__ModuleLoader__.load({
|
|
|
4578
4720
|
依赖祖先 overflow:visible 才能展开到输入框之外,禁止给任何中间祖先加裁剪。 */
|
|
4579
4721
|
html, body { overflow-x: hidden !important; max-width: 100vw !important }
|
|
4580
4722
|
* { min-width: 0 !important; }
|
|
4581
|
-
|
|
4723
|
+
/* 表格不设 display:block:上游 markdown 表格已自带滚动容器(tableScroll),
|
|
4724
|
+
display:block 会破坏 caption/sticky 语义且与上游 width:max-content 冲突;
|
|
4725
|
+
这里仅保留溢出约束,宽表由上游 wrapper 横向滚动。 */
|
|
4726
|
+
table { max-width: 100% !important; overflow-x: auto !important; }
|
|
4582
4727
|
img, video, canvas, svg { max-width: 100% !important; height: auto !important }
|
|
4583
4728
|
pre, code { white-space: pre-wrap !important; word-break: break-all !important }
|
|
4584
4729
|
input, select, textarea { max-width: 100% !important; }
|
|
@@ -4651,20 +4796,25 @@ window.__ModuleLoader__.load({
|
|
|
4651
4796
|
"认证": "auth",
|
|
4652
4797
|
"工作节点": "dshb-nodes"
|
|
4653
4798
|
};
|
|
4799
|
+
let raf = 0;
|
|
4654
4800
|
new MutationObserver(() => {
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
const
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4801
|
+
if (raf !== 0) return;
|
|
4802
|
+
raf = requestAnimationFrame(() => {
|
|
4803
|
+
raf = 0;
|
|
4804
|
+
const cells = document.querySelectorAll("button[class*=\"navCell\"]");
|
|
4805
|
+
for (const cell of Array.from(cells)) {
|
|
4806
|
+
const label = cell.querySelector("span[class*=\"navLabel\"]");
|
|
4807
|
+
if (!label) continue;
|
|
4808
|
+
const text = label.textContent ?? "";
|
|
4809
|
+
const iconKey = ICON_LABELS[text];
|
|
4810
|
+
if (!iconKey) continue;
|
|
4811
|
+
const iconSlot = cell.querySelector("[class*=\"navIcon\"]");
|
|
4812
|
+
if (!iconSlot) continue;
|
|
4813
|
+
if (iconSlot.getAttribute("data-dshb-icon") === iconKey) continue;
|
|
4814
|
+
iconSlot.innerHTML = ICON_SVG[iconKey] ?? "";
|
|
4815
|
+
iconSlot.setAttribute("data-dshb-icon", iconKey);
|
|
4816
|
+
}
|
|
4817
|
+
});
|
|
4668
4818
|
}).observe(document.body, {
|
|
4669
4819
|
childList: true,
|
|
4670
4820
|
subtree: true
|