From c927465861c448fe8791f2749d5e1748bca96494 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 2 Feb 2026 19:51:56 +0000 Subject: [PATCH 1/8] Add save button to message edits Co-authored-by: me --- .../_app+/recipients+/$recipientId.index.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/routes/_app+/recipients+/$recipientId.index.tsx b/app/routes/_app+/recipients+/$recipientId.index.tsx index 042c5c87..7dcd0e30 100644 --- a/app/routes/_app+/recipients+/$recipientId.index.tsx +++ b/app/routes/_app+/recipients+/$recipientId.index.tsx @@ -536,6 +536,20 @@ function MessageForms({ className="mt-4 w-full resize-none bg-transparent text-sm leading-relaxed text-[hsl(var(--palette-cream))] placeholder:text-[hsl(var(--palette-cream))]/80 focus-visible:outline-none" rows={4} /> +
+ + + Save + +
Date: Mon, 2 Feb 2026 20:16:12 +0000 Subject: [PATCH 2/8] Show save check only on edits Co-authored-by: me --- .../_app+/recipients+/$recipientId.index.tsx | 65 +++++++++++-------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/app/routes/_app+/recipients+/$recipientId.index.tsx b/app/routes/_app+/recipients+/$recipientId.index.tsx index 7dcd0e30..c9b3a5ab 100644 --- a/app/routes/_app+/recipients+/$recipientId.index.tsx +++ b/app/routes/_app+/recipients+/$recipientId.index.tsx @@ -383,6 +383,8 @@ function MessageForms({ const deleteSafeDelayMs = 150 const [confirmDelete, setConfirmDelete] = useState(false) const [canDelete, setCanDelete] = useState(false) + const [savedContent, setSavedContent] = useState(message.content) + const [hasEdits, setHasEdits] = useState(false) const formRef = useRef(null) const textareaRef = useRef(null) const [updateContentForm, updateContentFields] = useForm({ @@ -408,6 +410,7 @@ function MessageForms({ const sendIsPending = sendNowFetcher.state !== 'idle' const deleteIsPending = deleteFetcher.state !== 'idle' const textareaProps = getTextareaProps(updateContentFields.content) + const showSaveButton = hasEdits || updateIsPending useEffect(() => { if (confirmDelete) { @@ -419,6 +422,18 @@ function MessageForms({ setCanDelete(false) }, [confirmDelete, deleteSafeDelayMs]) + useEffect(() => { + setSavedContent(message.content) + setHasEdits(false) + }, [message.content]) + + useEffect(() => { + if (updateContentFetcher.data?.result.status === 'success') { + setSavedContent((previous) => textareaRef.current?.value ?? previous) + setHasEdits(false) + } + }, [updateContentFetcher.data?.result.status]) + const handleSendNow = () => { setConfirmDelete(false) const formData = new FormData() @@ -432,6 +447,13 @@ function MessageForms({ setTimeout(() => textareaRef.current?.focus(), 0) } + const handleContentChange: React.ChangeEventHandler = ( + event, + ) => { + textareaProps.onChange?.(event) + setHasEdits(event.target.value !== savedContent) + } + const handleDeleteSelect = (event: Event) => { if (!confirmDelete) { event.preventDefault() @@ -461,19 +483,21 @@ function MessageForms({ {headerText}
- - - Save - + {showSaveButton ? ( + + + Save + + ) : null} { if (!open) setConfirmDelete(false) @@ -532,24 +556,11 @@ function MessageForms({