@artenx/dshb 0.1.29 → 0.1.30
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 +60 -12
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -1641,16 +1641,57 @@ window.__ModuleLoader__.load({
|
|
|
1641
1641
|
}
|
|
1642
1642
|
}
|
|
1643
1643
|
/**
|
|
1644
|
-
* 模型选择弹窗(dsh-client-ui-model-selection
|
|
1645
|
-
*
|
|
1646
|
-
*
|
|
1647
|
-
*
|
|
1648
|
-
* close()(焦点移出菜单即关闭),手机上表现为菜单刚打开就被关掉("弹不出来")。
|
|
1649
|
-
* 这里只保留窄屏下的视觉适配:模型名不换行连字符 + 按最宽名字缩放字号。
|
|
1644
|
+
* 模型选择弹窗(dsh-client-ui-model-selection):定位完全交还上游的 fixed + place()。
|
|
1645
|
+
* 第二层模型列表含自动聚焦的搜索框;窄屏下以 inputmode=none 阻止自动唤起虚拟键盘,
|
|
1646
|
+
* 用户主动点搜索框时切回 search。保持焦点有效,避免 blur 触发上游关闭菜单。
|
|
1647
|
+
* 同时保留模型名的窄屏视觉适配。
|
|
1650
1648
|
*/
|
|
1651
|
-
function
|
|
1649
|
+
function installModelMenuBehavior(ctx) {
|
|
1652
1650
|
ctx.effect(() => {
|
|
1653
1651
|
const narrow = window.matchMedia(NARROW_QUERY);
|
|
1652
|
+
const manualKeyboardInputs = /* @__PURE__ */ new WeakSet();
|
|
1653
|
+
const isModelSearchInput = (target) => {
|
|
1654
|
+
if (!(target instanceof HTMLInputElement) || target.getAttribute("role") !== "searchbox") return false;
|
|
1655
|
+
const menu = target.closest("[class*=\"_menu\"]");
|
|
1656
|
+
return menu !== null && menu.querySelector("[class*=\"modelName\"]") !== null;
|
|
1657
|
+
};
|
|
1658
|
+
const setAutoKeyboardMode = (input) => {
|
|
1659
|
+
if (narrow.matches && isModelSearchInput(input) && !manualKeyboardInputs.has(input)) input.inputMode = "none";
|
|
1660
|
+
};
|
|
1661
|
+
const prepareSearchInputs = (node) => {
|
|
1662
|
+
if (!narrow.matches) return;
|
|
1663
|
+
if (node instanceof HTMLInputElement) setAutoKeyboardMode(node);
|
|
1664
|
+
else if (node instanceof Element) for (const input of node.querySelectorAll("input[role=\"searchbox\"]")) setAutoKeyboardMode(input);
|
|
1665
|
+
};
|
|
1666
|
+
const onSearchFocus = (event) => {
|
|
1667
|
+
const input = event.target;
|
|
1668
|
+
if (input instanceof HTMLInputElement) setAutoKeyboardMode(input);
|
|
1669
|
+
};
|
|
1670
|
+
const onSearchPointerDown = (event) => {
|
|
1671
|
+
const input = event.target;
|
|
1672
|
+
if (!narrow.matches || !isModelSearchInput(input)) return;
|
|
1673
|
+
manualKeyboardInputs.add(input);
|
|
1674
|
+
input.inputMode = "search";
|
|
1675
|
+
};
|
|
1676
|
+
const onSearchBlur = (event) => {
|
|
1677
|
+
const input = event.target;
|
|
1678
|
+
if (!isModelSearchInput(input)) return;
|
|
1679
|
+
manualKeyboardInputs.delete(input);
|
|
1680
|
+
if (narrow.matches) input.inputMode = "none";
|
|
1681
|
+
else input.removeAttribute("inputmode");
|
|
1682
|
+
};
|
|
1683
|
+
const restoreSearchInputs = () => {
|
|
1684
|
+
for (const input of document.querySelectorAll("input[role=\"searchbox\"]")) if (isModelSearchInput(input)) input.removeAttribute("inputmode");
|
|
1685
|
+
};
|
|
1686
|
+
const onNarrowChange = () => {
|
|
1687
|
+
if (narrow.matches) prepareSearchInputs(document.documentElement);
|
|
1688
|
+
else restoreSearchInputs();
|
|
1689
|
+
sync();
|
|
1690
|
+
};
|
|
1691
|
+
document.addEventListener("focus", onSearchFocus, true);
|
|
1692
|
+
document.addEventListener("pointerdown", onSearchPointerDown, true);
|
|
1693
|
+
document.addEventListener("blur", onSearchBlur, true);
|
|
1694
|
+
prepareSearchInputs(document.documentElement);
|
|
1654
1695
|
let fallbackLast = 0;
|
|
1655
1696
|
const findMenus = () => {
|
|
1656
1697
|
const byHash = Array.from(document.querySelectorAll("[class*=\"7KE1Ra_menu\"]"));
|
|
@@ -1697,19 +1738,26 @@ window.__ModuleLoader__.load({
|
|
|
1697
1738
|
}
|
|
1698
1739
|
};
|
|
1699
1740
|
sync();
|
|
1700
|
-
const mo = new MutationObserver(() =>
|
|
1741
|
+
const mo = new MutationObserver((records) => {
|
|
1742
|
+
for (const record of records) for (const node of record.addedNodes) prepareSearchInputs(node);
|
|
1743
|
+
requestAnimationFrame(sync);
|
|
1744
|
+
});
|
|
1701
1745
|
mo.observe(document.documentElement, {
|
|
1702
1746
|
childList: true,
|
|
1703
1747
|
subtree: true
|
|
1704
1748
|
});
|
|
1705
|
-
narrow.addEventListener("change",
|
|
1749
|
+
narrow.addEventListener("change", onNarrowChange);
|
|
1706
1750
|
window.addEventListener("resize", sync);
|
|
1707
1751
|
return () => {
|
|
1708
1752
|
mo.disconnect();
|
|
1709
|
-
|
|
1753
|
+
document.removeEventListener("focus", onSearchFocus, true);
|
|
1754
|
+
document.removeEventListener("pointerdown", onSearchPointerDown, true);
|
|
1755
|
+
document.removeEventListener("blur", onSearchBlur, true);
|
|
1756
|
+
narrow.removeEventListener("change", onNarrowChange);
|
|
1710
1757
|
window.removeEventListener("resize", sync);
|
|
1758
|
+
restoreSearchInputs();
|
|
1711
1759
|
};
|
|
1712
|
-
}, "dshb-mobile: model menu
|
|
1760
|
+
}, "dshb-mobile: model menu behavior");
|
|
1713
1761
|
}
|
|
1714
1762
|
/**
|
|
1715
1763
|
* 上下文用量弹窗(ContextMeter .JObwrW_panel,dsh-client-ui-conversation)上游是
|
|
@@ -1908,7 +1956,7 @@ window.__ModuleLoader__.load({
|
|
|
1908
1956
|
installViewport(ctx);
|
|
1909
1957
|
installFrameMarker(ctx);
|
|
1910
1958
|
installStatsLine(ctx);
|
|
1911
|
-
|
|
1959
|
+
installModelMenuBehavior(ctx);
|
|
1912
1960
|
installContextPanelPosition(ctx);
|
|
1913
1961
|
const layout = ctx.layout;
|
|
1914
1962
|
const slots = ctx.slots;
|