-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathuse-ai-chat-panel.ts
More file actions
89 lines (79 loc) · 2.23 KB
/
use-ai-chat-panel.ts
File metadata and controls
89 lines (79 loc) · 2.23 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
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
import { useState, useEffect, useCallback } from 'react';
import type { UIMessage } from 'ai';
const STORAGE_KEY = 'objectstack:ai-chat-messages';
const PANEL_STATE_KEY = 'objectstack:ai-chat-panel-open';
/**
* Load persisted chat messages from localStorage.
*/
export function loadMessages(): UIMessage[] {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return [];
const parsed = JSON.parse(raw);
return Array.isArray(parsed) ? parsed : [];
} catch {
return [];
}
}
/**
* Persist chat messages to localStorage.
*/
export function saveMessages(messages: UIMessage[]): void {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(messages));
} catch {
// localStorage may be full or unavailable — silently ignore
}
}
/**
* Load panel open/closed state from localStorage.
*/
function loadPanelState(): boolean {
try {
return localStorage.getItem(PANEL_STATE_KEY) === 'true';
} catch {
return false;
}
}
/**
* Hook for managing AI Chat Panel state:
* - Panel visibility toggle (open/close)
* - Global keyboard shortcut (Ctrl+Shift+I / Cmd+Shift+I)
* - Panel state persistence to localStorage
*/
export function useAiChatPanel() {
const [isOpen, setIsOpen] = useState<boolean>(loadPanelState);
// Persist panel state to localStorage
const setOpen = useCallback((open: boolean) => {
setIsOpen(open);
try {
localStorage.setItem(PANEL_STATE_KEY, String(open));
} catch {
// silently ignore
}
}, []);
const toggle = useCallback(() => {
setIsOpen((prev) => {
const next = !prev;
try {
localStorage.setItem(PANEL_STATE_KEY, String(next));
} catch {
// silently ignore
}
return next;
});
}, []);
// Global keyboard shortcut: Ctrl+Shift+I / Cmd+Shift+I
useEffect(() => {
function handleKeyDown(e: KeyboardEvent) {
if (e.shiftKey && (e.ctrlKey || e.metaKey) && e.key === 'I') {
e.preventDefault();
toggle();
}
}
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [toggle]);
return { isOpen, setOpen, toggle };
}