mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 17:30:31 +00:00
Use React handlers for rename inputs
This commit is contained in:
parent
f3600e8947
commit
45c471a331
4 changed files with 42 additions and 52 deletions
|
|
@ -517,38 +517,16 @@ function ArchiveModeButton({
|
|||
function ThreadRenameRow({ thread, actions }: { thread: ToolbarThreadRow; actions: ToolbarActions }): ReactNode {
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
const generating = thread.rename?.generating ?? false;
|
||||
const draft = thread.rename?.draft ?? thread.title;
|
||||
useLayoutEffect(() => {
|
||||
const input = inputRef.current;
|
||||
if (!input) return;
|
||||
input.oninput = () => {
|
||||
actions.updateRenameDraft(thread.threadId, input.value);
|
||||
};
|
||||
input.onkeydown = (event) => {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
if (!event.isComposing && !generating) actions.saveRenameThread(thread.threadId, input.value);
|
||||
return;
|
||||
}
|
||||
if (event.key === "Escape") {
|
||||
event.preventDefault();
|
||||
actions.cancelRenameThread(thread.threadId);
|
||||
}
|
||||
};
|
||||
input.onblur = () => {
|
||||
if (!generating) actions.saveRenameThread(thread.threadId, input.value);
|
||||
};
|
||||
const draft = thread.rename?.draft ?? thread.title;
|
||||
if (input.value !== draft) input.value = draft;
|
||||
if (input.ownerDocument.activeElement !== input) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
return () => {
|
||||
input.oninput = null;
|
||||
input.onkeydown = null;
|
||||
input.onblur = null;
|
||||
};
|
||||
}, [actions, generating, thread.rename?.draft, thread.threadId, thread.title]);
|
||||
}, [draft]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -562,8 +540,25 @@ function ThreadRenameRow({ thread, actions }: { thread: ToolbarThreadRow; action
|
|||
ref={inputRef}
|
||||
className="codex-panel__thread-rename-input"
|
||||
type="text"
|
||||
defaultValue={thread.rename?.draft ?? thread.title}
|
||||
defaultValue={draft}
|
||||
aria-label={`Rename ${thread.title}`}
|
||||
onInput={(event) => {
|
||||
actions.updateRenameDraft(thread.threadId, event.currentTarget.value);
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
if (!event.nativeEvent.isComposing && !generating) actions.saveRenameThread(thread.threadId, event.currentTarget.value);
|
||||
return;
|
||||
}
|
||||
if (event.key === "Escape") {
|
||||
event.preventDefault();
|
||||
actions.cancelRenameThread(thread.threadId);
|
||||
}
|
||||
}}
|
||||
onBlur={(event) => {
|
||||
if (!generating) actions.saveRenameThread(thread.threadId, event.currentTarget.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -185,34 +185,12 @@ function RenameRow({ row, actions }: { row: ThreadsRowModel; actions: ThreadsVie
|
|||
useLayoutEffect(() => {
|
||||
const input = inputRef.current;
|
||||
if (!input) return;
|
||||
input.oninput = () => {
|
||||
actions.updateRename(row.thread.id, input.value);
|
||||
};
|
||||
input.onkeydown = (event) => {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
if (!event.isComposing && !row.rename.generating) actions.saveRename(row.thread.id, input.value);
|
||||
return;
|
||||
}
|
||||
if (event.key === "Escape") {
|
||||
event.preventDefault();
|
||||
actions.cancelRename(row.thread.id);
|
||||
}
|
||||
};
|
||||
input.onblur = () => {
|
||||
if (!row.rename.generating) actions.saveRename(row.thread.id, input.value);
|
||||
};
|
||||
if (input.value !== row.rename.draft) input.value = row.rename.draft;
|
||||
if (input.ownerDocument.activeElement !== input) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
return () => {
|
||||
input.oninput = null;
|
||||
input.onkeydown = null;
|
||||
input.onblur = null;
|
||||
};
|
||||
}, [actions, row.rename.draft, row.rename.generating, row.thread.id]);
|
||||
}, [row.rename.draft]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -229,6 +207,23 @@ function RenameRow({ row, actions }: { row: ThreadsRowModel; actions: ThreadsVie
|
|||
type="text"
|
||||
aria-label="Thread name"
|
||||
defaultValue={row.rename.draft}
|
||||
onInput={(event) => {
|
||||
actions.updateRename(row.thread.id, event.currentTarget.value);
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
if (!event.nativeEvent.isComposing && !row.rename.generating) actions.saveRename(row.thread.id, event.currentTarget.value);
|
||||
return;
|
||||
}
|
||||
if (event.key === "Escape") {
|
||||
event.preventDefault();
|
||||
actions.cancelRename(row.thread.id);
|
||||
}
|
||||
}}
|
||||
onBlur={(event) => {
|
||||
if (!row.rename.generating) actions.saveRename(row.thread.id, event.currentTarget.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1985,7 +1985,7 @@ describe("toolbar renderer decisions", () => {
|
|||
input.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
expect(updateRenameDraft).toHaveBeenCalledWith("editing", "New title");
|
||||
|
||||
input.dispatchEvent(new FocusEvent("blur"));
|
||||
input.dispatchEvent(new FocusEvent("focusout", { bubbles: true }));
|
||||
expect(saveRenameThread).toHaveBeenCalledWith("editing", "New title");
|
||||
input.dispatchEvent(new KeyboardEvent("keydown", { key: "Escape", bubbles: true }));
|
||||
expect(cancelRenameThread).toHaveBeenCalledWith("editing");
|
||||
|
|
@ -2179,8 +2179,8 @@ describe("threads view renderer decisions", () => {
|
|||
|
||||
const input = expectPresent(parent.querySelector<HTMLInputElement>(".codex-panel-threads__rename-input"));
|
||||
input.value = "New name";
|
||||
input.dispatchEvent(new Event("input"));
|
||||
input.dispatchEvent(new FocusEvent("blur"));
|
||||
input.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
input.dispatchEvent(new FocusEvent("focusout", { bubbles: true }));
|
||||
|
||||
expect(actions.updateRename).toHaveBeenCalledWith("thread", "New name");
|
||||
expect(actions.saveRename).toHaveBeenCalledWith("thread", "New name");
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ describe("CodexThreadsView", () => {
|
|||
expect(input).not.toBeNull();
|
||||
if (!input) return;
|
||||
input.value = "Renamed thread";
|
||||
input.dispatchEvent(new FocusEvent("blur"));
|
||||
input.dispatchEvent(new FocusEvent("focusout", { bubbles: true }));
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(setThreadName).toHaveBeenCalledWith("thread", "Renamed thread");
|
||||
|
|
|
|||
Loading…
Reference in a new issue