This commit is contained in:
Ishaan Gupta 2026-05-18 15:39:19 +05:30 committed by GitHub
commit 13531d135b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 57 additions and 32 deletions

View file

@ -542,13 +542,13 @@ export function MemoriesGrid({
{!isEmpty && !isSelectionMode && (
<div
id="filter-pills"
className="flex items-center justify-between gap-4 mb-3 pr-2"
className="mb-3 flex flex-col gap-2 pr-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4"
>
<div className="flex flex-wrap items-center gap-1.5">
<div className="scrollbar-none -mx-1 flex items-center gap-1.5 overflow-x-auto px-1 pb-1 sm:mx-0 sm:flex-wrap sm:overflow-visible sm:px-0 sm:pb-0">
<Button
className={cn(
dmSansClassName(),
"rounded-full border border-[#161F2C] bg-[#0D121A] px-2.5 py-1 text-xs h-auto hover:bg-[#00173C] hover:border-[#2261CA33]",
"h-auto shrink-0 rounded-full border border-[#161F2C] bg-[#0D121A] px-2.5 py-1 text-xs hover:bg-[#00173C] hover:border-[#2261CA33]",
selectedCategories.length === 0 &&
"bg-[#00173C] border-[#2261CA33]",
)}
@ -566,7 +566,7 @@ export function MemoriesGrid({
key={facet.category}
className={cn(
dmSansClassName(),
"rounded-full border border-[#161F2C] bg-[#0D121A] px-2.5 py-1 text-xs h-auto hover:bg-[#00173C] hover:border-[#2261CA33]",
"h-auto shrink-0 rounded-full border border-[#161F2C] bg-[#0D121A] px-2.5 py-1 text-xs hover:bg-[#00173C] hover:border-[#2261CA33]",
selectedCategoriesSet.has(facet.category) &&
"bg-[#00173C] border-[#2261CA33]",
)}
@ -577,7 +577,7 @@ export function MemoriesGrid({
</Button>
))}
</div>
<div className="flex items-center gap-2 shrink-0">
<div className="flex shrink-0 items-center justify-end gap-2">
{/* View mode toggle — segmented control */}
<div
role="tablist"

View file

@ -1,11 +1,12 @@
"use client"
import { useRef, useCallback } from "react"
import { useRef, useCallback, useState } from "react"
import { cn } from "@lib/utils"
import { dmSansClassName } from "@/lib/fonts"
import { Maximize2, Plus, Loader2 } from "lucide-react"
import { useProject } from "@/stores"
import { useQuickNoteDraft } from "@/stores/quick-note-draft"
import { TextEditor } from "./text-editor"
interface QuickNoteCardProps {
onSave: (content: string) => void
@ -18,28 +19,23 @@ export function QuickNoteCard({
onMaximize,
isSaving = false,
}: QuickNoteCardProps) {
const textareaRef = useRef<HTMLTextAreaElement>(null)
const [isExpanded, setIsExpanded] = useState(false)
const { selectedProject } = useProject()
const { draft, setDraft } = useQuickNoteDraft(selectedProject)
const draftRef = useRef(draft)
draftRef.current = draft
const handleChange = useCallback(
(e: React.ChangeEvent<HTMLTextAreaElement>) => {
setDraft(e.target.value)
},
const handleContentChange = useCallback(
(content: string) => setDraft(content),
[setDraft],
)
const handleKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
e.preventDefault()
if (draft.trim() && !isSaving) {
onSave(draft)
}
}
},
[draft, isSaving, onSave],
)
const handleEditorSubmit = useCallback(() => {
const currentDraft = draftRef.current
if (currentDraft.trim() && !isSaving) {
onSave(currentDraft)
}
}, [isSaving, onSave])
const handleSaveClick = useCallback(() => {
if (draft.trim() && !isSaving) {
@ -51,7 +47,17 @@ export function QuickNoteCard({
onMaximize(draft)
}, [draft, onMaximize])
const handleBlurCapture = useCallback(
(e: React.FocusEvent<HTMLDivElement>) => {
if (e.currentTarget.contains(e.relatedTarget as Node | null)) return
setIsExpanded(draftRef.current.trim().length > 0)
},
[],
)
const canSave = draft.trim().length > 0 && !isSaving
const editorHeight =
isExpanded || draft.trim() ? "min-h-[188px]" : "min-h-[120px]"
return (
<div
@ -64,6 +70,8 @@ export function QuickNoteCard({
<div
id="quick-note-inner"
className="bg-[#0B1017] rounded-[18px] p-3 relative"
onFocusCapture={() => setIsExpanded(true)}
onBlurCapture={handleBlurCapture}
style={{
boxShadow: "inset 1.421px 1.421px 4.263px 0 rgba(11, 15, 21, 0.4)",
}}
@ -77,18 +85,23 @@ export function QuickNoteCard({
<Maximize2 className="size-[14px]" />
</button>
<textarea
ref={textareaRef}
value={draft}
onChange={handleChange}
onKeyDown={handleKeyDown}
placeholder="Start writing..."
disabled={isSaving}
<div
className={cn(
dmSansClassName(),
"w-full h-[120px] bg-transparent resize-none outline-none text-[12px] leading-normal text-white placeholder:text-[#737373] pr-5 disabled:opacity-50",
"w-full pr-5 text-white transition-[min-height] duration-200 disabled:opacity-50",
"[&_.ProseMirror]:text-[12px] [&_.ProseMirror]:leading-normal [&_.ProseMirror_p.is-editor-empty:first-child::before]:text-[#737373]",
editorHeight,
)}
/>
aria-disabled={isSaving}
>
<TextEditor
content={draft}
onContentChange={handleContentChange}
onSubmit={handleEditorSubmit}
debounceMs={0}
editable={!isSaving}
/>
</div>
<div
id="quick-note-action-bar"

View file

@ -18,11 +18,13 @@ export function TextEditor({
onContentChange,
onSubmit,
debounceMs = 500,
editable = true,
}: {
content: string | undefined
onContentChange: (content: string) => void
onSubmit: () => void
debounceMs?: number
editable?: boolean
}) {
const containerRef = useRef<HTMLDivElement>(null)
const editorRef = useRef<Editor | null>(null)
@ -44,6 +46,7 @@ export function TextEditor({
extensions,
content: initialContent,
contentType: "markdown",
editable,
immediatelyRender: true,
onCreate: ({ editor }) => {
editorRef.current = editor
@ -86,12 +89,21 @@ export function TextEditor({
})
useEffect(() => {
if (editor && initialContent) {
if (editor && initialContent !== undefined) {
const json = editor.getJSON()
const currentContent =
editor.storage.markdown?.manager?.serialize(json) ?? ""
if (currentContent === initialContent) return
hasUserEditedRef.current = false
editor.commands.setContent(initialContent, { contentType: "markdown" })
}
}, [editor, initialContent])
useEffect(() => {
editor?.setEditable(editable)
}, [editor, editable])
const handleClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
const target = e.target as HTMLElement
if (target.closest(".ProseMirror")) {