Allow editing previous messages in channel chat

This commit is contained in:
Matthew Remmel
2025-10-15 10:00:23 -04:00
committed by hodlbod
parent 7334cd26f8
commit 5b22d6ac01
5 changed files with 159 additions and 14 deletions
+24 -2
View File
@@ -8,13 +8,16 @@
import Button from "@lib/components/Button.svelte"
import EditorContent from "@app/editor/EditorContent.svelte"
import {makeEditor} from "@app/editor"
import {onDestroy, onMount} from "svelte"
type Props = {
url?: string
content?: string
onEditPrevious?: () => void
onSubmit: (event: EventContent) => void
}
const {onSubmit, url}: Props = $props()
const {content, onEditPrevious, onSubmit, url}: Props = $props()
const autofocus = !isMobile
@@ -22,6 +25,15 @@
export const focus = () => editor.then(ed => ed.chain().focus().run())
export const canEnterEditPrevious = () =>
editor.then(ed => ed.getText({blockSeparator: "\n"}) === "")
const handleKeyDown = async (event: KeyboardEvent) => {
if (event.key === "ArrowUp" && (await canEnterEditPrevious())) {
onEditPrevious?.()
}
}
const uploadFiles = () => editor.then(ed => ed.chain().selectFiles().run())
const submit = async () => {
@@ -38,7 +50,17 @@
ed.chain().clearContent().run()
}
const editor = makeEditor({url, autofocus, submit, uploading, aggressive: true})
const editor = makeEditor({url, autofocus, content, submit, uploading, aggressive: true})
onMount(async () => {
const ed = await editor
ed.view.dom.addEventListener("keydown", handleKeyDown)
})
onDestroy(async () => {
const ed = await editor
ed?.view?.dom.removeEventListener("keydown", handleKeyDown)
})
</script>
<form class="relative z-feature flex gap-2 p-2" onsubmit={preventDefault(submit)}>
@@ -0,0 +1,21 @@
<script lang="ts">
import {slide} from "@lib/transition"
import CloseCircle from "@assets/icons/close-circle.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
const {
clear,
}: {
clear: () => void
} = $props()
</script>
<div
class="relative border-l-2 border-solid border-primary bg-base-300 px-2 py-1 pr-8 text-xs"
transition:slide>
<p class="text-primary">Editing message</p>
<Button class="absolute right-2 top-2 cursor-pointer" onclick={clear}>
<Icon icon={CloseCircle} />
</Button>
</div>
+19 -2
View File
@@ -6,6 +6,7 @@
import TapTarget from "@lib/components/TapTarget.svelte"
import Avatar from "@lib/components/Avatar.svelte"
import Reply from "@assets/icons/reply-2.svg?dataurl"
import Pen from "@assets/icons/pen.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Content from "@app/components/Content.svelte"
@@ -26,9 +27,19 @@
replyTo?: (event: TrustedEvent) => void
showPubkey?: boolean
inert?: boolean
canEdit: (event: TrustedEvent) => boolean
onEdit: (event: TrustedEvent) => void
}
const {url, event, replyTo = undefined, showPubkey = false, inert = false}: Props = $props()
const {
url,
event,
replyTo = undefined,
showPubkey = false,
inert = false,
canEdit,
onEdit,
}: Props = $props()
const thunk = $thunks[event.id]
const shouldProtect = canEnforceNip70(url)
@@ -38,8 +49,9 @@
const [_, colorValue] = colors[parseInt(hash(event.pubkey)) % colors.length]
const reply = () => replyTo!(event)
const edit = canEdit(event) ? () => onEdit(event) : undefined
const onTap = () => pushModal(ChannelMessageMenuMobile, {url, event, reply})
const onTap = () => pushModal(ChannelMessageMenuMobile, {url, event, reply, edit})
const openProfile = () => pushModal(ProfileDetail, {pubkey: event.pubkey, url})
@@ -107,6 +119,11 @@
<Icon icon={Reply} size={4} />
</Button>
{/if}
{#if edit}
<Button class="btn join-item btn-xs" onclick={edit}>
<Icon icon={Pen} size={4} />
</Button>
{/if}
<ChannelMessageMenuButton {url} {event} />
</button>
{/if}