Keep a room message in the composer and toast when sending it fails, instead of dropping it silently

This commit is contained in:
Jon Staab 2026-09-25 15:47:44 -07:00
parent 790700dd9f
commit 326fb33bca
2 changed files with 69 additions and 58 deletions

View file

@ -174,13 +174,12 @@
return return
} }
try {
const protect = await shouldProtect const protect = await shouldProtect
if (eventToEdit) { if (eventToEdit) {
// Don't do anything if message hasn't changed // Don't do anything if message hasn't changed
if (eventToEdit.content === content) { if (eventToEdit.content === content) {
return return clearEventToEdit()
} }
// Delete the previous message, to be republished below with the same timestamp // Delete the previous message, to be republished below with the same timestamp
@ -228,12 +227,12 @@
}, },
}) })
} }
} finally {
// Only once it's sent, so a failure leaves the reply or edit in place to try again.
clearParent() clearParent()
clearShare() clearShare()
clearEventToEdit() clearEventToEdit()
} }
}
const getElementKey = (element: {id: string}) => element.id const getElementKey = (element: {id: string}) => element.id

View file

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import {writable} from "svelte/store" import {writable} from "svelte/store"
import type {Maybe} from "@welshman/lib" import type {Maybe, MaybeAsync} from "@welshman/lib"
import {MESSAGE} from "@welshman/util" import {MESSAGE} from "@welshman/util"
import type {EventContent} from "@welshman/util" import type {EventContent} from "@welshman/util"
import {escapeHtml, isMobile, preventDefault} from "@lib/html" import {escapeHtml, isMobile, preventDefault} from "@lib/html"
@ -20,6 +20,7 @@
import {makeEditor} from "@app/editor" import {makeEditor} from "@app/editor"
import {app} from "@app/core" import {app} from "@app/core"
import {getDictation} from "@app/dictation" import {getDictation} from "@app/dictation"
import {pushToast} from "@app/toast"
import {DraftKey, type Draft} from "@app/drafts" import {DraftKey, type Draft} from "@app/drafts"
import type {Share} from "@app/share" import type {Share} from "@app/share"
import {onDestroy, onMount} from "svelte" import {onDestroy, onMount} from "svelte"
@ -29,7 +30,7 @@
h?: string h?: string
onEscape?: () => void onEscape?: () => void
onEditPrevious?: () => void onEditPrevious?: () => void
onSubmit: (event: EventContent) => void onSubmit: (event: EventContent) => MaybeAsync<void>
initialValues?: Share initialValues?: Share
} }
@ -100,7 +101,7 @@
const hidePopover = () => tippy?.hide() const hidePopover = () => tippy?.hide()
const submit = async () => { const submit = async () => {
if ($uploading) { if ($uploading || sending) {
return return
} }
@ -108,12 +109,23 @@
const content = ed.getText({blockSeparator: "\n"}).trim() const content = ed.getText({blockSeparator: "\n"}).trim()
const tags = ed.storage.nostr.getEditorTags() const tags = ed.storage.nostr.getEditorTags()
onSubmit({content, tags}) sending = true
try {
await onSubmit({content, tags})
} catch (error) {
console.error("Failed to send message", error)
return pushToast({theme: "error", message: "Failed to send your message."})
} finally {
sending = false
}
draftKey?.clear() draftKey?.clear()
ed.chain().clearContent(true).run() ed.chain().clearContent(true).run()
} }
let sending = false
let tippy: Maybe<TippyController> = $state() let tippy: Maybe<TippyController> = $state()
let content = $state( let content = $state(
initialValues?.type === "text" ? initialValues.value : (draftKey?.get()?.content ?? ""), initialValues?.type === "text" ? initialValues.value : (draftKey?.get()?.content ?? ""),