From e6fc9c42278d979b155fd71b1f8f13e72c990208 Mon Sep 17 00:00:00 2001 From: Yash Date: Thu, 11 Apr 2024 01:34:49 +0000 Subject: [PATCH 1/2] ok --- apps/web/package.json | 1 + apps/web/src/components/Sidebar.tsx | 145 --------------- .../components/Sidebar/AddMemoryDialog.tsx | 39 ++++ .../src/components/Sidebar/MemoriesBar.tsx | 174 ++++++++---------- 4 files changed, 121 insertions(+), 238 deletions(-) delete mode 100644 apps/web/src/components/Sidebar.tsx create mode 100644 apps/web/src/components/Sidebar/AddMemoryDialog.tsx diff --git a/apps/web/package.json b/apps/web/package.json index 8e8a70ed..7ca13deb 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -27,6 +27,7 @@ "framer-motion": "^11.0.24", "lucide-react": "^0.338.0", "next": "14.1.0", + "novel": "0.1.22", "react": "^18", "react-dom": "^18", "tailwind-merge": "^2.2.1", diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx deleted file mode 100644 index 66ca1652..00000000 --- a/apps/web/src/components/Sidebar.tsx +++ /dev/null @@ -1,145 +0,0 @@ -'use client'; -import { StoredContent } from '@/server/db/schema'; -import { - Plus, - MoreHorizontal, - ArrowUpRight, - Edit3, - Trash2, -} from 'lucide-react'; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from './ui/dropdown-menu'; - -import { useState, useEffect, useRef } from 'react'; - -export default function Sidebar() { - const websites: StoredContent[] = [ - { - id: 1, - content: '', - title: 'Visual Studio Code', - url: 'https://code.visualstudio.com', - description: '', - image: 'https://code.visualstudio.com/favicon.ico', - baseUrl: 'https://code.visualstudio.com', - savedAt: new Date() - }, - { - id: 1, - content: '', - title: "yxshv/vscode: An unofficial remake of vscode's landing page", - url: 'https://github.com/yxshv/vscode', - description: '', - image: 'https://github.com/favicon.ico', - baseUrl: 'https://github.com', - savedAt: new Date() - }, - ]; - - return ( - - ); -} - -export const ListItem: React.FC<{ item: StoredContent }> = ({ item }) => { - const [isEditing, setIsEditing] = useState(false); - const editInputRef = useRef(null); - - useEffect(() => { - if (isEditing) { - setTimeout(() => { - editInputRef.current?.focus(); - }, 500); - } - }, [isEditing]); - - return ( -
- isEditing && e.preventDefault()} - className="flex w-[90%] items-center gap-2 focus:outline-none" - > - {isEditing ? ( - - ) : ( - <> - {item.title - - - )} - {isEditing ? ( - setIsEditing(false)} - onKeyDown={(e) => e.key === 'Escape' && setIsEditing(false)} - /> - ) : ( - - {item.title ?? 'Untitled website'} - - )} - - - - - - - window.open(item.url)}> - - Open - - { - setIsEditing(true); - }} - > - - Edit - - - - Delete - - - -
- ); -}; diff --git a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx new file mode 100644 index 00000000..1bd4b688 --- /dev/null +++ b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx @@ -0,0 +1,39 @@ +import { useEffect, useRef } from "react"; +import { + DialogClose, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "../ui/dialog"; +import { Input } from "../ui/input"; +import { Label } from "../ui/label"; + +export default function AddMemoryPage() { + return ( + <> + + Add a web page to memory + + This will take you the web page you are trying to add to memory, where + the extension will save the page to memory + + + + + + + Add + + + Cancel + + + + ); +} diff --git a/apps/web/src/components/Sidebar/MemoriesBar.tsx b/apps/web/src/components/Sidebar/MemoriesBar.tsx index d7d8b5b5..779dea25 100644 --- a/apps/web/src/components/Sidebar/MemoriesBar.tsx +++ b/apps/web/src/components/Sidebar/MemoriesBar.tsx @@ -1,10 +1,13 @@ +import { Editor } from "novel"; import { useAutoAnimate } from "@formkit/auto-animate/react"; import { MemoryWithImage, MemoryWithImages3, MemoryWithImages2, } from "@/assets/MemoryWithImages"; -import { type CollectedSpaces } from "../../../types/memory"; +import { type CollectedSpaces } + +from "../../../types/memory"; import { Input, InputWithIcon } from "../ui/input"; import { ArrowUpRight, @@ -22,7 +25,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "../ui/dropdown-menu"; -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { Variant, useAnimate, motion } from "framer-motion"; import { useMemory } from "@/contexts/MemoryContext"; import { SpaceIcon } from "@/assets/Memories"; @@ -38,6 +41,8 @@ import { import { Label } from "../ui/label"; import useViewport from "@/hooks/useViewport"; import useTouchHold from "@/hooks/useTouchHold"; +import { DialogTrigger } from "@radix-ui/react-dialog"; +import AddMemoryPage from "./AddMemoryDialog"; export function MemoriesBar() { const [parent, enableAnimations] = useAutoAnimate(); @@ -59,38 +64,43 @@ export function MemoriesBar() { />
- - - - - - { - setIsDropdownOpen(false); - setAddMemoryState("page"); - }} - > - - Page to Memory - - - - Note - - - - Space - - - + + + + + + e.preventDefault()}> + + { + setAddMemoryState("page"); + }} + > + + Page to Memory + + + + { + setAddMemoryState("note"); + }} + > + + Note + + + + + Space + + + +
-
void; + type: "page" | "note" | "space" | null; + children?: React.ReactNode | React.ReactNode[]; + isOpen: boolean; }) { return ( - <> - onStateChange(open ? "page" : null)} + + {children} + { + e.preventDefault(); + ( + document.querySelector("[data-autofocus]") as + | HTMLInputElement + | undefined + )?.focus(); + }} > - - - Add a web page to memory - - This will take you the web page you are trying to add to memory, - where the extension will save the page to memory - - - - - - - Add - - - Cancel - - - - - - - - Add a web page to memory - - This will take you the web page you are trying to add to memory, - where the extension will save the page to memory - - - - - - - Add - - - Cancel - - - - - + {type === "page" && } + {type === "note" && ( + <> + + + + + Add + + + Cancel + + + + )} + + ); } From 4a90aaabf3fd41754b990f50ef4cbfa03723b0a8 Mon Sep 17 00:00:00 2001 From: Yash Date: Thu, 11 Apr 2024 02:22:33 +0000 Subject: [PATCH 2/2] novel editor --- apps/web/src/app/globals.css | 55 ++++++++++++++++++- .../components/Sidebar/AddMemoryDialog.tsx | 31 ++++++++++- .../src/components/Sidebar/MemoriesBar.tsx | 42 +++++++------- 3 files changed, 100 insertions(+), 28 deletions(-) diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index f19a0b57..cedb03dc 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -57,14 +57,65 @@ body { padding-bottom: 15dvh; } -.chat-answer pre { +.chat-answer pre { @apply bg-rgray-3 rounded-md border border-rgray-5 p-3 text-sm my-5; } +.novel-editor pre { + @apply bg-rgray-3 rounded-md border border-rgray-5 p-4 text-sm text-rgray-11; +} + .chat-answer h1 { @apply text-rgray-11 text-xl font-medium my-5; } .chat-answer img { @apply rounded-md font-medium my-5; -} \ No newline at end of file +} + +.tippy-box { + @apply bg-rgray-3 text-rgray-11 border border-rgray-5 rounded-md py-0; +} + +.tippy-content #slash-command { + @apply text-rgray-11 bg-transparent border-none; +} + +#slash-command button { + @apply text-rgray-11 py-2; +} + +#slash-command button div:first-child { + @apply text-rgray-11 bg-rgray-4 border-rgray-5 ; +} + +#slash-command button.novel-bg-stone-100 { + @apply bg-rgray-1; +} + +.novel-editor [data-type=taskList] > li { + @apply my-0; +} + +.novel-editor input[type=checkbox] { + @apply accent-rgray-4 rounded-md; + + background: var(--gray-4) !important; + border: 1px solid var(--gray-10) !important; +} + +.novel-editor .is-editor-empty::before { + content: 'Press \'/\' for commands' !important; +} + +.novel-editor h1 { + @apply text-2xl; +} + +.novel-editor h2 { + @apply text-xl; +} + +.novel-editor h3 { + @apply text-lg; +} diff --git a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx index 1bd4b688..5a1d92f0 100644 --- a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx +++ b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef } from "react"; +import { Editor } from "novel"; import { DialogClose, DialogDescription, @@ -8,8 +8,9 @@ import { } from "../ui/dialog"; import { Input } from "../ui/input"; import { Label } from "../ui/label"; +import { useRef } from "react"; -export default function AddMemoryPage() { +export function AddMemoryPage() { return ( <> @@ -23,7 +24,7 @@ export default function AddMemoryPage() { @@ -37,3 +38,27 @@ export default function AddMemoryPage() { ); } + +export function NoteAddPage() { + return ( + <> + + + + + Add + + + Cancel + + + + ); +} diff --git a/apps/web/src/components/Sidebar/MemoriesBar.tsx b/apps/web/src/components/Sidebar/MemoriesBar.tsx index 779dea25..83984233 100644 --- a/apps/web/src/components/Sidebar/MemoriesBar.tsx +++ b/apps/web/src/components/Sidebar/MemoriesBar.tsx @@ -5,9 +5,7 @@ import { MemoryWithImages3, MemoryWithImages2, } from "@/assets/MemoryWithImages"; -import { type CollectedSpaces } - -from "../../../types/memory"; +import { type CollectedSpaces } from "../../../types/memory"; import { Input, InputWithIcon } from "../ui/input"; import { ArrowUpRight, @@ -42,7 +40,7 @@ import { Label } from "../ui/label"; import useViewport from "@/hooks/useViewport"; import useTouchHold from "@/hooks/useTouchHold"; import { DialogTrigger } from "@radix-ui/react-dialog"; -import AddMemoryPage from "./AddMemoryDialog"; +import { AddMemoryPage, NoteAddPage } from "./AddMemoryDialog"; export function MemoriesBar() { const [parent, enableAnimations] = useAutoAnimate(); @@ -319,32 +317,30 @@ export function AddMemoryModal({ { e.preventDefault(); + const novel = document.querySelector('[contenteditable="true"]') as + | HTMLDivElement + | undefined; + if (novel) { + novel.autofocus = false; + novel.onfocus = () => { + ( + document.querySelector("[data-modal-autofocus]") as + | HTMLInputElement + | undefined + )?.focus(); + novel.onfocus = null; + }; + } ( - document.querySelector("[data-autofocus]") as + document.querySelector("[data-modal-autofocus]") as | HTMLInputElement | undefined )?.focus(); }} + className="w-max max-w-[auto]" > {type === "page" && } - {type === "note" && ( - <> - - - - - Add - - - Cancel - - - - )} + {type === "note" && } );