From f7b7b5b637be0712b0157b3dfe49094c4c6b5eb7 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sat, 22 Aug 2026 13:03:25 +0200 Subject: [PATCH] Msg edit --- src/components/page/channel/TextChannel.tsx | 116 ++++++++++++++++++-- 1 file changed, 104 insertions(+), 12 deletions(-) diff --git a/src/components/page/channel/TextChannel.tsx b/src/components/page/channel/TextChannel.tsx index 55ccff4..27c2151 100644 --- a/src/components/page/channel/TextChannel.tsx +++ b/src/components/page/channel/TextChannel.tsx @@ -14,6 +14,7 @@ import { ContextMenuItem, ContextMenuTrigger, } from "@/components/ui/context-menu"; +import { Textarea } from "@/components/ui/textarea"; export default function TextChannel({ appRef, @@ -28,10 +29,9 @@ export default function TextChannel({ const account = appRef.current?.getAccount(); - const userPubKey = - (account && - base58.encode(ed.getPublicKey(base58.decode(account.privateKey)))) || - null; + const secretKey = (account && base58.decode(account.privateKey)) || null; + + const userPubKey = secretKey && base58.encode(ed.getPublicKey(secretKey)); useEffect(() => { if (!intersectionRef.current) return; @@ -88,6 +88,7 @@ export default function TextChannel({ message={message} channel={channel} userPubKey={userPubKey} + secretKey={secretKey} /> ))}
@@ -116,28 +117,36 @@ export default function TextChannel({ export function TextMessage({ appRef, message, - channel, userPubKey, + secretKey, }: { appRef: React.RefObject | null>; message: StoredMessage; channel: Channel; userPubKey: string | null; + secretKey: Uint8Array | null; }) { const time = new Date(message.timestamp).toLocaleTimeString([], { hour: "numeric", minute: "2-digit", }); + const author = appRef.current?.server?.users[message.author]; + const [verified, setVerified] = useState(true); + const [editing, setEditing] = useState(false); + const [draft, setDraft] = useState(message.content); useEffect(() => { const serverPubKey = appRef.current?.server?.serverPublicKey && - base58.encode(appRef.current?.server?.serverPublicKey); + base58.encode(appRef.current.server.serverPublicKey); + if (!serverPubKey) return; + const authorPubKey = base58.decode(message.author); + setVerified( ed.verify( base58.decode(message.signature), @@ -159,6 +168,56 @@ export function TextMessage({ }); } + function startEditing() { + setDraft(message.content); + setEditing(true); + } + + function cancelEditing() { + setDraft(message.content); + setEditing(false); + } + + function handleSave() { + const content = draft.trim(); + + if ( + !content || + content === message.content || + !secretKey || + !appRef.current?.server?.serverPublicKey + ) { + cancelEditing(); + return; + } + + const signature = new TextEncoder().encode( + `${message.timestamp}@${base58.encode(appRef.current.server?.serverPublicKey)}@${content}`, + ); + + appRef.current?.server?.websocket?.send({ + method: "EditMessage", + message_id: message.id, + channel_id: channel.id, + signature: base58.encode(ed.sign(signature, secretKey)), + content, + }); + + setEditing(false); + } + + function handleKeyDown(e: React.KeyboardEvent) { + if (e.key === "Escape") { + e.preventDefault(); + cancelEditing(); + } + + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + handleSave(); + } + } + const content = (
@@ -168,6 +227,7 @@ export function TextMessage({ message.author.slice(0, 2).toUpperCase()} +
@@ -176,30 +236,62 @@ export function TextMessage({ )} {author?.displayName || message.author.slice(0, 8)} + {time} - {message.is_edited && ( + + {message.is_edited && !editing && ( (edited) )}
-

- {message.content} -

+ + {editing ? ( +
+