Skip to content

Commit 0ab55b3

Browse files
committed
Merge branch 'feat/revamp-ui'
2 parents 2c93b73 + 6e246f5 commit 0ab55b3

File tree

9 files changed

+841
-79
lines changed

9 files changed

+841
-79
lines changed

characters/Nayari.character.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Nayari",
3-
"clients": ["direct","twitter"],
3+
"clients": ["twitter"],
44
"modelProvider": "openrouter",
55
"settings": {
66
"voice": {

client/public/website_nayari.jpg

760 KB
Loading

client/src/components/chat.tsx

+11-9
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ interface ExtraContentFields {
3131

3232
type ContentWithUser = Content & ExtraContentFields;
3333

34-
export default function Page({ agentId }: { agentId: UUID }) {
34+
export default function Page({ agentId, className }: { agentId: UUID, className?: string }) {
3535
const { toast } = useToast();
3636
const [selectedFile, setSelectedFile] = useState<File | null>(null);
3737
const [input, setInput] = useState("");
@@ -72,7 +72,7 @@ export default function Page({ agentId }: { agentId: UUID }) {
7272
const attachments: IAttachment[] | undefined = selectedFile
7373
? [
7474
{
75-
url: URL.createObjectURL(selectedFile),
75+
url: selectedFile ? URL.createObjectURL(selectedFile) : '',
7676
contentType: selectedFile.type,
7777
title: selectedFile.name,
7878
},
@@ -165,13 +165,15 @@ export default function Page({ agentId }: { agentId: UUID }) {
165165
});
166166

167167
return (
168-
<div className="flex flex-col w-full h-[calc(100dvh)] p-4">
169-
<div className="flex-1 overflow-y-auto">
170-
<ChatMessageList ref={messagesContainerRef}>
168+
<div
169+
className={cn("flex flex-col w-full h-full relative", className)}
170+
>
171+
<div className="absolute inset-0 overflow-y-auto px-4 pt-4 pb-[180px]">
172+
<ChatMessageList ref={messagesContainerRef} className="h-full">
171173
{transitions((styles, message) => {
172174
const variant = getMessageVariant(message?.user);
173175
return (
174-
// @ts-expect-error
176+
// @ts-expect-error animated.div from react-spring has incompatible types with ChatBubble props
175177
<animated.div
176178
style={styles}
177179
className="flex flex-col gap-2 p-4"
@@ -268,7 +270,7 @@ export default function Page({ agentId }: { agentId: UUID }) {
268270
})}
269271
</ChatMessageList>
270272
</div>
271-
<div className="px-4 pb-4">
273+
<div className="fixed bottom-0 left-0 right-0 px-4 pb-4 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/50">
272274
<form
273275
ref={formRef}
274276
onSubmit={handleSendMessage}
@@ -286,7 +288,7 @@ export default function Page({ agentId }: { agentId: UUID }) {
286288
<X />
287289
</Button>
288290
<img
289-
src={URL.createObjectURL(selectedFile)}
291+
src={selectedFile ? URL.createObjectURL(selectedFile) : ''}
290292
height="100%"
291293
width="100%"
292294
className="aspect-square object-contain w-16"
@@ -353,4 +355,4 @@ export default function Page({ agentId }: { agentId: UUID }) {
353355
</div>
354356
</div>
355357
);
356-
}
358+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { useEffect, useRef } from "react";
2+
3+
export function useAutoScroll(ref: React.RefObject<HTMLDivElement>) {
4+
const shouldScrollRef = useRef(true);
5+
const prevScrollHeightRef = useRef(0);
6+
7+
useEffect(() => {
8+
const element = ref.current;
9+
if (!element) return;
10+
11+
const handleScroll = () => {
12+
const { scrollTop, scrollHeight, clientHeight } = element;
13+
// Check if user has scrolled up
14+
shouldScrollRef.current = scrollTop + clientHeight >= scrollHeight - 100;
15+
prevScrollHeightRef.current = scrollHeight;
16+
};
17+
18+
element.addEventListener("scroll", handleScroll);
19+
return () => element.removeEventListener("scroll", handleScroll);
20+
}, [ref]);
21+
22+
useEffect(() => {
23+
const element = ref.current;
24+
if (!element) return;
25+
26+
// Only auto-scroll if we're at the bottom or new content was added
27+
if (shouldScrollRef.current || element.scrollHeight > prevScrollHeightRef.current) {
28+
element.scrollTop = element.scrollHeight;
29+
prevScrollHeightRef.current = element.scrollHeight;
30+
}
31+
}); // No dependencies to run on every render, like Svelte's $effect
32+
33+
return null;
34+
}

client/src/routes/chat.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ export default function AgentRoute() {
2525
</div>
2626

2727
{/* Chat Interface */}
28-
<div className="flex-1 overflow-hidden">
29-
<Chat agentId={agentId} />
28+
<div className="flex-1 overflow-hidden flex flex-col relative">
29+
<Chat agentId={agentId} className="absolute inset-0" />
3030
</div>
3131
</div>
3232
);
33-
}
33+
}

0 commit comments

Comments
 (0)