diff --git a/src/app/components/ThunkStatusDetail.svelte b/src/app/components/ThunkStatusDetail.svelte index cc8b2653..3da57bb4 100644 --- a/src/app/components/ThunkStatusDetail.svelte +++ b/src/app/components/ThunkStatusDetail.svelte @@ -2,6 +2,7 @@ import {PublishStatus} from "@welshman/net" import {displayRelayUrl} from "@welshman/util" import Button from "@lib/components/Button.svelte" + import {addPeriod} from "@lib/util" interface Props { url: string @@ -25,7 +26,7 @@

- Failed to publish to {displayRelayUrl(url)}: {message}. + Failed to publish to {displayRelayUrl(url)}: {addPeriod(message)}

diff --git a/src/app/editor/index.ts b/src/app/editor/index.ts index 2184f317..8ea78606 100644 --- a/src/app/editor/index.ts +++ b/src/app/editor/index.ts @@ -15,6 +15,7 @@ import { } from "@welshman/app" import type {FileAttributes} from "@welshman/editor" import {Editor, MentionSuggestion, WelshmanExtension, editorProps} from "@welshman/editor" +import {escapeHtml} from "@lib/html" import {makeMentionNodeView} from "@app/editor/MentionNodeView" import ProfileSuggestion from "@app/editor/ProfileSuggestion.svelte" import {uploadFile} from "@app/core/commands" @@ -82,7 +83,7 @@ export const makeEditor = async ({ ) return new Editor({ - content, + content: escapeHtml(content), autofocus, editorProps, element: document.createElement("div"), diff --git a/src/lib/html.ts b/src/lib/html.ts index ec38e0d4..adfd6aca 100644 --- a/src/lib/html.ts +++ b/src/lib/html.ts @@ -164,3 +164,11 @@ export const compressFile = async ( }) }) } + +export const escapeHtml = (html: string) => { + const element = document.createElement("div") + + element.innerText = html + + return element.innerHTML +} diff --git a/src/lib/util.ts b/src/lib/util.ts index a1ae8d5b..6a2248ec 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -26,3 +26,5 @@ export const buildUrl = (base: string | URL, ...pathname: string[]) => { return url.toString() } + +export const addPeriod = (s: string) => (s + ".").replace(/\.+$/, ".") diff --git a/src/routes/spaces/[relay]/[h]/+page.svelte b/src/routes/spaces/[relay]/[h]/+page.svelte index e93bf402..53dd5624 100644 --- a/src/routes/spaces/[relay]/[h]/+page.svelte +++ b/src/routes/spaces/[relay]/[h]/+page.svelte @@ -110,51 +110,58 @@ } const onSubmit = async ({content, tags}: EventContent) => { - tags.push(["h", h]) + try { + tags.push(["h", h]) - if (await shouldProtect) { - tags.push(PROTECTED) - } + if (await shouldProtect) { + tags.push(PROTECTED) + } - let template: EventContent & {created_at?: number} = {content, tags} + let template: EventContent & {created_at?: number} = {content, tags} - if (eventToEdit) { - // Delete previous message, to be republished with same timestamp - template.created_at = eventToEdit.created_at - publishDelete({ + if (eventToEdit) { + // Don't do anything if message hasn't changed + if (eventToEdit.content === content) { + return + } + + // Delete previous message, to be republished with same timestamp + template.created_at = eventToEdit.created_at + publishDelete({ + relays: [url], + event: $state.snapshot(eventToEdit), + protect: await shouldProtect, + }) + } + + if (share) { + template = prependParent(share, template, url) + } + + if (parent) { + template = prependParent(parent, template, url) + } + + const thunk = publishThunk({ relays: [url], - event: $state.snapshot(eventToEdit), - protect: await shouldProtect, + event: makeEvent(MESSAGE, template), + delay: $userSettingsValues.send_delay, }) + + if ($userSettingsValues.send_delay) { + pushToast({ + timeout: 30_000, + children: { + component: ThunkToast, + props: {thunk}, + }, + }) + } + } finally { + clearParent() + clearShare() + clearEventToEdit() } - - if (share) { - template = prependParent(share, template, url) - } - - if (parent) { - template = prependParent(parent, template, url) - } - - const thunk = publishThunk({ - relays: [url], - event: makeEvent(MESSAGE, template), - delay: $userSettingsValues.send_delay, - }) - - if ($userSettingsValues.send_delay) { - pushToast({ - timeout: 30_000, - children: { - component: ThunkToast, - props: {thunk}, - }, - }) - } - - clearParent() - clearShare() - clearEventToEdit() } const onScroll = () => { diff --git a/src/routes/spaces/[relay]/chat/+page.svelte b/src/routes/spaces/[relay]/chat/+page.svelte index 3da1032e..596f1d1f 100644 --- a/src/routes/spaces/[relay]/chat/+page.svelte +++ b/src/routes/spaces/[relay]/chat/+page.svelte @@ -54,45 +54,52 @@ } const onSubmit = async ({content, tags}: EventContent) => { - let template: EventContent & {created_at?: number} = {content, tags} + try { + let template: EventContent & {created_at?: number} = {content, tags} - if (eventToEdit) { - // Delete previous message, to be republished with same timestamp - template.created_at = eventToEdit.created_at - publishDelete({relays: [url], event: eventToEdit, protect: await shouldProtect}) - } + if (eventToEdit) { + // Don't do anything if message hasn't changed + if (eventToEdit.content === content) { + return + } - if (await shouldProtect) { - tags.push(PROTECTED) - } + // Delete previous message, to be republished with same timestamp + template.created_at = eventToEdit.created_at + publishDelete({relays: [url], event: eventToEdit, protect: await shouldProtect}) + } - if (share) { - template = prependParent(share, template, url) - } + if (await shouldProtect) { + tags.push(PROTECTED) + } - if (parent) { - template = prependParent(parent, template, url) - } + if (share) { + template = prependParent(share, template, url) + } - const thunk = publishThunk({ - relays: [url], - event: makeEvent(MESSAGE, template), - delay: $userSettingsValues.send_delay, - }) + if (parent) { + template = prependParent(parent, template, url) + } - if ($userSettingsValues.send_delay) { - pushToast({ - timeout: 30_000, - children: { - component: ThunkToast, - props: {thunk}, - }, + const thunk = publishThunk({ + relays: [url], + event: makeEvent(MESSAGE, template), + delay: $userSettingsValues.send_delay, }) - } - clearParent() - clearShare() - clearEventToEdit() + if ($userSettingsValues.send_delay) { + pushToast({ + timeout: 30_000, + children: { + component: ThunkToast, + props: {thunk}, + }, + }) + } + } finally { + clearParent() + clearShare() + clearEventToEdit() + } } const onScroll = () => {