Drafts
This commit is contained in:
@@ -28,6 +28,7 @@ import { cn } from "@/lib/utils";
|
||||
type Provider = "openai" | "anthropic" | "xai";
|
||||
type AuthMode = "open" | "token";
|
||||
type SidebarSelection = { kind: "chat" | "search"; id: string };
|
||||
type DraftSelectionKind = "chat" | "search";
|
||||
type SidebarItem = SidebarSelection & {
|
||||
title: string;
|
||||
updatedAt: string;
|
||||
@@ -132,6 +133,7 @@ export default function App() {
|
||||
const [selectedItem, setSelectedItem] = useState<SidebarSelection | null>(null);
|
||||
const [selectedChat, setSelectedChat] = useState<ChatDetail | null>(null);
|
||||
const [selectedSearch, setSelectedSearch] = useState<SearchDetail | null>(null);
|
||||
const [draftKind, setDraftKind] = useState<DraftSelectionKind | null>(null);
|
||||
const [isLoadingCollections, setIsLoadingCollections] = useState(false);
|
||||
const [isLoadingSelection, setIsLoadingSelection] = useState(false);
|
||||
const [isSending, setIsSending] = useState(false);
|
||||
@@ -163,6 +165,7 @@ export default function App() {
|
||||
setSelectedItem(null);
|
||||
setSelectedChat(null);
|
||||
setSelectedSearch(null);
|
||||
setDraftKind(null);
|
||||
};
|
||||
|
||||
const refreshCollections = async (preferredSelection?: SidebarSelection) => {
|
||||
@@ -277,9 +280,9 @@ export default function App() {
|
||||
}, [isAuthenticated, selectedKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedItem?.kind === "search") return;
|
||||
if (draftKind === "search" || selectedItem?.kind === "search") return;
|
||||
transcriptEndRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
|
||||
}, [selectedChat?.messages.length, isSending, selectedItem?.kind]);
|
||||
}, [draftKind, selectedChat?.messages.length, isSending, selectedItem?.kind]);
|
||||
|
||||
const messages = selectedChat?.messages ?? [];
|
||||
|
||||
@@ -294,6 +297,8 @@ export default function App() {
|
||||
}, [searches, selectedItem]);
|
||||
|
||||
const selectedTitle = useMemo(() => {
|
||||
if (draftKind === "chat") return "New chat";
|
||||
if (draftKind === "search") return "New search";
|
||||
if (!selectedItem) return "Sybil";
|
||||
if (selectedItem.kind === "chat") {
|
||||
if (selectedChat) return getChatTitle(selectedChat, selectedChat.messages);
|
||||
@@ -303,69 +308,34 @@ export default function App() {
|
||||
if (selectedSearch) return getSearchTitle(selectedSearch);
|
||||
if (selectedSearchSummary) return getSearchTitle(selectedSearchSummary);
|
||||
return "New search";
|
||||
}, [selectedChat, selectedChatSummary, selectedItem, selectedSearch, selectedSearchSummary]);
|
||||
}, [draftKind, selectedChat, selectedChatSummary, selectedItem, selectedSearch, selectedSearchSummary]);
|
||||
|
||||
const isSearchMode = selectedItem?.kind === "search";
|
||||
const isSearchMode = draftKind ? draftKind === "search" : selectedItem?.kind === "search";
|
||||
const isSearchRunning = isSending && selectedItem?.kind === "search";
|
||||
|
||||
const handleCreateChat = async () => {
|
||||
const handleCreateChat = () => {
|
||||
setError(null);
|
||||
try {
|
||||
const chat = await createChat();
|
||||
setSelectedItem({ kind: "chat", id: chat.id });
|
||||
setSelectedChat({
|
||||
id: chat.id,
|
||||
title: chat.title,
|
||||
createdAt: chat.createdAt,
|
||||
updatedAt: chat.updatedAt,
|
||||
messages: [],
|
||||
});
|
||||
setSelectedSearch(null);
|
||||
await refreshCollections({ kind: "chat", id: chat.id });
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
if (message.includes("bearer token")) {
|
||||
handleAuthFailure(message);
|
||||
} else {
|
||||
setError(message);
|
||||
}
|
||||
}
|
||||
setDraftKind("chat");
|
||||
setSelectedItem(null);
|
||||
setSelectedChat(null);
|
||||
setSelectedSearch(null);
|
||||
};
|
||||
|
||||
const handleCreateSearch = async () => {
|
||||
const handleCreateSearch = () => {
|
||||
setError(null);
|
||||
try {
|
||||
const search = await createSearch();
|
||||
setSelectedItem({ kind: "search", id: search.id });
|
||||
setSelectedSearch({
|
||||
id: search.id,
|
||||
title: search.title,
|
||||
query: search.query,
|
||||
createdAt: search.createdAt,
|
||||
updatedAt: search.updatedAt,
|
||||
requestId: null,
|
||||
latencyMs: null,
|
||||
error: null,
|
||||
results: [],
|
||||
});
|
||||
setSelectedChat(null);
|
||||
await refreshCollections({ kind: "search", id: search.id });
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
if (message.includes("bearer token")) {
|
||||
handleAuthFailure(message);
|
||||
} else {
|
||||
setError(message);
|
||||
}
|
||||
}
|
||||
setDraftKind("search");
|
||||
setSelectedItem(null);
|
||||
setSelectedChat(null);
|
||||
setSelectedSearch(null);
|
||||
};
|
||||
|
||||
const handleSendChat = async (content: string) => {
|
||||
let chatId = selectedItem?.kind === "chat" ? selectedItem.id : null;
|
||||
let chatId = draftKind === "chat" ? null : selectedItem?.kind === "chat" ? selectedItem.id : null;
|
||||
|
||||
if (!chatId) {
|
||||
const chat = await createChat();
|
||||
chatId = chat.id;
|
||||
setDraftKind(null);
|
||||
setSelectedItem({ kind: "chat", id: chatId });
|
||||
setSelectedChat({
|
||||
id: chat.id,
|
||||
@@ -433,11 +403,15 @@ export default function App() {
|
||||
};
|
||||
|
||||
const handleSendSearch = async (query: string) => {
|
||||
let searchId = selectedItem?.kind === "search" ? selectedItem.id : null;
|
||||
let searchId = draftKind === "search" ? null : selectedItem?.kind === "search" ? selectedItem.id : null;
|
||||
|
||||
if (!searchId) {
|
||||
const search = await createSearch();
|
||||
const search = await createSearch({
|
||||
query,
|
||||
title: query.slice(0, 80),
|
||||
});
|
||||
searchId = search.id;
|
||||
setDraftKind(null);
|
||||
setSelectedItem({ kind: "search", id: searchId });
|
||||
}
|
||||
|
||||
@@ -542,6 +516,7 @@ export default function App() {
|
||||
setSelectedItem(null);
|
||||
setSelectedChat(null);
|
||||
setSelectedSearch(null);
|
||||
setDraftKind(null);
|
||||
setComposer("");
|
||||
setError(null);
|
||||
};
|
||||
@@ -638,7 +613,10 @@ export default function App() {
|
||||
"mb-1 w-full rounded-lg px-3 py-2 text-left transition",
|
||||
active ? "bg-slate-700 text-slate-50" : "text-slate-200 hover:bg-slate-800"
|
||||
)}
|
||||
onClick={() => setSelectedItem({ kind: item.kind, id: item.id })}
|
||||
onClick={() => {
|
||||
setDraftKind(null);
|
||||
setSelectedItem({ kind: item.kind, id: item.id });
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
Reference in New Issue
Block a user