From 0ce7c916ffcbf6515c3da521775c72861bddd53c Mon Sep 17 00:00:00 2001 From: yxshv Date: Mon, 15 Apr 2024 01:57:39 +0530 Subject: [PATCH] add profile and fix drawer scroll --- apps/web/src/app/api/chat/route.ts | 64 +++++------ apps/web/src/app/api/getCount/route.ts | 4 +- apps/web/src/app/globals.css | 11 ++ apps/web/src/app/layout.tsx | 1 - apps/web/src/components/Main.tsx | 84 +++++++++++++-- apps/web/src/components/MemoryDrawer.tsx | 22 ++-- .../components/Sidebar/AddMemoryDialog.tsx | 10 +- apps/web/src/components/Sidebar/index.tsx | 102 +++++++++++++++++- apps/web/src/components/ui/dialog.tsx | 6 +- 9 files changed, 241 insertions(+), 63 deletions(-) diff --git a/apps/web/src/app/api/chat/route.ts b/apps/web/src/app/api/chat/route.ts index c78c9484..374f39cd 100644 --- a/apps/web/src/app/api/chat/route.ts +++ b/apps/web/src/app/api/chat/route.ts @@ -69,39 +69,43 @@ export async function POST(req: NextRequest) { }); } - const resp = await fetch( - `https://cf-ai-backend.dhravya.workers.dev/chat?q=${query}&user=${session.user.email ?? session.user.name}&sourcesOnly=${sourcesOnly}&spaces=${spaces}`, - { - headers: { - "X-Custom-Auth-Key": env.BACKEND_SECURITY_KEY, - }, - method: "POST", - body: JSON.stringify({ - chatHistory: chatHistory.chatHistory ?? [], - }), - }, - ); + try { + const resp = await fetch( + `https://cf-ai-backend.dhravya.workers.dev/chat?q=${query}&user=${session.user.email ?? session.user.name}&sourcesOnly=${sourcesOnly}&spaces=${spaces}`, + { + headers: { + "X-Custom-Auth-Key": env.BACKEND_SECURITY_KEY, + }, + method: "POST", + body: JSON.stringify({ + chatHistory: chatHistory.chatHistory ?? [], + }), + }, + ); - console.log("sourcesOnly", sourcesOnly); + console.log("sourcesOnly", sourcesOnly); - if (sourcesOnly == "true") { - const data = await resp.json(); - console.log("data", data); - return new Response(JSON.stringify(data), { status: 200 }); - } + if (sourcesOnly == "true") { + const data = await resp.json(); + console.log("data", data); + return new Response(JSON.stringify(data), { status: 200 }); + } - if (resp.status !== 200 || !resp.ok) { - const errorData = await resp.json(); - console.log(errorData); - return new Response( - JSON.stringify({ message: "Error in CF function", error: errorData }), - { status: resp.status }, - ); - } + if (resp.status !== 200 || !resp.ok) { + const errorData = await resp.json(); + console.log(errorData); + return new Response( + JSON.stringify({ message: "Error in CF function", error: errorData }), + { status: resp.status }, + ); + } - // Stream the response back to the client - const { readable, writable } = new TransformStream(); - resp && resp.body!.pipeTo(writable); + // Stream the response back to the client + const { readable, writable } = new TransformStream(); + resp && resp.body!.pipeTo(writable); + + return new Response(readable, { status: 200 }); + } catch { + } - return new Response(readable, { status: 200 }); } diff --git a/apps/web/src/app/api/getCount/route.ts b/apps/web/src/app/api/getCount/route.ts index 3238e58a..9fe54f78 100644 --- a/apps/web/src/app/api/getCount/route.ts +++ b/apps/web/src/app/api/getCount/route.ts @@ -1,5 +1,5 @@ import { db } from "@/server/db"; -import { and, eq, sql } from "drizzle-orm"; +import { and, eq, ne, sql } from "drizzle-orm"; import { sessions, storedContent, users } from "@/server/db/schema"; import { type NextRequest, NextResponse } from "next/server"; @@ -66,7 +66,7 @@ export async function GET(req: NextRequest) { .where( and( eq(storedContent.user, session.user.id), - eq(storedContent.type, "page"), + ne(storedContent.type, "twitter-bookmark"), ), ); diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index e4523452..9a543be6 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -57,6 +57,17 @@ body { padding-bottom: 15dvh; } +.bottom-padding { + bottom: 20vh; + bottom: 20dvh; +} + +@media (min-width: 768px) { + .bottom-padding { + bottom: 0; + } +} + .chat-answer code { @apply bg-rgray-3 text-wrap rounded-md border border-rgray-5 p-1 text-sm text-rgray-11; } diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index e5a447dc..b57c3d9c 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -2,7 +2,6 @@ import type { Metadata } from "next"; import { Roboto, Inter } from "next/font/google"; import "./globals.css"; -const roboto = Roboto({ weight: ["300", "400", "500"], subsets: ["latin"] }); const inter = Inter({ weight: ["300", "400", "500"], subsets: ["latin"] }); export const metadata: Metadata = { diff --git a/apps/web/src/components/Main.tsx b/apps/web/src/components/Main.tsx index 68ee8d9f..79225eb5 100644 --- a/apps/web/src/components/Main.tsx +++ b/apps/web/src/components/Main.tsx @@ -45,6 +45,8 @@ export default function Main({ sidebarOpen }: { sidebarOpen: boolean }) { const [selectedSpaces, setSelectedSpaces] = useState([]); + const [isStreaming, setIsStreaming] = useState(false) + useEffect(() => { const search = searchParams.get("q"); if (search && search.trim().length > 0) { @@ -241,6 +243,8 @@ export default function Main({ sidebarOpen }: { sidebarOpen: boolean }) { return; } + setIsStreaming(true) + if (response.body) { let reader = response.body?.getReader(); let decoder = new TextDecoder("utf-8"); @@ -259,14 +263,24 @@ export default function Main({ sidebarOpen }: { sidebarOpen: boolean }) { return reader?.read().then(processText); }); + } }; - const onSend = async () => { + const onSend = () => { + if (value.trim().length < 1) return setLayout("chat"); - await getSearchResults(); + getSearchResults(); }; + function onValueChange(e: React.ChangeEvent) { + const value = e.target.value; + setValue(value); + const lines = countLines(e.target); + e.target.rows = Math.min(5, lines); + } + + return ( <> @@ -284,6 +298,7 @@ export default function Main({ sidebarOpen }: { sidebarOpen: boolean }) { /> ) : (
- { + textArea.current?.querySelector("textarea")?.focus(); + }} + side="top" + align="start" + className="bg-[#252525] mr-auto md:hidden" + selectedSpaces={selectedSpaces} + setSelectedSpaces={setSelectedSpaces} + /> + { + if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) { + onSend(); + } + }, + }} + > +
+ + { + textArea.current?.querySelector("textarea")?.focus(); + }} + className="hidden md:flex" + selectedSpaces={selectedSpaces} + setSelectedSpaces={setSelectedSpaces} + /> + +
+
+ +
-
- {width <= 768 && } -
+ + )} + {width <= 768 && }
); @@ -388,7 +454,7 @@ export function Chat({ "sidebar relative flex w-full flex-col items-end gap-5 px-5 pt-5 transition-[padding-left,padding-top,padding-right] delay-200 duration-200 md:items-center md:gap-10 md:px-72 [&[data-sidebar-open='true']]:pr-10 [&[data-sidebar-open='true']]:delay-0 md:[&[data-sidebar-open='true']]:pl-[calc(2.5rem+30vw)]", )} > -
+
{chatHistory.map((msg, i) => ( {msg.question} @@ -404,12 +470,12 @@ export function Chat({ ))}
-
+
-
+
{ diff --git a/apps/web/src/components/MemoryDrawer.tsx b/apps/web/src/components/MemoryDrawer.tsx index f1ca5d47..a71d3d19 100644 --- a/apps/web/src/components/MemoryDrawer.tsx +++ b/apps/web/src/components/MemoryDrawer.tsx @@ -32,16 +32,18 @@ export function MemoryDrawer({ className, hide = false, ...props }: Props) { )} handle={false} > - - + +
+ +
diff --git a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx index 1406925c..63f0d122 100644 --- a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx +++ b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx @@ -26,7 +26,7 @@ export function AddMemoryPage({ closeDialog, defaultSpaces, onAdd }: { closeDial const [selectedSpacesId, setSelectedSpacesId] = useState(defaultSpaces ?? []); return ( -
+
Add a web page to memory @@ -133,7 +133,7 @@ export function NoteAddPage({ closeDialog, defaultSpaces, onAdd }: { closeDialog } return ( -
+
void, } return ( -
+
Add a space @@ -376,7 +376,7 @@ export function AddExistingMemoryToSpace({ const [selected, setSelected] = useState([]); return ( -
+
Add an existing memory to {space.title} diff --git a/apps/web/src/components/Sidebar/index.tsx b/apps/web/src/components/Sidebar/index.tsx index f87d516b..f1a25a85 100644 --- a/apps/web/src/components/Sidebar/index.tsx +++ b/apps/web/src/components/Sidebar/index.tsx @@ -1,12 +1,12 @@ "use client"; import { MemoryIcon } from "../../assets/Memories"; -import { Trash2, User2 } from "lucide-react"; +import { Box, LogOut, Trash2, User2 } from "lucide-react"; import React, { useEffect, useState } from "react"; import { MemoriesBar } from "./MemoriesBar"; import { AnimatePresence, motion } from "framer-motion"; import { Bin } from "@/assets/Bin"; import { Avatar, AvatarFallback, AvatarImage } from "@radix-ui/react-avatar"; -import { useSession } from "next-auth/react"; +import { signOut, useSession } from "next-auth/react"; import MessagePoster from "@/app/MessagePoster"; export type MenuItem = { @@ -61,6 +61,7 @@ export default function Sidebar({
), label: "Profile", + content: }, ]; @@ -88,6 +89,7 @@ export default function Sidebar({ setSelectedItem={setSelectedItem} />
+ {/* + */}
), + content: }} selectedItem={selectedItem} setSelectedItem={setSelectedItem} /> - + {/* */}
{selectedItem && {Subbar}} @@ -184,3 +188,95 @@ export function SubSidebar({ children }: { children?: React.ReactNode }) { ); } + +export function ProfileTab({ open }: { open: boolean }) { + + const { data: session } = useSession() + + const [tweetStat, setTweetStat] = useState<[number, number] | null>(); + const [memoryStat, setMemoryStat] = useState<[number, number] | null>(); + + const [loading, setLoading] = useState(true) + + useEffect(() => { + fetch("/api/getCount").then(async resp => { + const data = await resp.json() as any; + setTweetStat([data.tweetsCount, data.tweetsLimit]) + setMemoryStat([data.pageCount, data.pageLimit]) + setLoading(false) + }) + }, [open]) + + return ( +
+
+

Profile

+
+ { + (e.target as HTMLImageElement).src = "/icons/white_without_bg.png" + }} + /> +
+

{session?.user?.name}

+ + {session?.user?.email} + + +
+
+
+
+

+ + Storage +

+ {loading ? ( +
+
+
+
+ ) : ( + <> +
+

+ Memories +
+ {memoryStat?.join("/")} +
+

+
+
0 ? '5%' : '0%' + }} className="rounded-full h-full bg-rgray-5" /> +
+
+
+

+ Tweets +
+ {tweetStat?.join("/")} +
+

+
+
0 ? '5%' : '0%' + }} className="rounded-full h-full bg-rgray-5" /> +
+
+ + )} +
+
+ ) +} diff --git a/apps/web/src/components/ui/dialog.tsx b/apps/web/src/components/ui/dialog.tsx index bc36e749..12ccd5ea 100644 --- a/apps/web/src/components/ui/dialog.tsx +++ b/apps/web/src/components/ui/dialog.tsx @@ -38,7 +38,7 @@ const DialogContent = React.forwardRef< ) => (
) => (