-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseDraftLifecycle.ts
More file actions
102 lines (90 loc) · 2.67 KB
/
useDraftLifecycle.ts
File metadata and controls
102 lines (90 loc) · 2.67 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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { useEffect } from "react";
import type { SavedDraft } from "../../types/workspace";
function isEditableTarget(target: EventTarget | null): boolean {
if (!(target instanceof HTMLElement)) {
return false;
}
const tag = target.tagName.toLowerCase();
return (
tag === "input" ||
tag === "textarea" ||
tag === "select" ||
target.isContentEditable
);
}
type PanelDensityMode = "balanced" | "focus-intake" | "focus-response";
type ViewMode = "panels" | "conversation";
interface UseDraftLifecycleOptions {
initialDraft?: SavedDraft | null;
viewMode: ViewMode;
input: string;
savedDraftId: string | null;
refreshWorkspaceCatalog: () => Promise<unknown>;
findSimilar: (query: string) => Promise<unknown> | void;
loadAlternatives: (draftId: string) => Promise<unknown> | void;
loadTemplates: () => Promise<unknown> | void;
handleLoadDraft: (draft: SavedDraft) => void;
onPanelDensityModeChange: (mode: PanelDensityMode) => void;
setSuggestionsDismissed: (value: boolean) => void;
}
export function useDraftLifecycle({
initialDraft,
viewMode,
input,
savedDraftId,
refreshWorkspaceCatalog,
findSimilar,
loadAlternatives,
loadTemplates,
handleLoadDraft,
onPanelDensityModeChange,
setSuggestionsDismissed,
}: UseDraftLifecycleOptions) {
useEffect(() => {
void refreshWorkspaceCatalog();
}, [refreshWorkspaceCatalog]);
useEffect(() => {
if (input.trim().length >= 10) {
setSuggestionsDismissed(false);
void findSimilar(input);
}
}, [input, findSimilar, setSuggestionsDismissed]);
useEffect(() => {
if (savedDraftId) {
void loadAlternatives(savedDraftId);
}
}, [savedDraftId, loadAlternatives]);
useEffect(() => {
if (viewMode !== "panels") {
return;
}
const handleKeydown = (event: KeyboardEvent) => {
if (!event.metaKey || event.altKey || event.ctrlKey) {
return;
}
if (isEditableTarget(event.target)) {
return;
}
if (event.key === "1") {
event.preventDefault();
onPanelDensityModeChange("balanced");
} else if (event.key === "2") {
event.preventDefault();
onPanelDensityModeChange("focus-intake");
} else if (event.key === "3") {
event.preventDefault();
onPanelDensityModeChange("focus-response");
}
};
window.addEventListener("keydown", handleKeydown);
return () => window.removeEventListener("keydown", handleKeydown);
}, [viewMode, onPanelDensityModeChange]);
useEffect(() => {
if (initialDraft) {
handleLoadDraft(initialDraft);
}
}, [initialDraft, handleLoadDraft]);
useEffect(() => {
void loadTemplates();
}, [loadTemplates]);
}