From 8bfa65987d4044f1c135036af8fea267c89f89d9 Mon Sep 17 00:00:00 2001
From: Patrick He <77468352+he-patrick@users.noreply.github.com>
Date: Tue, 6 Aug 2024 09:30:37 -0400
Subject: [PATCH] feat(chat) use the original message ID for processing
This is a prerequisite for operations that rely on previous messages, such as reactions.
---
modules/API/API.js | 6 +-
react/features/breakout-rooms/middleware.ts | 4 +-
.../components/AbstractMessageContainer.ts | 4 +-
.../chat/components/native/ChatMessage.tsx | 4 +-
.../chat/components/web/ChatMessage.tsx | 2 +-
.../chat/components/web/ChatMessageGroup.tsx | 2 +-
react/features/chat/functions.ts | 2 +-
react/features/chat/middleware.ts | 78 +++++++++++--------
react/features/chat/reducer.ts | 6 +-
react/features/chat/types.ts | 2 +-
10 files changed, 59 insertions(+), 51 deletions(-)
diff --git a/modules/API/API.js b/modules/API/API.js
index 47d10e5e4f..d4887e3d7a 100644
--- a/modules/API/API.js
+++ b/modules/API/API.js
@@ -1338,14 +1338,14 @@ class API {
* @returns {void}
*/
notifyReceivedChatMessage(
- { body, id, nick, privateMessage, ts } = {}) {
- if (APP.conference.isLocalId(id)) {
+ { body, from, nick, privateMessage, ts } = {}) {
+ if (APP.conference.isLocalId(from)) {
return;
}
this._sendEvent({
name: 'incoming-message',
- from: id,
+ from,
message: body,
nick,
privateMessage,
diff --git a/react/features/breakout-rooms/middleware.ts b/react/features/breakout-rooms/middleware.ts
index 8645c6741c..2e27666a82 100644
--- a/react/features/breakout-rooms/middleware.ts
+++ b/react/features/breakout-rooms/middleware.ts
@@ -83,12 +83,12 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
const { messages } = getState()['features/chat'];
messages?.forEach(m => {
- if (m.messageType === MESSAGE_TYPE_REMOTE && !getParticipantById(getState(), m.id)) {
+ if (m.messageType === MESSAGE_TYPE_REMOTE && !getParticipantById(getState(), m.participantId)) {
const rooms: IRooms = action.rooms;
for (const room of Object.values(rooms)) {
const participants = room.participants || {};
- const matchedJid = Object.keys(participants).find(jid => jid.endsWith(m.id));
+ const matchedJid = Object.keys(participants).find(jid => jid.endsWith(m.participantId));
if (matchedJid) {
m.displayName = participants[matchedJid].displayName;
diff --git a/react/features/chat/components/AbstractMessageContainer.ts b/react/features/chat/components/AbstractMessageContainer.ts
index d5a40b3f5b..19cf8bf60b 100644
--- a/react/features/chat/components/AbstractMessageContainer.ts
+++ b/react/features/chat/components/AbstractMessageContainer.ts
@@ -36,13 +36,13 @@ export default class AbstractMessageContainer
extends Compo
for (let i = 0; i < messagesCount; i++) {
const message = this.props.messages[i];
- if (message.id === currentGroupParticipantId) {
+ if (message.participantId === currentGroupParticipantId) {
currentGrouping.push(message);
} else {
currentGrouping.length && groups.push(currentGrouping);
currentGrouping = [ message ];
- currentGroupParticipantId = message.id;
+ currentGroupParticipantId = message.participantId;
}
}
diff --git a/react/features/chat/components/native/ChatMessage.tsx b/react/features/chat/components/native/ChatMessage.tsx
index 952b2944f0..eedad83c92 100644
--- a/react/features/chat/components/native/ChatMessage.tsx
+++ b/react/features/chat/components/native/ChatMessage.tsx
@@ -113,7 +113,7 @@ class ChatMessage extends Component {
{ this.props.showAvatar &&
}
@@ -175,7 +175,7 @@ class ChatMessage extends Component {
diff --git a/react/features/chat/components/web/ChatMessage.tsx b/react/features/chat/components/web/ChatMessage.tsx
index 926902e423..5a36b8e26b 100644
--- a/react/features/chat/components/web/ChatMessage.tsx
+++ b/react/features/chat/components/web/ChatMessage.tsx
@@ -197,7 +197,7 @@ const ChatMessage = ({
className = { classes.replyButtonContainer }>
+ participantID = { message.participantId } />
)}
diff --git a/react/features/chat/components/web/ChatMessageGroup.tsx b/react/features/chat/components/web/ChatMessageGroup.tsx
index b156712e11..8d86bc5fd5 100644
--- a/react/features/chat/components/web/ChatMessageGroup.tsx
+++ b/react/features/chat/components/web/ChatMessageGroup.tsx
@@ -66,7 +66,7 @@ const ChatMessageGroup = ({ className = '', messages }: IProps) => {
{messages.map((message, i) => (
diff --git a/react/features/chat/functions.ts b/react/features/chat/functions.ts
index a4f045cd43..e580a18dd2 100644
--- a/react/features/chat/functions.ts
+++ b/react/features/chat/functions.ts
@@ -172,7 +172,7 @@ export function getMessageText(message: IMessage) {
*/
export function getCanReplyToMessage(state: IReduxState, message: IMessage) {
const { knocking } = state['features/lobby'];
- const participant = getParticipantById(state, message.id);
+ const participant = getParticipantById(state, message.participantId);
return Boolean(participant)
&& (message.privateMessage || (message.lobbyChat && !knocking))
diff --git a/react/features/chat/middleware.ts b/react/features/chat/middleware.ts
index 5490a8fcc7..0c50614dcc 100644
--- a/react/features/chat/middleware.ts
+++ b/react/features/chat/middleware.ts
@@ -125,7 +125,7 @@ MiddlewareRegistry.register(store => next => action => {
store.dispatch(pushReactions(data.reactions));
_handleReceivedMessage(store, {
- id: participant.getId(),
+ participantId: participant.getId(),
message: getReactionMessageFromBuffer(data.reactions),
privateMessage: false,
lobbyChat: false,
@@ -137,12 +137,12 @@ MiddlewareRegistry.register(store => next => action => {
}
case NON_PARTICIPANT_MESSAGE_RECEIVED: {
- const { id, json: data } = action;
+ const { participantId, json: data } = action;
if (data?.type === MESSAGE_TYPE_SYSTEM && data.message) {
_handleReceivedMessage(store, {
displayName: data.displayName ?? i18next.t('chat.systemDisplayName'),
- id,
+ participantId,
lobbyChat: false,
message: data.message,
privateMessage: true,
@@ -213,7 +213,7 @@ MiddlewareRegistry.register(store => next => action => {
case ADD_REACTION_MESSAGE: {
if (localParticipant?.id) {
_handleReceivedMessage(store, {
- id: localParticipant.id,
+ participantId: localParticipant.id,
message: action.message,
privateMessage: false,
timestamp: Date.now(),
@@ -274,25 +274,30 @@ function _addChatMsgListener(conference: IJitsiConference, store: IStore) {
conference.on(
JitsiConferenceEvents.MESSAGE_RECEIVED,
- // eslint-disable-next-line max-params
- (id: string, message: string, timestamp: number, displayName: string, isGuest?: boolean) => {
+ /* eslint-disable max-params */
+ (participantId: string, message: string, timestamp: number,
+ displayName: string, isGuest: boolean, messageId: string) => {
+ /* eslint-enable max-params */
_onConferenceMessageReceived(store, {
- id: id || displayName, // in case of messages coming from visitors we can have unknown id
+ // in case of messages coming from visitors we can have unknown id
+ participantId: participantId || displayName,
message,
timestamp,
displayName,
isGuest,
+ messageId,
privateMessage: false });
}
);
conference.on(
JitsiConferenceEvents.PRIVATE_MESSAGE_RECEIVED,
- (id: string, message: string, timestamp: number) => {
+ (participantId: string, message: string, timestamp: number, messageId: string) => {
_onConferenceMessageReceived(store, {
- id,
+ participantId,
message,
timestamp,
+ messageId,
privateMessage: true
});
}
@@ -311,25 +316,29 @@ function _addChatMsgListener(conference: IJitsiConference, store: IStore) {
* @param {Object} message - The message object.
* @returns {void}
*/
-function _onConferenceMessageReceived(store: IStore, { displayName, id, isGuest, message, timestamp, privateMessage }: {
- displayName?: string; id: string; isGuest?: boolean;
- message: string; privateMessage: boolean; timestamp: number; }) {
+function _onConferenceMessageReceived(store: IStore,
+ { displayName, isGuest, message, messageId, participantId, privateMessage, timestamp }: {
+ displayName?: string; isGuest?: boolean; message: string; messageId?: string;
+ participantId: string; privateMessage: boolean; timestamp: number; }
+) {
+
const isGif = isGifMessage(message);
if (isGif) {
- _handleGifMessageReceived(store, id, message);
+ _handleGifMessageReceived(store, participantId, message);
if (getGifDisplayMode(store.getState()) === 'tile') {
return;
}
}
_handleReceivedMessage(store, {
displayName,
- id,
isGuest,
+ participantId,
message,
privateMessage,
lobbyChat: false,
- timestamp
+ timestamp,
+ messageId
}, true, isGif);
}
@@ -337,14 +346,14 @@ function _onConferenceMessageReceived(store: IStore, { displayName, id, isGuest,
* Handles a received gif message.
*
* @param {Object} store - Redux store.
- * @param {string} id - Id of the participant that sent the message.
+ * @param {string} participantId - Id of the participant that sent the message.
* @param {string} message - The message sent.
* @returns {void}
*/
-function _handleGifMessageReceived(store: IStore, id: string, message: string) {
+function _handleGifMessageReceived(store: IStore, participantId: string, message: string) {
const url = message.substring(GIF_PREFIX.length, message.length - 1);
- store.dispatch(addGif(id, url));
+ store.dispatch(addGif(participantId, url));
}
/**
@@ -374,7 +383,7 @@ function _handleChatError({ dispatch }: IStore, error: Error) {
export function handleLobbyMessageReceived(message: string, participantId: string) {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
_handleReceivedMessage({ dispatch,
- getState }, { id: participantId,
+ getState }, { participantId,
message,
privateMessage: false,
lobbyChat: true,
@@ -387,18 +396,18 @@ export function handleLobbyMessageReceived(message: string, participantId: strin
* Function to get lobby chat user display name.
*
* @param {Store} state - The Redux store.
- * @param {string} id - The knocking participant id.
+ * @param {string} participantId - The knocking participant id.
* @returns {string}
*/
-function getLobbyChatDisplayName(state: IReduxState, id: string) {
+function getLobbyChatDisplayName(state: IReduxState, participantId: string) {
const { knockingParticipants } = state['features/lobby'];
const { lobbyMessageRecipient } = state['features/chat'];
- if (id === lobbyMessageRecipient?.id) {
+ if (participantId === lobbyMessageRecipient?.id) {
return lobbyMessageRecipient.name;
}
- const knockingParticipant = knockingParticipants.find(p => p.id === id);
+ const knockingParticipant = knockingParticipants.find(p => p.id === participantId);
if (knockingParticipant) {
return knockingParticipant.name;
@@ -417,9 +426,9 @@ function getLobbyChatDisplayName(state: IReduxState, id: string) {
* @returns {void}
*/
function _handleReceivedMessage({ dispatch, getState }: IStore,
- { displayName, id, isGuest, message, privateMessage, timestamp, lobbyChat }: {
- displayName?: string; id: string; isGuest?: boolean; lobbyChat: boolean;
- message: string; privateMessage: boolean; timestamp: number; },
+ { displayName, isGuest, lobbyChat, message, messageId, participantId, privateMessage, timestamp }: {
+ displayName?: string; isGuest?: boolean; lobbyChat: boolean; message: string;
+ messageId?: string; participantId: string; privateMessage: boolean; timestamp: number; },
shouldPlaySound = true,
isReaction = false
) {
@@ -434,12 +443,12 @@ function _handleReceivedMessage({ dispatch, getState }: IStore,
// Provide a default for the case when a message is being
// backfilled for a participant that has left the conference.
- const participant = getParticipantById(state, id) || { local: undefined };
+ const participant = getParticipantById(state, participantId) || { local: undefined };
const localParticipant = getLocalParticipant(getState);
let displayNameToShow = lobbyChat
- ? getLobbyChatDisplayName(state, id)
- : displayName || getParticipantDisplayName(state, id);
+ ? getLobbyChatDisplayName(state, participantId)
+ : displayName || getParticipantDisplayName(state, participantId);
const hasRead = participant.local || isChatOpen;
const timestampToDate = timestamp ? new Date(timestamp) : new Date();
const millisecondsTimestamp = timestampToDate.getTime();
@@ -455,13 +464,14 @@ function _handleReceivedMessage({ dispatch, getState }: IStore,
dispatch(addMessage({
displayName: displayNameToShow,
hasRead,
- id,
+ participantId,
messageType: participant.local ? MESSAGE_TYPE_LOCAL : MESSAGE_TYPE_REMOTE,
message,
privateMessage,
lobbyChat,
recipient: getParticipantDisplayName(state, localParticipant?.id ?? ''),
timestamp: millisecondsTimestamp,
+ messageId,
isReaction
}));
@@ -477,7 +487,7 @@ function _handleReceivedMessage({ dispatch, getState }: IStore,
APP.API.notifyReceivedChatMessage({
body: message,
- id,
+ from: participantId,
nick: displayNameToShow,
privateMessage,
ts: timestamp
@@ -512,7 +522,7 @@ function _persistSentPrivateMessage({ dispatch, getState }: IStore, recipientID:
dispatch(addMessage({
displayName,
hasRead: true,
- id: localParticipant.id,
+ participantId: localParticipant.id,
messageType: MESSAGE_TYPE_LOCAL,
message,
privateMessage: !isLobbyPrivateMessage,
@@ -562,7 +572,7 @@ function _shouldSendPrivateMessageTo(state: IReduxState, action: AnyAction) {
if (lastMessage.privateMessage) {
// We show the notice if the last received message was private.
- return lastMessage.id;
+ return lastMessage.participantId;
}
// But messages may come rapidly, we want to protect our users from mis-sending a message
@@ -577,7 +587,7 @@ function _shouldSendPrivateMessageTo(state: IReduxState, action: AnyAction) {
? recentPrivateMessages[0] : recentPrivateMessages[recentPrivateMessages.length - 1];
if (recentPrivateMessage) {
- return recentPrivateMessage.id;
+ return recentPrivateMessage.participantId;
}
return undefined;
diff --git a/react/features/chat/reducer.ts b/react/features/chat/reducer.ts
index d5c63332d8..e050f23396 100644
--- a/react/features/chat/reducer.ts
+++ b/react/features/chat/reducer.ts
@@ -1,5 +1,3 @@
-import { v4 as uuidv4 } from 'uuid';
-
import { ILocalParticipant, IParticipant } from '../base/participants/types';
import ReducerRegistry from '../base/redux/ReducerRegistry';
@@ -48,9 +46,9 @@ ReducerRegistry.register('features/chat', (state = DEFAULT_STATE, ac
const newMessage: IMessage = {
displayName: action.displayName,
error: action.error,
- id: action.id,
+ participantId: action.participantId,
isReaction: action.isReaction,
- messageId: uuidv4(),
+ messageId: action.messageId,
messageType: action.messageType,
message: action.message,
privateMessage: action.privateMessage,
diff --git a/react/features/chat/types.ts b/react/features/chat/types.ts
index a58b289ab3..a50fb312a7 100644
--- a/react/features/chat/types.ts
+++ b/react/features/chat/types.ts
@@ -5,12 +5,12 @@ import { IStore } from '../app/types';
export interface IMessage {
displayName: string;
error?: Object;
- id: string;
isReaction: boolean;
lobbyChat: boolean;
message: string;
messageId: string;
messageType: string;
+ participantId: string;
privateMessage: boolean;
recipient: string;
timestamp: number;