MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / useComposerDraft

Function useComposerDraft

apps/kimi-web/src/composables/useComposerDraft.ts:19–87  ·  view source on GitHub ↗
(deps: ComposerDraftDeps)

Source from the content-addressed store, hash-verified

17 * the imperative `loadForEdit` handle exposed to the parent.
18 */
19export function useComposerDraft(deps: ComposerDraftDeps) {
20 const { sessionId } = deps;
21
22 function loadDraft(sid: string | undefined): string {
23 return safeGetString(draftStorageKey(sid)) ?? '';
24 }
25 function saveDraft(sid: string | undefined, value: string): void {
26 const key = draftStorageKey(sid);
27 if (value) safeSetString(key, value);
28 else safeRemove(key);
29 }
30
31 const text = ref(loadDraft(sessionId()));
32 const textareaRef = ref<HTMLTextAreaElement | null>(null);
33
34 function autosize(): void {
35 const el = textareaRef.value;
36 if (!el) return;
37 // Reset to measure the natural content height, then fit the box to it.
38 // The resting height and the upper cap live in CSS (`min-height` /
39 // `max-height`); once the content outgrows the cap, `overflow-y: auto`
40 // scrolls internally. This keeps a single source of truth for the bounds.
41 el.style.height = 'auto';
42 el.style.height = `${el.scrollHeight}px`;
43 }
44
45 watch(text, (value) => {
46 void nextTick(autosize);
47 // Persist the live draft for the current session (empty clears the entry).
48 saveDraft(sessionId(), value);
49 });
50
51 // Switching sessions: stash the draft under the OLD session, then load the new
52 // session's draft into the box.
53 watch(sessionId, (newSid, oldSid) => {
54 if (newSid === oldSid) return;
55 saveDraft(oldSid, text.value);
56 text.value = loadDraft(newSid);
57 void nextTick(autosize);
58 });
59
60 /** Imperatively load text into the box for editing (used by "edit & resend the
61 last message" after an undo, or by the dock queue panel when the user edits
62 a queued prompt). Focuses with the caret at the end. */
63 function loadForEdit(value: string): void {
64 text.value = value;
65 void nextTick(() => {
66 const el = textareaRef.value;
67 if (!el) return;
68 el.focus();
69 const pos = value.length;
70 el.setSelectionRange(pos, pos);
71 autosize();
72 });
73 }
74
75 /**
76 * Synchronously clear the persisted draft for the current session.

Callers 1

setupFunction · 0.90

Calls 2

loadDraftFunction · 0.85
saveDraftFunction · 0.85

Tested by 1

setupFunction · 0.72