From b37291f386d600cafe8a28c51b7dcb37f7f224a9 Mon Sep 17 00:00:00 2001 From: Vlad Velici Date: Thu, 24 Oct 2024 22:07:23 +0100 Subject: [PATCH] Update demo app to show edited time, edit button, and simplify on hover with css only --- .../MessageComponent/MessageComponent.tsx | 84 +++++++++---------- demo/src/containers/Chat/Chat.tsx | 55 ++++++------ demo/src/index.css | 9 ++ 3 files changed, 77 insertions(+), 71 deletions(-) diff --git a/demo/src/components/MessageComponent/MessageComponent.tsx b/demo/src/components/MessageComponent/MessageComponent.tsx index 17f6e159..f4c0e2f3 100644 --- a/demo/src/components/MessageComponent/MessageComponent.tsx +++ b/demo/src/components/MessageComponent/MessageComponent.tsx @@ -1,7 +1,7 @@ import { Message } from '@ably/chat'; import React, { useCallback, useState } from 'react'; import clsx from 'clsx'; -import { FaTrash } from 'react-icons/fa6'; +import { FaPencil, FaTrash } from 'react-icons/fa6'; function twoDigits(input: number): string { if (input === 0) { @@ -14,58 +14,48 @@ function twoDigits(input: number): string { } interface MessageProps { - id: string; self?: boolean; message: Message; - onMessageClick?(message: Message): void; + onMessageUpdate?(message: Message): void; onMessageDelete?(msg: Message): void; } -export const MessageComponent: React.FC = ({ - id, - self = false, - message, - onMessageClick, - onMessageDelete, -}) => { - const handleMessageClick = useCallback(() => { - onMessageClick?.(message); - }, [id, onMessageClick]); - - const [hovered, setHovered] = useState(false); - - let displayCreatedAt: string; - if (Date.now() - message.createdAt.getTime() < 1000 * 60 * 60 * 24) { +function shortDate(date: Date): string { + if (Date.now() - date.getTime() < 1000 * 60 * 60 * 24) { // last 24h show the time - displayCreatedAt = twoDigits(message.createdAt.getHours()) + ':' + twoDigits(message.createdAt.getMinutes()); + return twoDigits(date.getHours()) + ':' + twoDigits(date.getMinutes()); } else { // older, show full date - displayCreatedAt = - message.createdAt.getDate() + + return date.getDate() + '/' + - message.createdAt.getMonth() + + date.getMonth() + '/' + - message.createdAt.getFullYear() + + date.getFullYear() + ' ' + - twoDigits(message.createdAt.getHours()) + + twoDigits(date.getHours()) + ':' + - twoDigits(message.createdAt.getMinutes()); + twoDigits(date.getMinutes()); } +} + +export const MessageComponent: React.FC = ({ + self = false, + message, + onMessageUpdate, + onMessageDelete, +}) => { + const handleMessageUpdate = useCallback((e : React.UIEvent) => { + e.stopPropagation(); onMessageUpdate?.(message); + }, [ message ]); - const handleDelete = useCallback(() => { - // Add your delete handling logic here - onMessageDelete?.(message); - }, [message, onMessageDelete]); + const handleMessageDelete = useCallback((e : React.UIEvent) => { + e.stopPropagation(); onMessageDelete?.(message); + }, [ message ]); return ( -
setHovered(true)} - onMouseLeave={() => setHovered(false)} - > +
= ({
{message.clientId} ·{' '} - {displayCreatedAt} + {shortDate(message.createdAt)} {message.createdAt.toLocaleString()} + {message.isUpdated && (<> · Edited + {shortDate(message.updatedAt!)} + {message.createdAt.toLocaleString()} + + )}
= ({ })} > {message.text} - {hovered && ( - { - e.stopPropagation(); - handleDelete(); - }} - /> - )}
+
diff --git a/demo/src/containers/Chat/Chat.tsx b/demo/src/containers/Chat/Chat.tsx index d1f2958f..16bc0c2b 100644 --- a/demo/src/containers/Chat/Chat.tsx +++ b/demo/src/containers/Chat/Chat.tsx @@ -22,6 +22,18 @@ export const Chat = () => { const isConnected: boolean = currentStatus === ConnectionLifecycle.Connected; + const handleUpdatedMessage = (message: Message) => { + setMessages((prevMessage) => { + const index = prevMessage.findIndex((m) => m.timeserial === message.timeserial); + if (index === -1) { + return prevMessage; + } + const updatedArray = [...prevMessage]; + updatedArray[index] = message; + return updatedArray; + }); + }; + const { send: sendMessage, getPreviousMessages, @@ -50,15 +62,7 @@ export const Chat = () => { break; } case MessageEvents.Updated: { - setMessages((prevMessage) => { - const index = prevMessage.findIndex((m) => m.timeserial === message.message.timeserial); - if (index === -1) { - return prevMessage; - } - const updatedArray = [...prevMessage]; - updatedArray[index] = message.message; - return updatedArray; - }); + handleUpdatedMessage(message.message); break; } default: { @@ -164,21 +168,21 @@ export const Chat = () => { } }, [messages, loading]); - const updateMessage = useCallback( - (message: Message) => { - const newText = prompt('Enter new text'); - if (!newText) { - return; - } - const updateOp = update(message, { - text: newText, - metadata: message.metadata, - headers: message.headers, - }); - console.log('message ', message.timeserial, ' updated. op=', updateOp); - }, - [update], - ); + const onUpdateMessage = (message: Message) => { + const newText = prompt('Enter new text'); + if (!newText) { + return; + } + update(message, { + text: newText, + metadata: message.metadata, + headers: message.headers, + }).then((updatedMessage: Message) => { + handleUpdatedMessage(updatedMessage); + }).catch((error: unknown) => { + console.warn("failed to update message", error); + }); + }; return (
@@ -205,7 +209,6 @@ export const Chat = () => { > {messages.map((msg) => ( { }); }); }} - onMessageClick={updateMessage} + onMessageUpdate={onUpdateMessage} > ))}
diff --git a/demo/src/index.css b/demo/src/index.css index b4cf9411..973be1a6 100644 --- a/demo/src/index.css +++ b/demo/src/index.css @@ -55,3 +55,12 @@ body { .sent-at-time:hover > .short { display: none; } + +.chat-message .buttons { + display: none; +} + +.chat-message:hover .buttons { + display: block; + +} \ No newline at end of file