Repository navigation
Expand file tree
/
Copy pathcomposerSubmitRequestStore.ts
More file actions
39 lines (35 loc) · 1.68 KB
/
Copy pathcomposerSubmitRequestStore.ts
File metadata and controls
39 lines (35 loc) · 1.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { create } from "zustand";
import { composerTargetKey, type ComposerThreadTarget } from "./composerDraftStore";
/** Send what the draft holds, or keep it as a draft on the thread to send later. */
export type ComposerSubmitIntent = "send" | "save-draft";
interface ComposerSubmitRequestState {
/** Composer target keys whose draft should be handled as soon as that composer can. */
readonly pending: ReadonlyMap<string, ComposerSubmitIntent>;
readonly request: (target: ComposerThreadTarget, intent?: ComposerSubmitIntent) => void;
/** Claims a request once; null when there was none or another composer took it. */
readonly take: (key: string) => ComposerSubmitIntent | null;
}
/**
* One-shot asks, from outside a composer, to send what its draft holds. Writing to a draft and
* pressing send are both the reader's to do from the composer; this lets a surface beside it,
* such as a pull request's "Send to agent", press send for them through the composer's own path,
* so queueing, validation and attachments behave exactly as they would for Enter. Saving as a
* draft goes the same way, so it uploads and records context exactly as the composer's own save.
*/
export const useComposerSubmitRequestStore = create<ComposerSubmitRequestState>((set, get) => ({
pending: new Map(),
request: (target, intent = "send") =>
set((state) => ({
pending: new Map(state.pending).set(composerTargetKey(target), intent),
})),
take: (key) => {
const intent = get().pending.get(key) ?? null;
if (intent === null) return null;
set((state) => {
const pending = new Map(state.pending);
pending.delete(key);
return { pending };
});
return intent;
},
}));