dsh-focus-overlay 0.11.1 → 0.11.3
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 +57 -15
- package/package.json +2 -1
package/lib/client.js
CHANGED
|
@@ -1035,7 +1035,37 @@ window.__ModuleLoader__.load({
|
|
|
1035
1035
|
}
|
|
1036
1036
|
function InputBar(props) {
|
|
1037
1037
|
const { t, width, value, queueCount, occCount, errorLine, textareaRef, onFocusChange, onChange, onSend } = props;
|
|
1038
|
-
const
|
|
1038
|
+
const composingRef = (0, react.useRef)(false);
|
|
1039
|
+
const echoingRef = (0, react.useRef)(false);
|
|
1040
|
+
const [pending, setPending] = (0, react.useState)(null);
|
|
1041
|
+
const shown = pending ?? value;
|
|
1042
|
+
const empty = shown.trim() === "";
|
|
1043
|
+
const echo = (el, next) => {
|
|
1044
|
+
const start = el.selectionStart;
|
|
1045
|
+
const end = el.selectionEnd;
|
|
1046
|
+
echoingRef.current = true;
|
|
1047
|
+
try {
|
|
1048
|
+
onChange(next);
|
|
1049
|
+
} finally {
|
|
1050
|
+
echoingRef.current = false;
|
|
1051
|
+
}
|
|
1052
|
+
if (document.activeElement !== el) {
|
|
1053
|
+
el.focus();
|
|
1054
|
+
el.setSelectionRange(start, end);
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
const flush = (el) => {
|
|
1058
|
+
setPending(null);
|
|
1059
|
+
echo(el, el.value);
|
|
1060
|
+
};
|
|
1061
|
+
const onCompositionStart = () => {
|
|
1062
|
+
composingRef.current = true;
|
|
1063
|
+
setPending(value);
|
|
1064
|
+
};
|
|
1065
|
+
const onCompositionEnd = (e) => {
|
|
1066
|
+
composingRef.current = false;
|
|
1067
|
+
flush(e.currentTarget);
|
|
1068
|
+
};
|
|
1039
1069
|
const onKeyDown = (e) => {
|
|
1040
1070
|
if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && e.nativeEvent.keyCode !== 229) {
|
|
1041
1071
|
e.preventDefault();
|
|
@@ -1046,15 +1076,18 @@ window.__ModuleLoader__.load({
|
|
|
1046
1076
|
el.style.height = "auto";
|
|
1047
1077
|
el.style.height = `${Math.min(el.scrollHeight, 120)}px`;
|
|
1048
1078
|
};
|
|
1049
|
-
const refocusAfterEcho = (el) => {
|
|
1050
|
-
if (document.activeElement === el) return;
|
|
1051
|
-
el.focus();
|
|
1052
|
-
const end = el.value.length;
|
|
1053
|
-
el.setSelectionRange(end, end);
|
|
1054
|
-
};
|
|
1055
1079
|
(0, react.useEffect)(() => {
|
|
1056
1080
|
if (textareaRef.current) autoGrow(textareaRef.current);
|
|
1057
|
-
}, [
|
|
1081
|
+
}, [shown, textareaRef]);
|
|
1082
|
+
const handleInput = (e) => {
|
|
1083
|
+
const el = e.target;
|
|
1084
|
+
if (composingRef.current) setPending(el.value);
|
|
1085
|
+
else {
|
|
1086
|
+
setPending(null);
|
|
1087
|
+
echo(el, el.value);
|
|
1088
|
+
}
|
|
1089
|
+
autoGrow(el);
|
|
1090
|
+
};
|
|
1058
1091
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1059
1092
|
className: "fm-bar",
|
|
1060
1093
|
style: { maxWidth: Math.min(width, 680) },
|
|
@@ -1074,16 +1107,25 @@ window.__ModuleLoader__.load({
|
|
|
1074
1107
|
ref: textareaRef,
|
|
1075
1108
|
className: "fm-bar-text",
|
|
1076
1109
|
rows: 1,
|
|
1077
|
-
value,
|
|
1110
|
+
value: shown,
|
|
1078
1111
|
placeholder: t("composer.placeholder"),
|
|
1079
|
-
onChange:
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
refocusAfterEcho(e.target);
|
|
1083
|
-
},
|
|
1112
|
+
onChange: handleInput,
|
|
1113
|
+
onCompositionStart,
|
|
1114
|
+
onCompositionEnd,
|
|
1084
1115
|
onKeyDown,
|
|
1085
1116
|
onFocus: () => onFocusChange(true),
|
|
1086
|
-
onBlur: () =>
|
|
1117
|
+
onBlur: () => {
|
|
1118
|
+
if (echoingRef.current) return;
|
|
1119
|
+
if (composingRef.current) {
|
|
1120
|
+
composingRef.current = false;
|
|
1121
|
+
const el = textareaRef.current;
|
|
1122
|
+
if (el) {
|
|
1123
|
+
flush(el);
|
|
1124
|
+
if (document.activeElement === el) return;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
onFocusChange(false);
|
|
1128
|
+
}
|
|
1087
1129
|
}),
|
|
1088
1130
|
queueCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1089
1131
|
className: "fm-bar-queue",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-focus-overlay",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "Focus Mode for the dsh web GUI: a full-screen reading overlay that hides chrome and folds the AI tool-call flow into summaries, reusing the official Markdown / image primitives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.mjs",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"bundle"
|
|
55
55
|
],
|
|
56
56
|
"devDependencies": {
|
|
57
|
+
"playwright-core": "^1.63.0",
|
|
57
58
|
"tsdown": "0.22.2",
|
|
58
59
|
"vitest": "^4.1.10"
|
|
59
60
|
},
|