From 5f5abef50528608b26939f579d4e64d4d28ff67b Mon Sep 17 00:00:00 2001 From: Steven Lindsay Date: Fri, 8 Nov 2024 12:03:31 +0000 Subject: [PATCH] Refactor message docs - Refactored the deletion aspect of chat in the README.md, so it keeps consistency with updates and provides greater clarity for its usage. --- README.md | 50 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e8c2c213..d05897a2 100644 --- a/README.md +++ b/README.md @@ -346,22 +346,62 @@ These additional parameters are: * `metadata`: a map of extra information that can be attached to the deletion message. The return of this call will be the deleted message, as it would appear to other subscribers of the room. -This is a _soft delete_ and the message will still be available in the history, but with the `deletedAt` property set. +This is a _soft delete_ and the message will still be available in the history. +Example ```ts -const deletedMessage = await room.messages.delete(message, { description: 'This message was deleted for ...' }); +const deletedMessage = await room.messages.delete(message, + { + description: 'This message was deleted for ...' + }); ``` -Note that you can update deleted messages, which will effectively undo the delete. Only the last operation on a message takes effect. +`deletedMessage` is a Message object with the deletion applied. As with sending, the promise may resolve after the deletion message is received via the messages subscription. -### Subscribing to incoming messages +A `Message` that was deleted will have `deletedAt` and `deletedBy` fields set, and `isDeleted()` will return `true`. -To subscribe to incoming messages, call `subscribe` with your listener. +Note that you can update deleted messages, which will effectively undo the deletion. Only the last operation on a message takes effect. ```ts const { unsubscribe } = room.messages.subscribe((msg) => console.log(msg)); ``` +#### Handling deletes in realtime + +Deletion messages received from realtime have the `latestAction` parameter set to `ChatMessageActions.MessageDelete`, and the event received has the `type` set to `MessageEvents.Deleted`. +Just like `updates`, `deletion` messages are also full copies of the message, meaning that all that is needed to keep a state or UI up to date is to replace the old message with the received one. + +On rare occasions, deletes and updates might arrive over realtime out of order. + +To keep a correct state, the `Message` interface provides methods to compare two instances of the same base message to determine which action is newer:`actionBefore()`, `actionAfter()`, and `actionEqual()`. + +The same out-of-order situation can happen between deletions received over realtime and HTTP responses. + +In the situation where two concurrent deletes happen, both might be received via realtime before the HTTP response of the first one arrives. +Always use `actionAfter()`, `actionBefore()`, or `actionEqual()` to determine which instance of a `Message` is newer. + +Example for handling deletes: +```typescript +const messages : Message[] = []; // assuming this is where state is kept + +room.messages.subscribe(event => { + switch (event.type) { + case MessageEvents.Deleted: { + const serial = event.message.serial; + const index = messages.findIndex((m) => m.serial === serial); + if (index !== -1 && messages[index].actionBefore(event.message)) { + messages[index] = event.message; + } + break; + } + // other event types (ie. created and updated) omitted + } +}) +``` +### Subscribing to incoming messages + +To subscribe to incoming messages, call `subscribe` with your listener. + ### Unsubscribing from incoming messages When you're done with the listener, call `unsubscribe` to remove that listeners subscription and prevent it from receiving