Skip to content

Chat add message.with event example #2477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 80 additions & 6 deletions content/chat/rooms/messages.textile
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ The following are the properties of a message:

|_. Property |_. Description |_. Type |
| serial | An Ably-generated ID used to uniquely identify the message. By comparing it to others it provides a deterministic global ordering of messages. | String |
| version | An Ably-generated ID used to uniquely identify the version of the message. It provides a deterministic global ordering of message versions. The @version@ is identical to @serial@ if the action is @message.create@. | String |
| action | The latest action performed on this message, such as @message.create@, @message.update@ or @message.delete@. | String |
| clientId | The client identifier of the user that created the message. | String |
| roomId | The name of the room the message was created in. | String |
| text | The message contents. | String |
| headers | Optional headers for adding additional information to a message, such as the relative timestamp of a livestream video, or flagging a message as important. Do not use the headers for authoritative information. There is no server-side validation. When reading headers treat them like user input. | Object |
| metadata | Optional additional metadata about the message, such as animations, effects or links to other resources such as images. This information is not read by Ably. Do not use metadata for authoritative information. There is no server-side validation. When reading metadata treat it like user input. | Object |
| createdAt | The time the message was created. | Date |
| action | The latest action performed on this message, such as @message.create@, @message.update@ or @message.delete@. | String |
| version | An Ably-generated ID used to uniquely identify the version of the message. It provides a deterministic global ordering of message versions. The @version@ is identical to @serial@ if the action is @message.create@. | String |
| timestamp | The time the action was performed. It will be identical to @createdAt@ if the action is a @message.create@. | Date |
| operation | For updates and deletions, this provides additional details about the action. It may contain the following properties: | Object or undefined |
| | clientId: The client identifier of the user associated with the action. | String or undefined |
Expand Down Expand Up @@ -196,8 +196,9 @@ blang[react].

```[javascript]
import { Message } from '@ably/chat';
const messageToUpdate: Message
await room.messages.update(messageToUpdate, { text: "my updated text" }, { description: "Message update by user" });
const message: Message
const updatedMessage = message.copy({text: "my updated text"})
await room.messages.update(updatedMessage, { description: "Message update by user" });
```

```[react]
Expand All @@ -208,7 +209,7 @@ const MyComponent = () => {
const [message, setMessage] = useState<Message>();

const handleMessageUpdate = (msg: Message) => {
update(msg, { text: "my updated text" }, { description: "Message update by user" })
update(msg.copy({ text: "my updated text" }), { description: "Message update by user" })
.then((updatedMsg: Message) => {
console.log('Message updated:', updatedMsg);
})
Expand Down Expand Up @@ -566,6 +567,79 @@ h3(#ordering-update-delete). Ordering Updates and Deletes

Applying an action to a message produces a new version, which is uniquely identified by the @version@ property. When two message instances share the same @serial@ they represent the same chat message, but they can represent different versions. Lexicographically sorting the two message instances by the @version@ property gives the global order of the message versions: the message instance with a greater @version@ is newer, the message instance with a lower @version@ is older, and if their @version@ is equal then they are the same version.

The @Message@ object also has convenience methods "@versionBefore@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#versionbefore, "@versionAfter@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#versionafter and "@versionEqual@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#versionEqual which provide the same comparison.
The @Message@ object also has convenience methods "@isOlderVersionOf@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#isolderversionof, "@isNewerVersionOf@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#isnewerversionof and "@isSameVersionAs@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#issameversionas which provide the same comparison.

Update and Delete events provide the full message payload, so may be used to replace the entire earlier version of the message.

h2(#keep-messages-updated). Keep messages updated using @with()@

The "@Message@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html object has a convenience method "@with@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#with that takes a "@MessageEvent@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.MessageEvent.html, automatically compares versions, and returns the newest @Message@ instance. If @with@ is called with an event that is older than the message, the message is returned. If it is called with a newer event, the message from the event is returned. This can be used to ensure that the latest version of a message is always obtained without manually comparing versions.

Example usage to keep a list of messages updated:

```[javascript]
import { MessageEvents, Message } from '@ably/chat';
let myMessageList: Message[];

const { unsubscribe } = room.messages.subscribe((event) => {
switch (event.type) {
case MessageEvents.Created:
myMessageList.push(event.message);
break;
case MessageEvents.Updated:
case MessageEvents.Deleted:
const idx = myMessageList.findIndex((msg) => event.message.isNewerVersionOf(msg));
if (idx !== -1) {
myMessageList[idx] = myMessageList[idx].with(event);
}
break;
default:
break;
}
});
```

```[react]
import { MessageEvents, useMessages, Message } from '@ably/chat';

const MyComponent = () => {
// we use {list: []} to avoid copying the full array with every change
// but still take advantage of React's state change detection
const [ messages, setMessages ] = useState<{list: Message[]}>({list: []});
useMessages({
listener: (event) => {
switch (event.type) {
case MessageEvents.Created:
setMessages((prev) => {
// append new message
prev.list.push(event.message);
// update reference without copying whole array
return { list: prev.list };
});
break;
case MessageEvents.Updated:
case MessageEvents.Deleted:
setMyMessageList((prev) => {
// find existing message to apply update or delete to
const existing = prev.list.findIndex((msg) => msg.serial === event.message.serial);
if (existing === -1) {
return prev; // no change if not found
}
const newMsg = existing.with(event);
if (newMsg === existing) {
// with() returns the same object if the event is older,
// so in this case no change is needed
return prev;
}
// set new message and update reference without copying whole array
prev.list[existing] = newMsg;
return { list: prev.list };
});
break;
}
},
});

return <div>...</div>;
};
```