import { Button } from "$components/Button"; import { ContextMenu, type ContextMenuDivider, type ContextMenuItem, useContextMenu } from "$components/ContextMenu"; import { CHROME_SECTION, NO_MOTION_TRANSITION, QUICK_CAPTURE } from "$constants"; import { ChevronDownIcon, PenIcon, XIcon } from "$icons"; import type { CaptureMode } from "$types"; import { formatShortcut } from "$utils/shortcuts"; import { cn } from "$utils/tw"; import { AnimatePresence, motion } from "motion/react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; export type QuickCaptureSaveTarget = { id: string; locationId: number; relPath: string; label: string }; type QuickCaptureFormProps = { defaultMode?: CaptureMode; onSubmit: (text: string, mode: CaptureMode, destination?: { locationId: number; relPath: string }) => void; onClose: () => void; isSubmitting: boolean; error: string | null; reduceMotion?: boolean; saveTargets?: QuickCaptureSaveTarget[]; }; type FormTransition = typeof CHROME_SECTION.TRANSITION | typeof NO_MOTION_TRANSITION; type ModeButtonsProps = { currentMode: CaptureMode; setMode: (mode: CaptureMode) => void; isSubmitting: boolean; transition: FormTransition; }; const MODE_OPTIONS = ["QuickNote", "WritingSession", "Append"] as const satisfies readonly CaptureMode[]; const EMPTY_SAVE_TARGETS: QuickCaptureSaveTarget[] = []; const getModeLabel = (m: CaptureMode): string => { switch (m) { case "QuickNote": return "Quick Note"; case "WritingSession": return "Writing Session"; case "Append": return "Append"; default: return m; } }; const getModeDescription = (m: CaptureMode): string => { switch (m) { case "QuickNote": return "Capture and save immediately into your inbox."; case "WritingSession": return "Draft freely and save when you are ready."; case "Append": return "Append your note to the last configured target."; default: return "Capture a thought quickly."; } }; const getShortcutHint = (mode: CaptureMode): string => { if (mode === "WritingSession") { return `${formatShortcut("Cmd+Enter")} to save, Esc to close`; } return "Enter to save, Shift+Enter for newline, Esc to close"; }; const ModeDescription = ({ mode, transition }: { mode: CaptureMode; transition: FormTransition }) => ( {getModeDescription(mode)} ); const ModeButton = ( { mode, currentMode, setMode, isSubmitting, transition }: { mode: CaptureMode; currentMode: CaptureMode; setMode: (mode: CaptureMode) => void; isSubmitting: boolean; transition: FormTransition; }, ) => { const handleClick = useCallback(() => { setMode(mode); }, [mode, setMode]); const classes = useMemo( () => cn( "relative rounded px-2.5 py-1.5 text-xs font-medium transition-[color,background-color,opacity,border-color] duration-150 sm:text-sm", mode === currentMode ? "text-text-primary" : "text-text-secondary hover:text-text-primary", ), [mode, currentMode], ); return ( ); }; const ModeButtons = ({ currentMode, setMode, isSubmitting, transition }: ModeButtonsProps) => (
{MODE_OPTIONS.map((modeOption) => ( ))}
); const CaptureTitle = ({ mode, transition }: { mode: CaptureMode; transition: FormTransition }) => (

Quick Capture

); const QuickCaptureFormHeader = ( { onClose, currentMode, setMode, isSubmitting, transition }: ModeButtonsProps & { onClose: () => void }, ) => (
); const CaptureMetaRow = ({ mode, noteStats }: { mode: CaptureMode; noteStats: string }) => (
{getModeLabel(mode)} mode {noteStats}
); const CaptureTextarea = ( { textareaRef, text, isSubmitting, onChange, onKeyDown }: { textareaRef: React.RefObject; text: string; isSubmitting: boolean; onChange: (e: React.ChangeEvent) => void; onKeyDown: (e: React.KeyboardEvent) => void; }, ) => (