Skip to content

Commit 336fb91

Browse files
committed
use helper for threadId creation
1 parent 0750845 commit 336fb91

File tree

3 files changed

+14
-70
lines changed

3 files changed

+14
-70
lines changed

example/ui/chat/ChatBasic.tsx

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,55 +8,30 @@ import {
88
useThreadMessages,
99
type UIMessage,
1010
} from "@convex-dev/agent/react";
11-
import { useCallback, useEffect, useState } from "react";
11+
import { useState } from "react";
1212
import { cn } from "../lib/utils";
13-
14-
function getThreadIdFromHash() {
15-
return window.location.hash.replace(/^#/, "") || undefined;
16-
}
13+
import { useDemoThread } from "@/hooks/use-demo-thread";
1714

1815
export default function ChatBasic() {
19-
const createThread = useMutation(api.threads.createNewThread);
20-
const [threadId, setThreadId] = useState<string | undefined>(
21-
typeof window !== "undefined" ? getThreadIdFromHash() : undefined,
22-
);
16+
const {
17+
threadId,
18+
resetThread: newThread,
19+
setThreadId,
20+
} = useDemoThread("Basic Chat Example");
2321

2422
// Fetch thread title if threadId exists
2523
const threadDetails = useQuery(
2624
api.threads.getThreadDetails,
2725
threadId ? { threadId } : "skip",
2826
);
2927

30-
// Fetch all threads (internal API)
31-
// For demo, hardcode userId as in backend
28+
// Fetch all threads
3229
const threads = usePaginatedQuery(
3330
api.threads.listThreads,
3431
{},
3532
{ initialNumItems: 20 },
3633
);
3734

38-
// Listen for hash changes
39-
useEffect(() => {
40-
function onHashChange() {
41-
setThreadId(getThreadIdFromHash());
42-
}
43-
window.addEventListener("hashchange", onHashChange);
44-
return () => window.removeEventListener("hashchange", onHashChange);
45-
}, []);
46-
47-
// Reset handler: create a new thread and update hash
48-
const newThread = useCallback(() => {
49-
void createThread({ title: "Fresh thread" }).then((newId) => {
50-
window.location.hash = newId;
51-
setThreadId(newId);
52-
});
53-
}, [createThread]);
54-
55-
// On mount or when threadId changes, if no threadId, create one and set hash
56-
useEffect(() => {
57-
if (!threadId) newThread();
58-
}, [newThread, threadId]);
59-
6035
return (
6136
<div className="h-full flex flex-col">
6237
<header className="bg-white/80 backdrop-blur-sm p-4 flex justify-between items-center border-b">
@@ -106,7 +81,7 @@ export default function ChatBasic() {
10681
</div>
10782
<div className="px-4 py-2">
10883
<button
109-
onClick={newThread}
84+
onClick={() => void newThread()}
11085
className="w-full flex justify-center items-center gap-2 py-2 rounded-lg bg-blue-600 text-white hover:bg-blue-700 transition font-semibold shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-400"
11186
type="button"
11287
>

example/ui/chat/ChatStreaming.tsx

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,12 @@ import {
77
useUIMessages,
88
type UIMessage,
99
} from "@convex-dev/agent/react";
10-
import { useCallback, useEffect, useRef, useState } from "react";
10+
import { useEffect, useRef, useState } from "react";
1111
import { cn } from "@/lib/utils";
12-
13-
function getThreadIdFromHash() {
14-
return window.location.hash.replace(/^#/, "") || undefined;
15-
}
12+
import { useDemoThread } from "@/hooks/use-demo-thread";
1613

1714
export default function ChatStreaming() {
18-
const createThread = useMutation(api.threads.createNewThread);
19-
const [threadId, setThreadId] = useState<string | undefined>(
20-
typeof window !== "undefined" ? getThreadIdFromHash() : undefined,
21-
);
22-
23-
// Listen for hash changes
24-
useEffect(() => {
25-
function onHashChange() {
26-
setThreadId(getThreadIdFromHash());
27-
}
28-
window.addEventListener("hashchange", onHashChange);
29-
return () => window.removeEventListener("hashchange", onHashChange);
30-
}, []);
31-
32-
const resetThread = useCallback(() => {
33-
void createThread({
34-
title: "Streaming Chat Example",
35-
}).then((newId) => {
36-
window.location.hash = newId;
37-
setThreadId(newId);
38-
});
39-
}, [createThread]);
40-
41-
// On mount or when threadId changes, if no threadId, create one and set hash
42-
useEffect(() => {
43-
if (!threadId) {
44-
void resetThread();
45-
}
46-
}, [resetThread, threadId]);
15+
const { threadId, resetThread } = useDemoThread("Streaming Chat Example");
4716

4817
return (
4918
<>
@@ -54,7 +23,7 @@ export default function ChatStreaming() {
5423
</header>
5524
<div className="h-[calc(100vh-8rem)] flex flex-col bg-gray-50">
5625
{threadId ? (
57-
<Story threadId={threadId} reset={resetThread} />
26+
<Story threadId={threadId} reset={() => void resetThread()} />
5827
) : (
5928
<div className="flex-1 flex items-center justify-center text-gray-500">
6029
Loading...

example/ui/hooks/use-demo-thread.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export function useDemoThread(title: string) {
3333
}
3434
}, [resetThread, threadId]);
3535

36-
return { threadId, resetThread };
36+
return { threadId, resetThread, setThreadId };
3737
}
3838

3939
function getThreadIdFromHash() {

0 commit comments

Comments
 (0)