diff options
| author | Mahesh Sanikommmu <[email protected]> | 2025-09-03 19:00:57 -0700 |
|---|---|---|
| committer | Mahesh Sanikommmu <[email protected]> | 2025-09-03 19:00:57 -0700 |
| commit | 497986524bf059b975dd38ee012ceb7b5b68f88b (patch) | |
| tree | 54f2df594cae016a6c57d04cac43b14ab1f851c6 | |
| parent | updated the text input (diff) | |
| download | supermemory-mahesh/app-layout.tar.xz supermemory-mahesh/app-layout.zip | |
few more changesmahesh/app-layout
| -rw-r--r-- | apps/web/app/layout.tsx | 10 | ||||
| -rw-r--r-- | apps/web/app/page.tsx | 2 | ||||
| -rw-r--r-- | apps/web/components/chat-inline.tsx | 53 | ||||
| -rw-r--r-- | apps/web/components/memory-list-view.tsx | 4 | ||||
| -rw-r--r-- | apps/web/components/views/chat/chat-messages.tsx | 117 |
5 files changed, 103 insertions, 83 deletions
diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 9f8c24a1..9da01b39 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,5 +1,5 @@ import type { Metadata } from "next"; -import { Inter, JetBrains_Mono } from "next/font/google"; +import { Inter, JetBrains_Mono, Space_Grotesk } from "next/font/google"; import "../globals.css"; import "@ui/globals.css"; import { AuthProvider } from "@lib/auth-context"; @@ -25,6 +25,12 @@ const mono = JetBrains_Mono({ variable: "--font-mono", }); +const spaceGrotesk = Space_Grotesk({ + subsets: ["latin"], + variable: "--font-serif", +}); + + export const metadata: Metadata = { metadataBase: new URL("https://app.supermemory.ai"), description: "Your memories, wherever you are", @@ -39,7 +45,7 @@ export default function RootLayout({ return ( <html lang="en" suppressHydrationWarning> <body - className={`${sans.variable} ${mono.variable} antialiased`} + className={`${sans.variable} ${mono.variable} ${spaceGrotesk.variable} antialiased`} > <ThemeProvider attribute="class" defaultTheme="dark" enableSystem> <AutumnProvider diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx index a9a79e35..9952a5c9 100644 --- a/apps/web/app/page.tsx +++ b/apps/web/app/page.tsx @@ -142,7 +142,7 @@ const MemoryAppPage = () => { }, []); return ( - <div> + <div className="font-sans"> <AppHeader /> <MemoryListView diff --git a/apps/web/components/chat-inline.tsx b/apps/web/components/chat-inline.tsx index fe18f5d2..515417eb 100644 --- a/apps/web/components/chat-inline.tsx +++ b/apps/web/components/chat-inline.tsx @@ -44,34 +44,43 @@ export function ChatInline() { <div className="w-full max-w-4xl"> <div className="text-start mb-6"> <h2 className="text-xl font-medium text-foreground mb-2"> - Night owl, Mahesh + Good evening, Mahesh </h2> </div> <div className="relative"> - <div className="flex flex-col border border-border rounded-lg shadow-sm hover:shadow-md transition-shadow min-h-24"> - <textarea - value={message} - onChange={(e) => setMessage(e.target.value)} - onKeyDown={handleKeyDown} - placeholder="Ask your supermemory..." - id="chat-inline-textarea" - className="flex-1 bg-transparent text-foreground placeholder:text-muted-foreground focus:outline-none text-base resize-none px-4 py-3" - rows={2} - /> - <div className="flex w-full rounded-b-lg justify-end"> - <button - onClick={handleSend} - disabled={!message.trim()} - className="p-2 mr-1 rounded-lg disabled:text-muted-foreground disabled:cursor-not-allowed transition-colors flex-shrink-0" - type="button" - > - <ArrowUp className="w-6 h-6 bg-black rounded-full p-1 text-white" /> - </button> - </div> + <div className="bg-gradient-to-r from-blue-500 to-blue-600 p-[2px] rounded-3xl shadow-lg"> + <form + className="flex flex-col items-end gap-3 bg-white rounded-[22px] p-3" + onSubmit={(e) => { + e.preventDefault() + if (!message.trim()) return + handleSend() + }} + > + <textarea + value={message} + onChange={(e) => setMessage(e.target.value)} + onKeyDown={handleKeyDown} + placeholder="Yo, describe my fav destination..." + className="w-full text-black placeholder-black/40 rounded-md outline-none resize-none text-base leading-relaxed" + rows={2} + /> + <div className="flex items-center gap-2 w-full justify-between"> + <div className="flex items-center gap-2" /> + <button + onClick={handleSend} + disabled={!message.trim()} + className="text-white border-0 rounded-lg size-10 flex items-center justify-center transition-colors disabled:opacity-50 disabled:cursor-not-allowed" + type="button" + > + <img src="/icons/send.svg" alt="Send" className="w-8 h-8" /> + </button> + </div> + </form> </div> </div> </div> </div> </div> - ); + ) } diff --git a/apps/web/components/memory-list-view.tsx b/apps/web/components/memory-list-view.tsx index d137e134..8755c33e 100644 --- a/apps/web/components/memory-list-view.tsx +++ b/apps/web/components/memory-list-view.tsx @@ -52,7 +52,7 @@ const DocumentCard = memo( return ( <Card - className="h-full mx-4 p-4 transition-all cursor-pointer group relative overflow-hidden bg-card gap-2 md:w-full" + className="h-full mx-4 p-4 transition-all cursor-pointer group relative overflow-hidden bg-card shadow-lg gap-2 md:w-full hover:shadow-xl" onClick={() => { analytics.documentCardClicked(); onOpenDetails(document); @@ -61,7 +61,7 @@ const DocumentCard = memo( <CardHeader className="relative z-10 px-0"> <div className="flex items-center justify-between gap-2"> <div className="flex items-center gap-1"> - {getDocumentIcon(document.type, "w-4 h-4 flex-shrink-0")} + {/*{getDocumentIcon(document.type, "w-4 h-4 flex-shrink-0")}*/} <p className={cn( "text-sm font-medium line-clamp-1", diff --git a/apps/web/components/views/chat/chat-messages.tsx b/apps/web/components/views/chat/chat-messages.tsx index 4e32d075..65207548 100644 --- a/apps/web/components/views/chat/chat-messages.tsx +++ b/apps/web/components/views/chat/chat-messages.tsx @@ -345,25 +345,26 @@ export function ChatMessages() { <div className="h-full mx-auto flex flex-col max-w-3xl"> <div className="flex-1 relative"> <div - className="flex flex-col gap-2 absolute inset-0 overflow-y-auto px-4 pt-4 pb-7 scroll-pb-7" + className="flex flex-col gap-2 absolute inset-0 overflow-y-auto px-4 pt-4 pb-7 scroll-pb-7 custom-scrollbar" onScroll={onScroll} ref={scrollContainerRef} > {messages.map((message) => ( <div className={cn( - "flex", - message.role === "user" ? "items-center gap-2" : "flex-col", + "flex my-2", + message.role === "user" + ? "items-center flex-row-reverse gap-2" + : "flex-col", )} key={message.id} > - {message.role === "user" && ( - <UserIcon className="size-4 text-muted-foreground" /> - )} <div className={cn( - "flex flex-col gap-2 max-w-4/5 rounded-full", - message.role === "user" ? "bg-white/10 px-3 py-1.5" : "", + "flex flex-col gap-2 max-w-4/5", + message.role === "user" + ? "bg-white/10 px-3 py-1.5 border border-black/20 rounded-lg" + : "", )} > {message.parts @@ -372,14 +373,14 @@ export function ChatMessages() { part.type, ), ) - .map((part) => { + .map((part, index) => { switch (part.type) { case "text": return ( - <div key={message.id + part.type}> + <div key={`${message.id}-${part.type}-${index}`}> <Streamdown>{part.text}</Streamdown> </div> - ); + ) case "tool-searchMemories": { switch (part.state) { case "input-available": @@ -387,46 +388,46 @@ export function ChatMessages() { return ( <div className="text-sm flex items-center gap-2 text-muted-foreground" - key={message.id + part.type} + key={`${message.id}-${part.type}-${index}`} > <Spinner className="size-4" /> Searching memories... </div> - ); + ) case "output-error": return ( <div className="text-sm flex items-center gap-2 text-muted-foreground" - key={message.id + part.type} + key={`${message.id}-${part.type}-${index}`} > <X className="size-4" /> Error recalling memories </div> - ); + ) case "output-available": { - const output = part.output; + const output = part.output const foundCount = typeof output === "object" && output !== null && "count" in output ? Number(output.count) || 0 - : 0; + : 0 // @ts-expect-error const results = Array.isArray(output?.results) ? // @ts-expect-error output.results - : []; + : [] return ( <ExpandableMemories foundCount={foundCount} - key={message.id + part.type} + key={`${message.id}-${part.type}-${index}`} results={results} /> - ); + ) } default: - return null; + return null } } case "tool-addMemory": { @@ -435,44 +436,44 @@ export function ChatMessages() { return ( <div className="text-sm flex items-center gap-2 text-muted-foreground" - key={message.id + part.type} + key={`${message.id}-${part.type}-${index}`} > <Spinner className="size-4" /> Adding memory... </div> - ); + ) case "output-error": return ( <div className="text-sm flex items-center gap-2 text-muted-foreground" - key={message.id + part.type} + key={`${message.id}-${part.type}-${index}`} > <X className="size-4" /> Error adding memory </div> - ); + ) case "output-available": return ( <div className="text-sm flex items-center gap-2 text-muted-foreground" - key={message.id + part.type} + key={`${message.id}-${part.type}-${index}`} > <Check className="size-4" /> Memory added </div> - ); + ) case "input-streaming": return ( <div className="text-sm flex items-center gap-2 text-muted-foreground" - key={message.id + part.type} + key={`${message.id}-${part.type}-${index}`} > <Spinner className="size-4" /> Adding memory... </div> - ); + ) default: - return null; + return null } } default: - return null; + return null } })} </div> @@ -486,8 +487,8 @@ export function ChatMessages() { .filter((p) => p.type === "text") ?.map((p) => (p as any).text) .join("\n") ?? "", - ); - toast.success("Copied to clipboard"); + ) + toast.success("Copied to clipboard") }} size="icon" variant="ghost" @@ -526,8 +527,8 @@ export function ChatMessages() { : "opacity-0 scale-95 pointer-events-none", )} onClick={() => { - enableAutoScroll(); - scrollToBottom("smooth"); + enableAutoScroll() + scrollToBottom("smooth") }} size="sm" type="button" @@ -540,32 +541,32 @@ export function ChatMessages() { <div className="px-4 pb-4 pt-1 relative flex-shrink-0"> <div className="bg-gradient-to-r from-blue-500 to-blue-600 p-[3px] rounded-3xl shadow-lg"> <div className="flex p-2 gap-2"> - <div className="backdrop-blur-md bg-white/10 border border-white/20 rounded-xl px-4 py-2 text-white text-sm hover:bg-white/15 transition-all duration-200 cursor-pointer shadow-lg"> + <div className="backdrop-blur-md bg-white/10 border border-white/20 rounded-lg p-2 text-white text-xs hover:bg-white/15 transition-all duration-200 cursor-pointer shadow-lg"> Suggest me best hotels in Liechtenstein </div> - <div className="backdrop-blur-md bg-white/10 border border-white/20 rounded-xl px-4 py-2 text-white/90 text-sm hover:bg-white/15 transition-all duration-200 cursor-pointer shadow-lg"> + <div className="backdrop-blur-md bg-white/10 border border-white/20 rounded-lg p-2 text-white/90 text-xs hover:bg-white/15 transition-all duration-200 cursor-pointer shadow-lg"> Prepare a full itinerary to Liechtenstein </div> </div> <form - className="flex flex-col items-end gap-3 bg-white rounded-[22px] p-2" + className="flex flex-col items-end gap-3 bg-white rounded-[22px] p-3" onSubmit={(e) => { - e.preventDefault(); - if (status === "submitted") return; + e.preventDefault() + if (status === "submitted") return if (status === "streaming") { - stop(); - return; + stop() + return } if (input.trim()) { - enableAutoScroll(); - scrollToBottom("auto"); - sendMessage({ text: input }); - setInput(""); + enableAutoScroll() + scrollToBottom("auto") + sendMessage({ text: input }) + setInput("") } }} > <textarea - className="w-full text-black placeholder-black/40 rounded-md outline-none resize-none text-base leading-relaxed p-2" + className="w-full text-black placeholder-black/40 rounded-md outline-none resize-none text-base leading-relaxed" disabled={status === "submitted"} onChange={(e) => setInput(e.target.value)} placeholder="Yo, describe my fav destination..." @@ -573,12 +574,12 @@ export function ChatMessages() { value={input} onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { - e.preventDefault(); + e.preventDefault() if (input.trim() && status !== "submitted") { - enableAutoScroll(); - scrollToBottom("auto"); - sendMessage({ text: input }); - setInput(""); + enableAutoScroll() + scrollToBottom("auto") + sendMessage({ text: input }) + setInput("") } } }} @@ -592,14 +593,18 @@ export function ChatMessages() { type="button" variant="outline" > - <img src="/icons/attach.svg" alt="Attach" className="w-5 h-5" /> + <img + src="/icons/attach.svg" + alt="Attach" + className="w-5 h-5" + /> </Button> <Button className="bg-white/20 hover:bg-white/30 text-black border-[#EBEBEB] rounded-lg px-4 py-2 h-10" type="button" variant="outline" > - <Plus className="size-4 mr-2" /> + <Plus className="size-4" /> Link Project </Button> </div> @@ -612,7 +617,7 @@ export function ChatMessages() { variant="ghost" > {status === "ready" ? ( - <img src="/icons/send.svg" alt="Send" className="w-7 h-7" /> + <img src="/icons/send.svg" alt="Send" className="w-8 h-8" /> ) : status === "submitted" ? ( <Spinner className="size-5" /> ) : ( @@ -624,5 +629,5 @@ export function ChatMessages() { </div> </div> </div> - ); + ) } |