diff options
| author | Dhravya <[email protected]> | 2024-04-13 09:14:37 -0700 |
|---|---|---|
| committer | Dhravya <[email protected]> | 2024-04-13 09:14:37 -0700 |
| commit | 75cae41f2aebd6343ce95cd0b6910870724ed374 (patch) | |
| tree | 44c9a92202801aea87cdaffd51bcd8b836fa69ea /apps/web/src/components | |
| parent | CloudflareAI for better streaming (diff) | |
| download | supermemory-75cae41f2aebd6343ce95cd0b6910870724ed374.tar.xz supermemory-75cae41f2aebd6343ce95cd0b6910870724ed374.zip | |
merge
Diffstat (limited to 'apps/web/src/components')
| -rw-r--r-- | apps/web/src/components/Sidebar/AddMemoryDialog.tsx | 31 | ||||
| -rw-r--r-- | apps/web/src/components/Sidebar/MemoriesBar.tsx | 232 |
2 files changed, 139 insertions, 124 deletions
diff --git a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx index 886507ff..08b9a750 100644 --- a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx +++ b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx @@ -153,37 +153,6 @@ export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) { } export function SpaceAddPage({ closeDialog }: { closeDialog: () => void }) { - const [selectedSpacesId, setSelectedSpacesId] = useState<number[]>([]); - - const inputRef = useRef<HTMLInputElement>(null); - const [name, setName] = useState(""); - const [content, setContent] = useState(""); - const [loading, setLoading] = useState(false); - - function check(): boolean { - const data = { - name: name.trim(), - content, - }; - console.log(name); - if (!data.name || data.name.length < 1) { - if (!inputRef.current) { - alert("Please enter a name for the note"); - return false; - } - inputRef.current.value = ""; - inputRef.current.placeholder = "Please enter a title for the note"; - inputRef.current.dataset["error"] = "true"; - setTimeout(() => { - inputRef.current!.placeholder = "Title of the note"; - inputRef.current!.dataset["error"] = "false"; - }, 500); - inputRef.current.focus(); - return false; - } - return true; - } - return ( <div className="md:w-[40vw]"> <DialogHeader> diff --git a/apps/web/src/components/Sidebar/MemoriesBar.tsx b/apps/web/src/components/Sidebar/MemoriesBar.tsx index 769e6296..f671b72f 100644 --- a/apps/web/src/components/Sidebar/MemoriesBar.tsx +++ b/apps/web/src/components/Sidebar/MemoriesBar.tsx @@ -23,7 +23,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "../ui/dropdown-menu"; -import { useEffect, useRef, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { Variant, useAnimate, motion } from "framer-motion"; import { useMemory } from "@/contexts/MemoryContext"; import { SpaceIcon } from "@/assets/Memories"; @@ -42,11 +42,12 @@ import useTouchHold from "@/hooks/useTouchHold"; import { DialogTrigger } from "@radix-ui/react-dialog"; import { AddMemoryPage, NoteAddPage, SpaceAddPage } from "./AddMemoryDialog"; import { ExpandedSpace } from "./ExpandedSpace"; -import { StoredSpace } from "@/server/db/schema"; +import { StoredContent, StoredSpace } from "@/server/db/schema"; +import Image from "next/image"; export function MemoriesBar() { const [parent, enableAnimations] = useAutoAnimate(); - const { spaces, deleteSpace } = useMemory(); + const { spaces, deleteSpace, freeMemories } = useMemory(); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const [addMemoryState, setAddMemoryState] = useState< @@ -124,12 +125,15 @@ export function MemoriesBar() { > {spaces.map((space) => ( <SpaceItem - onDelete={() => deleteSpace(space.id)} + onDelete={() => {}} key={space.id} - onClick={() => setExpandedSpace(space.id)} + //onClick={() => setExpandedSpace(space.id)} {...space} /> ))} + {freeMemories.map((m) => ( + <MemoryItem {...m} key={m.id} /> + ))} </div> </div> ); @@ -145,12 +149,28 @@ const SpaceExitVariant: Variant = { }, }; +export function MemoryItem({ id, title, image }: StoredContent) { + return ( + <div className="hover:bg-rgray-2 has-[[data-state='true']]:bg-rgray-2 has-[[data-space-text]:focus-visible]:bg-rgray-2 has-[[data-space-text]:focus-visible]:ring-rgray-7 [&:has-[[data-space-text]:focus-visible]>[data-more-button]]:opacity-100 relative flex select-none flex-col-reverse items-center justify-center rounded-md p-2 pb-4 text-center font-normal ring-transparent transition has-[[data-space-text]:focus-visible]:outline-none has-[[data-space-text]:focus-visible]:ring-2 md:has-[[data-state='true']]:bg-transparent [&:hover>[data-more-button]]:opacity-100"> + <button data-space-text className="focus-visible:outline-none"> + {title} + </button> + + <div className="flex h-24 w-24 items-center justify-center"> + <img className="h-16 w-16" id={id.toString()} src={image!} /> + </div> + </div> + ); +} + export function SpaceItem({ name, id, onDelete, onClick, }: StoredSpace & { onDelete: () => void; onClick?: () => void }) { + const { cachedMemories } = useMemory(); + const [itemRef, animateItem] = useAnimate(); const { width } = useViewport(); @@ -162,6 +182,10 @@ export function SpaceItem({ }, }); + const spaceMemories = useMemo(() => { + return cachedMemories.filter((m) => m.space === id); + }, [cachedMemories]); + return ( <motion.div ref={itemRef} @@ -176,104 +200,106 @@ export function SpaceItem({ isOpen={moreDropdownOpen} setIsOpen={setMoreDropdownOpen} onDelete={() => { + onDelete(); + return; if (!itemRef.current || width < 768) { onDelete(); return; } - const trash = document.querySelector("#trash")! as HTMLDivElement; - const trashBin = document.querySelector("#trash-button")!; - const trashRect = trashBin.getBoundingClientRect(); - const scopeRect = itemRef.current.getBoundingClientRect(); - const el = document.createElement("div"); - el.style.position = "fixed"; - el.style.top = "0"; - el.style.left = "0"; - el.style.width = "15px"; - el.style.height = "15px"; - el.style.backgroundColor = "var(--gray-7)"; - el.style.zIndex = "60"; - el.style.borderRadius = "50%"; - el.style.transform = "scale(5)"; - el.style.opacity = "0"; - trash.dataset["open"] = "true"; - const initial = { - x: scopeRect.left + scopeRect.width / 2, - y: scopeRect.top + scopeRect.height / 2, - }; - const delta = { - x: - trashRect.left + - trashRect.width / 2 - - scopeRect.left + - scopeRect.width / 2, - y: - trashRect.top + - trashRect.height / 4 - - scopeRect.top + - scopeRect.height / 2, - }; - const end = { - x: trashRect.left + trashRect.width / 2, - y: trashRect.top + trashRect.height / 4, - }; - el.style.offsetPath = `path('M ${initial.x} ${initial.y} Q ${delta.x * 0.01} ${delta.y * 0.01} ${end.x} ${end.y}`; - animateItem(itemRef.current, SpaceExitVariant, { - duration: 0.2, - }).then(() => { - itemRef.current.style.scale = "0"; - onDelete(); - }); - document.body.appendChild(el); - el.animate( - { - transform: ["scale(5)", "scale(1)"], - opacity: [0, 0.3, 1], - }, - { - duration: 200, - easing: "cubic-bezier(0.64, 0.57, 0.67, 1.53)", - fill: "forwards", - }, - ); - el.animate( - { - offsetDistance: ["0%", "100%"], - }, - { - duration: 2000, - easing: "cubic-bezier(0.64, 0.57, 0.67, 1.53)", - fill: "forwards", - delay: 200, - }, - ).onfinish = () => { - el.animate( - { transform: "scale(0)", opacity: 0 }, - { duration: 200, fill: "forwards" }, - ).onfinish = () => { - el.remove(); - }; - }; + // const trash = document.querySelector("#trash")! as HTMLDivElement; + // const trashBin = document.querySelector("#trash-button")!; + // const trashRect = trashBin.getBoundingClientRect(); + // const scopeRect = itemRef.current.getBoundingClientRect(); + // const el = document.createElement("div"); + // el.style.position = "fixed"; + // el.style.top = "0"; + // el.style.left = "0"; + // el.style.width = "15px"; + // el.style.height = "15px"; + // el.style.backgroundColor = "var(--gray-7)"; + // el.style.zIndex = "60"; + // el.style.borderRadius = "50%"; + // el.style.transform = "scale(5)"; + // el.style.opacity = "0"; + // trash.dataset["open"] = "true"; + // const initial = { + // x: scopeRect.left + scopeRect.width / 2, + // y: scopeRect.top + scopeRect.height / 2, + // }; + // const delta = { + // x: + // trashRect.left + + // trashRect.width / 2 - + // scopeRect.left + + // scopeRect.width / 2, + // y: + // trashRect.top + + // trashRect.height / 4 - + // scopeRect.top + + // scopeRect.height / 2, + // }; + // const end = { + // x: trashRect.left + trashRect.width / 2, + // y: trashRect.top + trashRect.height / 4, + // }; + // el.style.offsetPath = `path('M ${initial.x} ${initial.y} Q ${delta.x * 0.01} ${delta.y * 0.01} ${end.x} ${end.y}`; + // animateItem(itemRef.current, SpaceExitVariant, { + // duration: 0.2, + // }).then(() => { + // itemRef.current.style.scale = "0"; + // onDelete(); + // }); + // document.body.appendChild(el); + // el.animate( + // { + // transform: ["scale(5)", "scale(1)"], + // opacity: [0, 0.3, 1], + // }, + // { + // duration: 200, + // easing: "cubic-bezier(0.64, 0.57, 0.67, 1.53)", + // fill: "forwards", + // }, + // ); + // el.animate( + // { + // offsetDistance: ["0%", "100%"], + // }, + // { + // duration: 2000, + // easing: "cubic-bezier(0.64, 0.57, 0.67, 1.53)", + // fill: "forwards", + // delay: 200, + // }, + // ).onfinish = () => { + // el.animate( + // { transform: "scale(0)", opacity: 0 }, + // { duration: 200, fill: "forwards" }, + // ).onfinish = () => { + // el.remove(); + // }; + // }; }} /> - {/* {content.length > 2 ? ( + {spaceMemories.length > 2 ? ( <MemoryWithImages3 className="h-24 w-24" id={id.toString()} - images={content.map((c) => c.image).reverse() as string[]} + images={spaceMemories.map((c) => c.image).reverse() as string[]} /> - ) : content.length === 1 ? ( + ) : spaceMemories.length === 1 ? ( <MemoryWithImage className="h-24 w-24" id={id.toString()} - image={content[0].image!} + image={spaceMemories[0].image!} /> ) : ( <MemoryWithImages2 className="h-24 w-24" id={id.toString()} - images={content.map((c) => c.image).reverse() as string[]} + images={spaceMemories.map((c) => c.image).reverse() as string[]} /> - )} */} + )} </motion.div> ); } @@ -288,7 +314,7 @@ export function SpaceMoreButton({ setIsOpen?: (open: boolean) => void; }) { return ( - <> + <Dialog> <DropdownMenu open={isOpen} onOpenChange={setIsOpen}> <DropdownMenuTrigger asChild> <button @@ -310,16 +336,36 @@ export function SpaceMoreButton({ <Edit3 className="mr-2 h-4 w-4" strokeWidth={1.5} /> Edit </DropdownMenuItem> - <DropdownMenuItem - onClick={onDelete} - className="focus:bg-red-100 focus:text-red-400 dark:focus:bg-red-100/10" - > - <Trash2 className="mr-2 h-4 w-4" strokeWidth={1.5} /> - Move to Trash - </DropdownMenuItem> + <DialogTrigger asChild> + <DropdownMenuItem + onClick={onDelete} + className="focus:bg-red-100 focus:text-red-400 dark:focus:bg-red-100/10" + > + <Trash2 className="mr-2 h-4 w-4" strokeWidth={1.5} /> + Move to Trash + </DropdownMenuItem> + </DialogTrigger> </DropdownMenuContent> </DropdownMenu> - </> + <DialogContent> + <DialogTitle className="text-xl">Are you sure?</DialogTitle> + <DialogDescription className="text-md"> + You will not be able to recover this space + </DialogDescription> + <DialogFooter> + <DialogClose + type={undefined} + onClick={onDelete} + className="ml-auto flex items-center justify-center rounded-md bg-red-500/40 px-3 py-2 transition hover:bg-red-500/60 focus-visible:bg-red-500/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500" + > + Delete + </DialogClose> + <DialogClose className="focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 hover:bg-rgray-4 ml-auto flex items-center justify-center rounded-md px-3 py-2 transition focus-visible:outline-none focus-visible:ring-2"> + Cancel + </DialogClose> + </DialogFooter> + </DialogContent> + </Dialog> ); } |