dsh-focus-overlay 0.11.0 → 0.11.2
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 +47 -8
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -1035,7 +1035,24 @@ 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 [pending, setPending] = (0, react.useState)(null);
|
|
1040
|
+
const shown = pending ?? value;
|
|
1041
|
+
const empty = shown.trim() === "";
|
|
1042
|
+
const flush = (v) => {
|
|
1043
|
+
if (v === null) return;
|
|
1044
|
+
setPending(null);
|
|
1045
|
+
onChange(v);
|
|
1046
|
+
};
|
|
1047
|
+
const onCompositionStart = () => {
|
|
1048
|
+
composingRef.current = true;
|
|
1049
|
+
setPending(value);
|
|
1050
|
+
};
|
|
1051
|
+
const onCompositionEnd = (e) => {
|
|
1052
|
+
composingRef.current = false;
|
|
1053
|
+
flush(e.currentTarget.value);
|
|
1054
|
+
refocusAfterEcho(e.currentTarget);
|
|
1055
|
+
};
|
|
1039
1056
|
const onKeyDown = (e) => {
|
|
1040
1057
|
if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && e.nativeEvent.keyCode !== 229) {
|
|
1041
1058
|
e.preventDefault();
|
|
@@ -1046,9 +1063,25 @@ window.__ModuleLoader__.load({
|
|
|
1046
1063
|
el.style.height = "auto";
|
|
1047
1064
|
el.style.height = `${Math.min(el.scrollHeight, 120)}px`;
|
|
1048
1065
|
};
|
|
1066
|
+
const refocusAfterEcho = (el) => {
|
|
1067
|
+
if (document.activeElement === el) return;
|
|
1068
|
+
el.focus();
|
|
1069
|
+
const end = el.value.length;
|
|
1070
|
+
el.setSelectionRange(end, end);
|
|
1071
|
+
};
|
|
1049
1072
|
(0, react.useEffect)(() => {
|
|
1050
1073
|
if (textareaRef.current) autoGrow(textareaRef.current);
|
|
1051
|
-
}, [
|
|
1074
|
+
}, [shown, textareaRef]);
|
|
1075
|
+
const handleInput = (e) => {
|
|
1076
|
+
const el = e.target;
|
|
1077
|
+
if (composingRef.current) setPending(el.value);
|
|
1078
|
+
else {
|
|
1079
|
+
setPending(null);
|
|
1080
|
+
onChange(el.value);
|
|
1081
|
+
}
|
|
1082
|
+
autoGrow(el);
|
|
1083
|
+
refocusAfterEcho(el);
|
|
1084
|
+
};
|
|
1052
1085
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1053
1086
|
className: "fm-bar",
|
|
1054
1087
|
style: { maxWidth: Math.min(width, 680) },
|
|
@@ -1068,15 +1101,21 @@ window.__ModuleLoader__.load({
|
|
|
1068
1101
|
ref: textareaRef,
|
|
1069
1102
|
className: "fm-bar-text",
|
|
1070
1103
|
rows: 1,
|
|
1071
|
-
value,
|
|
1104
|
+
value: shown,
|
|
1072
1105
|
placeholder: t("composer.placeholder"),
|
|
1073
|
-
onChange:
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
},
|
|
1106
|
+
onChange: handleInput,
|
|
1107
|
+
onCompositionStart,
|
|
1108
|
+
onCompositionEnd,
|
|
1077
1109
|
onKeyDown,
|
|
1078
1110
|
onFocus: () => onFocusChange(true),
|
|
1079
|
-
onBlur: () =>
|
|
1111
|
+
onBlur: () => {
|
|
1112
|
+
if (composingRef.current) {
|
|
1113
|
+
composingRef.current = false;
|
|
1114
|
+
flush(shown);
|
|
1115
|
+
if (textareaRef.current) refocusAfterEcho(textareaRef.current);
|
|
1116
|
+
}
|
|
1117
|
+
onFocusChange(false);
|
|
1118
|
+
}
|
|
1080
1119
|
}),
|
|
1081
1120
|
queueCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1082
1121
|
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.2",
|
|
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",
|