From f5bbdd434be3ca2c5a8856f38aafd0818393b1f1 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Thu, 5 Jun 2025 12:03:40 +0100 Subject: [PATCH 01/14] chat: add react examples for message reactions --- .../docs/chat/rooms/message-reactions.mdx | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index 2fbddb207d..f96deb356e 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -15,9 +15,17 @@ The reaction `name` can be any string. Summaries are aggregated based on unique ## Adding a message reaction + To add a message reaction use `room.messages.reactions.send(message, params)`. This method takes the following parameters: * `message` - The message to add the reaction to. It can also be an object of format `{serial: "message serial"}`. * `params` - Set the `name`, and optionally override the `type` or set a `count`. + + + +Use the [`sendReaction()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat_react.UseMessagesResponse.html#sendReaction) method available from the response of the `useMessages` hook to add a reaction to a message. This method takes the following parameters: +* `message` - The message to add the reaction to. It can also be an object of format `{serial: "message serial"}`. +* `params` - Set the `name`, and optionally override the `type` or set a `count`. + ```javascript @@ -87,10 +95,122 @@ room.messages.reactions.send(message, count = 100, ) ``` + +```react +import { MessageReactionType } from '@ably/chat'; +import { useMessages } from '@ably/chat/react'; + +const MyComponent = () => { + const { addReaction } = useMessages(); + + const handleAddReaction = async (message) => { + try { + // Add a 👍 reaction using the default type + await addReaction(message, { name: '👍' }); + + // The reaction can be anything, not just UTF-8 emojis: + await addReaction(message, { name: ':like:' }); + await addReaction(message, { name: '+1' }); + + // Add a :love: reaction using the Unique type + await addReaction(message, { + name: ':love:', + type: MessageReactionType.Unique, + }); + + // Add a ❤️ reaction with count 100 using the Multiple type + await addReaction(message, { + name: '❤️', + type: MessageReactionType.Multiple, + count: 100, + }); + } catch (error) { + console.error('Error adding reaction:', error); + } + }; + + return ( +
+ +
+ ); +}; +```
The `annotation-publish` capability is required for adding reactions. +## Removing a message reaction
+ + +To remove a message reaction use `room.messages.reactions.delete(message, params)`. This method takes the following parameters: +* `message` - The message to remove the reaction from. It can also be an object of format `{serial: "message serial"}`. +* `params` - Set the `name`, and optionally override the `type` or set a `count`. + + + +Use the [`deleteReaction()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat_react.UseMessagesResponse.html#deleteReaction) method available from the response of the `useMessages` hook to remove a reaction from a message. This method takes the following parameters: +* `message` - The message to remove the reaction from. It can also be an object of format `{serial: "message serial"}`. +* `params` - Set the `name`, and optionally override the `type` or set a `count`. + + + +```javascript +// Remove a 👍 reaction using the default type +await room.messages.reactions.delete(message, { name: '👍' }); + +// Remove a :love: reaction using the Unique type +await room.messages.reactions.delete(message, { + name: ':love:', + type: MessageReactionType.Unique, +}); + +// Remove a ❤️ reaction with count 50 using the Multiple type +await room.messages.reactions.delete(message, { + name: '❤️', + type: MessageReactionType.Multiple, + count: 50, +}); +``` + +```react +import { MessageReactionType } from '@ably/chat'; +import { useMessages } from '@ably/chat/react'; + +const MyComponent = () => { + const { deleteReaction } = useMessages(); + + const handleRemoveReaction = async (message) => { + try { + // Remove a 👍 reaction using the default type + await deleteReaction(message, { name: '👍' }); + + // Remove a :love: reaction using the Unique type + await deleteReaction(message, { + name: ':love:', + type: MessageReactionType.Unique, + }); + + // Remove a ❤️ reaction with count 50 using the Multiple type + await deleteReaction(message, { + name: '❤️', + type: MessageReactionType.Multiple, + count: 50, + }); + } catch (error) { + console.error('Error removing reaction:', error); + } + }; + + return ( +
+ +
+ ); +}; +``` +
+ ## Types of message reactions
Ably Chat supports three types of message reactions. They differ in how they are aggregated and what are the rules for adding and removing them. @@ -134,6 +254,26 @@ val room = ablyChatClient.rooms.get("room1") { } } ``` + +```react +import { MessageReactionType } from '@ably/chat'; +import { useChatClient } from '@ably/chat/react'; + +const MyComponent = () => { + const chatClient = useChatClient(); + + const getRoom = async () => { + const room = await chatClient.rooms.get('room1', { + messages: { + defaultMessageReactionType: MessageReactionType.Unique, + }, + }); + return room; + }; + + // ... rest of component +}; +``` ## Messages and reactions @@ -181,7 +321,13 @@ Always call `Message.with(event)` when applying message events and reaction even ## Subscribing to message reactions + Ably generates a summary (aggregate) of the reactions for each message and for each reaction type. For displaying accurate counts for message reactions, subscribe to changes in the message summary. + + + +Subscribe to message reactions with the [`useMessages`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.useMessages.html) hook. Supply a `reactionsListener` to receive message reaction summary events. Ably generates a summary (aggregate) of the reactions for each message and for each reaction type. For displaying accurate counts for message reactions, subscribe to changes in the message summary. + ```javascript @@ -189,6 +335,7 @@ room.messages.reactions.subscribe((event) => { console.log("received reactions summary event", event); }); ``` + ```swift room.messages.reactions.subscribe { event in print("received reactions summary event: \(event)") @@ -200,6 +347,20 @@ room.messages.reactions.subscribe { event -> println("received reactions summary event: $event") } ``` + +```react +import { useMessages } from '@ably/chat/react'; + +const MyComponent = () => { + useMessages({ + reactionsListener: (event) => { + console.log("received reactions summary event", event); + }, + }); + + return
...
; +}; +```
The event is of type `reaction.summary`. `event.summary` is the received reactions summary and contains the following properties: @@ -259,6 +420,47 @@ room.messages.reactions.subscribe { event -> } } ``` + +```react +import { useState, useEffect } from 'react'; +import { useMessages, Message } from '@ably/chat/react'; + +const MyComponent = () => { + const [messages, setMessages] = useState([]); + + const { get } = useMessages({ + reactionsListener: (event) => { + // find the relevant message (in practice: use binary search or a map for lookups) + setMessages((prevMessages) => { + const idx = prevMessages.findLastIndex((msg) => msg.serial === event.summary.messageSerial); + if (idx === -1) { + // not found + return prevMessages; + } + // update message + const updatedMessages = [...prevMessages]; + updatedMessages[idx] = updatedMessages[idx].with(event); + return updatedMessages; + }); + }, + }); + + // Initialize messages on component mount + useEffect(() => { + const initMessages = async () => { + try { + const result = await get({ limit: 50 }); + setMessages(result.items); + } catch (error) { + console.error('Error fetching messages:', error); + } + }; + initMessages(); + }, [get]); + + return
...
; +}; +``` ### Summary events are sent efficiently at scale
@@ -269,9 +471,17 @@ If multiple reactions are added in a short period of time, multiple reactions ma ### Subscribing to raw reactions + +Raw individual reactions are published for every reaction, unlike summaries which can be rolled up. Raw reactions are useful for receiving all reaction events, but they are not suitable for the purpose of displaying message reaction counts as their effect on the reactions summary depends on the previous reactions. + +Individual reactions are not received by default to save bandwidth and to reduce the number of messages and cost. If you want to receive them, you can configure them via a room option which, in turn, sets the appropriate channel options to enable receiving individual annotations and reactions: + + + Raw individual reactions are published for every reaction, unlike summaries which can be rolled up. Raw reactions are useful for receiving all reaction events, but they are not suitable for the purpose of displaying message reaction counts as their effect on the reactions summary depends on the previous reactions. Individual reactions are not received by default to save bandwidth and to reduce the number of messages and cost. If you want to receive them, you can configure them via a room option which, in turn, sets the appropriate channel options to enable receiving individual annotations and reactions: + ```javascript @@ -298,9 +508,34 @@ val room = ablyChatClient.rooms.get("room1") { } } ``` + +```react +import { useChatClient } from '@ably/chat/react'; + +const MyComponent = () => { + const chatClient = useChatClient(); + + const getRoom = async () => { + const room = await chatClient.rooms.get('room1', { + messages: { + rawMessageReactions: true, + }, + }); + return room; + }; + + // ... rest of component +}; +``` + Then you can receive raw reactions using the `room.messages.reactions.subscribeRaw()` method: + + + +Then you can receive raw reactions using the `rawReactionsListener` parameter in the `useMessages` hook: + ```javascript @@ -332,6 +567,24 @@ room.messages.reactions.subscribeRaw { event -> } } ``` + +```react +import { MessageReactionEvents, useMessages } from '@ably/chat/react'; + +const MyComponent = () => { + useMessages({ + rawReactionsListener: (event) => { + if (event.type === MessageReactionEvents.Create) { + console.log("new reaction", event.reaction); + } else if (event.type === MessageReactionEvents.Delete) { + console.log("reaction removed", event.reaction); + } + }, + }); + + return
...
; +}; +```
The `annotation-subscribe` capability is required for receiving individual reactions, however it is not required to receive summaries. From 71c733b5882bf6bc84fafb4b011034b6ad6cb9e1 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Fri, 6 Jun 2025 18:40:34 +0100 Subject: [PATCH 02/14] restructure reactions page --- .../docs/chat/rooms/message-reactions.mdx | 130 +++++++++--------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index f96deb356e..ddc0a20780 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -13,6 +13,71 @@ The reaction `name` represents the reaction itself, for example an emoji. Reacti The reaction `name` can be any string. Summaries are aggregated based on unique `name` values. UTF-8 emojis are a common use case, but any string can be used as long as they are consistent across all front-ends of your app. Examples of common reaction names are `👍`, `❤️`, `:like:`, `like`, `+1`, and so on. How those are presented to the user is entirely up to the app. +## Types of message reactions
+ +Ably Chat supports three types of message reactions. They differ in how they are aggregated and what are the rules for adding and removing them. + +| Type | Description | Example | Similar to | +| ---- | ----------- | ------- | --------- | +| `Unique`, `reaction:unique.v1` | A user can react to a message only once, with a reaction of their choice. When a user reacts a second time their reaction is changed. | Can 👍 or ❤️ but not both or more than once. | iMessage, WhatsApp, Facebook Messenger | +| `Distinct`, `reaction:distinct.v1` | A user can react to a message with each reaction at most once. | Can 👍 and ❤️ but each reaction only once. No 👍👍. | Slack | +| `Multiple`, `reaction:multiple.v1` | A user can react to a message with any reactions as many times as they like. Optionally a `count` parameter can be set when reacting. Reacting again adds to the existing count.| Can 👍 10 times and ❤️ 100 times. | Claps on Medium | + +Note that if adding two identical reactions of type `Distinct`, the second one will be accepted and broadcast as a raw reaction, but it will be ignored in the summary (aggregate). Similarly, when removing a reaction that doesn't exist (of any type), the operation will be accepted and broadcast as a raw reaction, but it will have no effect on the summary. + +### Configure the default reaction type + +The default reaction type can be configured at room-level using the Room Options. If nothing is set, the default is `Distinct`. + + +```javascript +import { MessageReactionType } from '@ably/chat'; + +const room = await ablyChatClient.rooms.get('room1', { + messages: { + defaultMessageReactionType: MessageReactionType.Unique, + }, +}); +``` + +```swift +let room = try await ablyChatClient.rooms.get( + name: "room1", + options: .init( + messages: .init(defaultMessageReactionType: .unique) + ) +) +``` + +```kotlin +val room = ablyChatClient.rooms.get("room1") { + messages { + defaultMessageReactionType = MessageReactionType.Unique + } +} +``` + +```react +import { MessageReactionType } from '@ably/chat'; +import { useChatClient } from '@ably/chat/react'; + +const MyComponent = () => { + const chatClient = useChatClient(); + + const getRoom = async () => { + const room = await chatClient.rooms.get('room1', { + messages: { + defaultMessageReactionType: MessageReactionType.Unique, + }, + }); + return room; + }; + + // ... rest of component +}; +``` + + ## Adding a message reaction @@ -211,71 +276,6 @@ const MyComponent = () => { ``` -## Types of message reactions - -Ably Chat supports three types of message reactions. They differ in how they are aggregated and what are the rules for adding and removing them. - -| Type | Description | Example | Similar to | -| ---- | ----------- | ------- | --------- | -| `Unique`, `reaction:unique.v1` | A user can react to a message only once, with a reaction of their choice. When a user reacts a second time their reaction is changed. | Can 👍 or ❤️ but not both or more than once. | iMessage, WhatsApp, Facebook Messenger | -| `Distinct`, `reaction:distinct.v1` | A user can react to a message with each reaction at most once. | Can 👍 and ❤️ but each reaction only once. No 👍👍. | Slack | -| `Multiple`, `reaction:multiple.v1` | A user can react to a message with any reactions as many times as they like. Optionally a `count` parameter can be set when reacting. Reacting again adds to the existing count.| Can 👍 10 times and ❤️ 100 times. | Claps on Medium | - -Note that if adding two identical reactions of type `Distinct`, the second one will be accepted and broadcast as a raw reaction, but it will be ignored in the summary (aggregate). Similarly, when removing a reaction that doesn't exist (of any type), the operation will be accepted and broadcast as a raw reaction, but it will have no effect on the summary. - -### Configure the default reaction type - -The default reaction type can be configured at room-level using the Room Options. If nothing is set, the default is `Distinct`. - - -```javascript -import { MessageReactionType } from '@ably/chat'; - -const room = await ablyChatClient.rooms.get('room1', { - messages: { - defaultMessageReactionType: MessageReactionType.Unique, - }, -}); -``` - -```swift -let room = try await ablyChatClient.rooms.get( - name: "room1", - options: .init( - messages: .init(defaultMessageReactionType: .unique) - ) -) -``` - -```kotlin -val room = ablyChatClient.rooms.get("room1") { - messages { - defaultMessageReactionType = MessageReactionType.Unique - } -} -``` - -```react -import { MessageReactionType } from '@ably/chat'; -import { useChatClient } from '@ably/chat/react'; - -const MyComponent = () => { - const chatClient = useChatClient(); - - const getRoom = async () => { - const room = await chatClient.rooms.get('room1', { - messages: { - defaultMessageReactionType: MessageReactionType.Unique, - }, - }); - return room; - }; - - // ... rest of component -}; -``` - - ## Messages and reactions The `Message` object contains a `reactions` property which is an object that looks like this: From d2483d9b38ef5633f86730553924668ded36f1d8 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 10 Jun 2025 17:46:04 +0100 Subject: [PATCH 03/14] chat: improvements to message reactions docs --- .../docs/chat/rooms/message-reactions.mdx | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index ddc0a20780..7659b7c4e6 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -59,21 +59,20 @@ val room = ablyChatClient.rooms.get("room1") { ```react import { MessageReactionType } from '@ably/chat'; -import { useChatClient } from '@ably/chat/react'; +import { ChatRoomProvider } from '@ably/chat/react'; const MyComponent = () => { - const chatClient = useChatClient(); - - const getRoom = async () => { - const room = await chatClient.rooms.get('room1', { - messages: { - defaultMessageReactionType: MessageReactionType.Unique, - }, - }); - return room; + const roomOptions = { + messages: { + defaultMessageReactionType: MessageReactionType.Unique, + }, }; - // ... rest of component + return ( + + + + ); }; ``` @@ -82,13 +81,13 @@ const MyComponent = () => { To add a message reaction use `room.messages.reactions.send(message, params)`. This method takes the following parameters: -* `message` - The message to add the reaction to. It can also be an object of format `{serial: "message serial"}`. +* `message` - The message to add the reaction to. This can be a Message object, or just the string serial. * `params` - Set the `name`, and optionally override the `type` or set a `count`. -Use the [`sendReaction()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat_react.UseMessagesResponse.html#sendReaction) method available from the response of the `useMessages` hook to add a reaction to a message. This method takes the following parameters: -* `message` - The message to add the reaction to. It can also be an object of format `{serial: "message serial"}`. +Use the [`sendReaction()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-react.UseMessagesResponse.html#sendReaction) method available from the response of the `useMessages` hook to add a reaction to a message. This method takes the following parameters: +* `message` - The message to add the reaction to. This can be a Message object, or just the string serial. * `params` - Set the `name`, and optionally override the `type` or set a `count`. @@ -214,7 +213,7 @@ To remove a message reaction use `room.messages.reactions.delete(message, params -Use the [`deleteReaction()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat_react.UseMessagesResponse.html#deleteReaction) method available from the response of the `useMessages` hook to remove a reaction from a message. This method takes the following parameters: +Use the [`deleteReaction()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-react.UseMessagesResponse.html#deleteReaction) method available from the response of the `useMessages` hook to remove a reaction from a message. This method takes the following parameters: * `message` - The message to remove the reaction from. It can also be an object of format `{serial: "message serial"}`. * `params` - Set the `name`, and optionally override the `type` or set a `count`. @@ -510,21 +509,22 @@ val room = ablyChatClient.rooms.get("room1") { ``` ```react -import { useChatClient } from '@ably/chat/react'; +import { ChatRoomProvider } from '@ably/chat/react'; const MyComponent = () => { - const chatClient = useChatClient(); - - const getRoom = async () => { - const room = await chatClient.rooms.get('room1', { + const roomOptions = { + messages: { messages: { rawMessageReactions: true, }, - }); - return room; + }, }; - // ... rest of component + return ( + + + + ); }; ``` From c46f4e79bfe0c6f8079847e3479e47e10c20e679 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 10 Jun 2025 17:49:21 +0100 Subject: [PATCH 04/14] chat: put reactions capability requirements in callouts --- src/pages/docs/chat/rooms/message-reactions.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index 7659b7c4e6..ec88e2b3db 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -202,7 +202,9 @@ const MyComponent = () => { ``` + ## Removing a message reaction @@ -587,7 +589,9 @@ const MyComponent = () => { ``` + You should be aware of the following limitations: From 53f88fba94e1937d63608b69201fe88a72d1f44f Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 10 Jun 2025 17:50:16 +0100 Subject: [PATCH 05/14] chat: remove pub/sub annotation type from reaction types table --- src/pages/docs/chat/rooms/message-reactions.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index ec88e2b3db..5ce39cbf0a 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -19,9 +19,9 @@ Ably Chat supports three types of message reactions. They differ in how they are | Type | Description | Example | Similar to | | ---- | ----------- | ------- | --------- | -| `Unique`, `reaction:unique.v1` | A user can react to a message only once, with a reaction of their choice. When a user reacts a second time their reaction is changed. | Can 👍 or ❤️ but not both or more than once. | iMessage, WhatsApp, Facebook Messenger | -| `Distinct`, `reaction:distinct.v1` | A user can react to a message with each reaction at most once. | Can 👍 and ❤️ but each reaction only once. No 👍👍. | Slack | -| `Multiple`, `reaction:multiple.v1` | A user can react to a message with any reactions as many times as they like. Optionally a `count` parameter can be set when reacting. Reacting again adds to the existing count.| Can 👍 10 times and ❤️ 100 times. | Claps on Medium | +| `Unique` | A user can react to a message only once, with a reaction of their choice. When a user reacts a second time their reaction is changed. | Can 👍 or ❤️ but not both or more than once. | iMessage, WhatsApp, Facebook Messenger | +| `Distinct` | A user can react to a message with each reaction at most once. | Can 👍 and ❤️ but each reaction only once. No 👍👍. | Slack | +| `Multiple` | A user can react to a message with any reactions as many times as they like. Optionally a `count` parameter can be set when reacting. Reacting again adds to the existing count.| Can 👍 10 times and ❤️ 100 times. | Claps on Medium | Note that if adding two identical reactions of type `Distinct`, the second one will be accepted and broadcast as a raw reaction, but it will be ignored in the summary (aggregate). Similarly, when removing a reaction that doesn't exist (of any type), the operation will be accepted and broadcast as a raw reaction, but it will have no effect on the summary. From b467f1021c0fcfbd3de9a1e5a17d4781804fb468 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 10 Jun 2025 17:54:28 +0100 Subject: [PATCH 06/14] chat: add react Messages and Reactions snippet --- .../docs/chat/rooms/message-reactions.mdx | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index 5ce39cbf0a..eacb79bdb4 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -292,6 +292,36 @@ interface Message { } } +// example (in real use, it is unlikely that all reaction types are present): +{ + // ... other message fields omitted + reactions: { + unique: { + '👍': { total: 2, clientIds: ['clientA', 'clientB'] }, + '❤️': { total: 1, clientIds: ['clientC'] }, + }, + distinct: { + '👍': { total: 2, clientIds: ['clientA', 'clientB'] }, + '❤️': { total: 1, clientIds: ['clientA'] }, + }, + multiple: { + '👍': { total: 10, clientIds: {'clientA': 7, 'clientB': 3} }, + '❤️': { total: 100, clientIds: {'clientA': 100} }, + }, + } +} +``` + +```react +interface Message { + // ... (other fields omitted) + reactions: { + unique: Ably.SummaryUniqueValues, + distinct: Ably.SummaryDistinctValues, + multiple: Ably.SummaryMultipleValues, + } +} + // example (in real use, it is unlikely that all reaction types are present): { // ... other message fields omitted From fcf09963117fd57c199ac75c9689a6c28190a61c Mon Sep 17 00:00:00 2001 From: owenpearson Date: Thu, 26 Jun 2025 16:24:47 +0100 Subject: [PATCH 07/14] chat: improve message reaction type descriptions --- src/pages/docs/chat/rooms/message-reactions.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index eacb79bdb4..e2dc6de2b3 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -19,9 +19,9 @@ Ably Chat supports three types of message reactions. They differ in how they are | Type | Description | Example | Similar to | | ---- | ----------- | ------- | --------- | -| `Unique` | A user can react to a message only once, with a reaction of their choice. When a user reacts a second time their reaction is changed. | Can 👍 or ❤️ but not both or more than once. | iMessage, WhatsApp, Facebook Messenger | -| `Distinct` | A user can react to a message with each reaction at most once. | Can 👍 and ❤️ but each reaction only once. No 👍👍. | Slack | -| `Multiple` | A user can react to a message with any reactions as many times as they like. Optionally a `count` parameter can be set when reacting. Reacting again adds to the existing count.| Can 👍 10 times and ❤️ 100 times. | Claps on Medium | +| `Unique` | Users can add a single reaction per message. If they react again, their previous reaction is replaced with the new one. | A user can add a 👍, but adding a ❤️ will replace the 👍. | iMessage, WhatsApp, Facebook Messenger | +| `Distinct` | Users can add each type of reaction once per message. Multiple different reactions are allowed, but duplicates are not. | A user can add both 👍 and ❤️, but cannot add a second 👍. | Slack | +| `Multiple` | Users can add unlimited reactions, including duplicates. A count parameter specifies how many reactions to add at once. Each new reaction adds to the total count. | A user can add 10 👍 reactions and 100 ❤️ reactions to the same message. | Claps on Medium | Note that if adding two identical reactions of type `Distinct`, the second one will be accepted and broadcast as a raw reaction, but it will be ignored in the summary (aggregate). Similarly, when removing a reaction that doesn't exist (of any type), the operation will be accepted and broadcast as a raw reaction, but it will have no effect on the summary. From 73d5f61dd24906278ab1289eead8aaf391ce3772 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Thu, 26 Jun 2025 16:26:19 +0100 Subject: [PATCH 08/14] chat: clarify how message reaction room options are configured --- src/pages/docs/chat/rooms/message-reactions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index e2dc6de2b3..f5c6f1cc32 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -27,7 +27,7 @@ Note that if adding two identical reactions of type `Distinct`, the second one w ### Configure the default reaction type -The default reaction type can be configured at room-level using the Room Options. If nothing is set, the default is `Distinct`. +The default reaction type can be configured at room-level by passing `RoomOptions` when calling `rooms.get`. If nothing is set, the default is `Distinct`. ```javascript From 6935ec19f3e351bcf03fd30ea69c5f090dbbc476 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Thu, 26 Jun 2025 16:28:55 +0100 Subject: [PATCH 09/14] chat: improve reaction send argument description --- src/pages/docs/chat/rooms/message-reactions.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index f5c6f1cc32..55ce415796 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -81,13 +81,13 @@ const MyComponent = () => { To add a message reaction use `room.messages.reactions.send(message, params)`. This method takes the following parameters: -* `message` - The message to add the reaction to. This can be a Message object, or just the string serial. +* `message` - The message to add the reaction to. Can be either a Message object or a string containing the message serial. * `params` - Set the `name`, and optionally override the `type` or set a `count`. Use the [`sendReaction()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-react.UseMessagesResponse.html#sendReaction) method available from the response of the `useMessages` hook to add a reaction to a message. This method takes the following parameters: -* `message` - The message to add the reaction to. This can be a Message object, or just the string serial. +* `message` - The message to add the reaction to. Can be either a Message object or a string containing the message serial. * `params` - Set the `name`, and optionally override the `type` or set a `count`. From 7d310797b484f57804015a53914a6836d91e477d Mon Sep 17 00:00:00 2001 From: owenpearson Date: Thu, 26 Jun 2025 16:31:49 +0100 Subject: [PATCH 10/14] chat: fix duplication of raw reactions description --- src/pages/docs/chat/rooms/message-reactions.mdx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index 55ce415796..e5c85fde46 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -210,13 +210,13 @@ The `annotation-publish` capability is required for adding reactions. To remove a message reaction use `room.messages.reactions.delete(message, params)`. This method takes the following parameters: -* `message` - The message to remove the reaction from. It can also be an object of format `{serial: "message serial"}`. +* `message` - The message to add the reaction to. This can be a Message object, or just the string serial. * `params` - Set the `name`, and optionally override the `type` or set a `count`. Use the [`deleteReaction()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-react.UseMessagesResponse.html#deleteReaction) method available from the response of the `useMessages` hook to remove a reaction from a message. This method takes the following parameters: -* `message` - The message to remove the reaction from. It can also be an object of format `{serial: "message serial"}`. +* `message` - The message to add the reaction to. This can be a Message object, or just the string serial. * `params` - Set the `name`, and optionally override the `type` or set a `count`. @@ -502,17 +502,9 @@ If multiple reactions are added in a short period of time, multiple reactions ma ### Subscribing to raw reactions - -Raw individual reactions are published for every reaction, unlike summaries which can be rolled up. Raw reactions are useful for receiving all reaction events, but they are not suitable for the purpose of displaying message reaction counts as their effect on the reactions summary depends on the previous reactions. - -Individual reactions are not received by default to save bandwidth and to reduce the number of messages and cost. If you want to receive them, you can configure them via a room option which, in turn, sets the appropriate channel options to enable receiving individual annotations and reactions: - - - Raw individual reactions are published for every reaction, unlike summaries which can be rolled up. Raw reactions are useful for receiving all reaction events, but they are not suitable for the purpose of displaying message reaction counts as their effect on the reactions summary depends on the previous reactions. Individual reactions are not received by default to save bandwidth and to reduce the number of messages and cost. If you want to receive them, you can configure them via a room option which, in turn, sets the appropriate channel options to enable receiving individual annotations and reactions: - ```javascript From 112fac11bf4e34789f70533ae51de09325d8f0f1 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Thu, 26 Jun 2025 16:39:29 +0100 Subject: [PATCH 11/14] chat: improve raw reactions description --- src/pages/docs/chat/rooms/message-reactions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index e5c85fde46..731e5d58bc 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -504,7 +504,7 @@ If multiple reactions are added in a short period of time, multiple reactions ma Raw individual reactions are published for every reaction, unlike summaries which can be rolled up. Raw reactions are useful for receiving all reaction events, but they are not suitable for the purpose of displaying message reaction counts as their effect on the reactions summary depends on the previous reactions. -Individual reactions are not received by default to save bandwidth and to reduce the number of messages and cost. If you want to receive them, you can configure them via a room option which, in turn, sets the appropriate channel options to enable receiving individual annotations and reactions: +Individual reactions are not received by default to save bandwidth and to reduce the number of messages and cost. If you want to receive them, you can enable them via the `rawMessageReactions` room option: ```javascript From f3b444eb9b5e95d104221164e4d7e2f9f0da2e9d Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 8 Jul 2025 21:17:31 +0100 Subject: [PATCH 12/14] chat: clarify room options API for react --- src/pages/docs/chat/rooms/message-reactions.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index 731e5d58bc..8fc9205df4 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -27,7 +27,13 @@ Note that if adding two identical reactions of type `Distinct`, the second one w ### Configure the default reaction type + The default reaction type can be configured at room-level by passing `RoomOptions` when calling `rooms.get`. If nothing is set, the default is `Distinct`. + + + +The default reaction type can be configured at room-level by passing `RoomOptions` to the `ChatRoomProvider`. If nothing is set, the default is `Distinct`. + ```javascript From 059aaa0e7f29d673eec79b245fea7b25e33267e4 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 8 Jul 2025 21:18:54 +0100 Subject: [PATCH 13/14] chat: rename addReaction -> sendReaction --- src/pages/docs/chat/rooms/message-reactions.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index 8fc9205df4..06de7065f6 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -171,25 +171,25 @@ import { MessageReactionType } from '@ably/chat'; import { useMessages } from '@ably/chat/react'; const MyComponent = () => { - const { addReaction } = useMessages(); + const { sendReaction } = useMessages(); const handleAddReaction = async (message) => { try { // Add a 👍 reaction using the default type - await addReaction(message, { name: '👍' }); + await sendReaction(message, { name: '👍' }); // The reaction can be anything, not just UTF-8 emojis: - await addReaction(message, { name: ':like:' }); - await addReaction(message, { name: '+1' }); + await sendReaction(message, { name: ':like:' }); + await sendReaction(message, { name: '+1' }); // Add a :love: reaction using the Unique type - await addReaction(message, { + await sendReaction(message, { name: ':love:', type: MessageReactionType.Unique, }); // Add a ❤️ reaction with count 100 using the Multiple type - await addReaction(message, { + await sendReaction(message, { name: '❤️', type: MessageReactionType.Multiple, count: 100, From ac8d6b0edf86be8e6be278ee0cd10760004d1998 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 8 Jul 2025 21:19:59 +0100 Subject: [PATCH 14/14] chat: declare roomOptions outside example component --- .../docs/chat/rooms/message-reactions.mdx | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/pages/docs/chat/rooms/message-reactions.mdx b/src/pages/docs/chat/rooms/message-reactions.mdx index 06de7065f6..63a13210dc 100644 --- a/src/pages/docs/chat/rooms/message-reactions.mdx +++ b/src/pages/docs/chat/rooms/message-reactions.mdx @@ -67,13 +67,13 @@ val room = ablyChatClient.rooms.get("room1") { import { MessageReactionType } from '@ably/chat'; import { ChatRoomProvider } from '@ably/chat/react'; -const MyComponent = () => { - const roomOptions = { - messages: { - defaultMessageReactionType: MessageReactionType.Unique, - }, - }; +const roomOptions = { + messages: { + defaultMessageReactionType: MessageReactionType.Unique, + }, +}; +const MyComponent = () => { return ( @@ -541,15 +541,15 @@ val room = ablyChatClient.rooms.get("room1") { ```react import { ChatRoomProvider } from '@ably/chat/react'; -const MyComponent = () => { - const roomOptions = { +const roomOptions = { + messages: { messages: { - messages: { - rawMessageReactions: true, - }, + rawMessageReactions: true, }, - }; + }, +}; +const MyComponent = () => { return (