Skip to content
Draft
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions apps/meteor/app/lib/server/methods/sendMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { metrics } from '../../../metrics/server';
import { settings } from '../../../settings/server';
import { sendMessage } from '../functions/sendMessage';
import { RateLimiter } from '../lib';
import { methodDeprecationLogger } from '../lib/deprecationWarningLogger';
/**
*
* @param uid
Expand Down Expand Up @@ -136,6 +137,8 @@ declare module '@rocket.chat/ddp-client' {

Meteor.methods<ServerMethods>({
async sendMessage(message, previewUrls) {
methodDeprecationLogger.method('sendMessage', '9.0.0', '/v1/chat.sendMessage');

check(message, {
_id: Match.Maybe(String),
rid: Match.Maybe(String),
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/slashcommand-asciiarts/client/gimme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { slashCommands } from '../../utils/client/slashCommand';
*/
async function Gimme({ message, params }: SlashCommandCallbackParams<'gimme'>): Promise<void> {
const msg = message;
await sdk.call('sendMessage', { ...msg, msg: `༼ つ ◕_◕ ༽つ ${params}` });
await sdk.rest.post('/v1/chat.sendMessage', { message: { ...msg, msg: `༼ つ ◕_◕ ༽つ ${params}` } });
}

slashCommands.add({
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/slashcommand-asciiarts/client/lenny.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { slashCommands } from '../../utils/client/slashCommand';

async function LennyFace({ message, params }: SlashCommandCallbackParams<'lenny'>): Promise<void> {
const msg = message;
await sdk.call('sendMessage', { ...msg, msg: `${params} ( ͡° ͜ʖ ͡°)` });
await sdk.rest.post('/v1/chat.sendMessage', { message: { ...msg, msg: `${params} ( ͡° ͜ʖ ͡°)` } });
}

slashCommands.add({
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/slashcommand-asciiarts/client/shrug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ slashCommands.add({
command: 'shrug',
callback: async ({ message, params }: SlashCommandCallbackParams<'shrug'>): Promise<void> => {
const msg = message;
await sdk.call('sendMessage', { ...msg, msg: `${params} ¯\\\\_(ツ)_/¯` });
await sdk.rest.post('/v1/chat.sendMessage', { message: { ...msg, msg: `${params} ¯\\\\_(ツ)_/¯` } });
},
options: {
description: 'Slash_Shrug_Description',
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/slashcommand-asciiarts/client/tableflip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ slashCommands.add({
command: 'tableflip',
callback: async ({ message, params }: SlashCommandCallbackParams<'tableflip'>): Promise<void> => {
const msg = message;
await sdk.call('sendMessage', { ...msg, msg: `${params} (╯°□°)╯︵ ┻━┻` });
await sdk.rest.post('/v1/chat.sendMessage', { message: { ...msg, msg: `${params} (╯°□°)╯︵ ┻━┻` } });
},
options: {
description: 'Slash_Tableflip_Description',
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/slashcommand-asciiarts/client/unflip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ slashCommands.add({
command: 'unflip',
callback: async ({ message, params }: SlashCommandCallbackParams<'unflip'>): Promise<void> => {
const msg = message;
await sdk.call('sendMessage', { ...msg, msg: `${params} ┬─┬ ノ( ゜-゜ノ)` });
await sdk.rest.post('/v1/chat.sendMessage', { message: { ...msg, msg: `${params} ┬─┬ ノ( ゜-゜ノ)` } });
},
options: {
description: 'Slash_TableUnflip_Description',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { sdk } from '../../../app/utils/client/lib/SDKClient';
import UserAutoCompleteMultiple from '../../components/UserAutoCompleteMultiple';
import { useOpenedRoom } from '../../lib/RoomManager';
import { roomCoordinator } from '../../lib/rooms/roomCoordinator';
import { callWithErrorHandling } from '../../lib/utils/callWithErrorHandling';

type Username = Exclude<IUser['username'], undefined>;

Expand All @@ -35,10 +34,12 @@ const GameCenterInvitePlayersModal = ({ game, onClose }: IGameCenterInvitePlayer
roomCoordinator.openRouteLink(group.t, { rid: group._id, name: group.name });

if (openedRoom === group._id) {
await callWithErrorHandling('sendMessage', {
_id: Random.id(),
rid: group._id,
msg: t('Apps_Game_Center_Play_Game_Together', { name }),
void sdk.rest.post('/v1/chat.sendMessage', {
message: {
_id: Random.id(),
rid: group._id,
msg: t('Apps_Game_Center_Play_Game_Together', { name }),
},
});
}
onClose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const useReadReceiptsDetailsAction = (message: IMessage): MessageActionCo
setModal(
<ReadReceiptsModal
messageId={message._id}
rid={message.rid}
onClose={() => {
setModal(null);
}}
Expand Down
10 changes: 6 additions & 4 deletions apps/meteor/client/hooks/notification/useNotification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ export const useNotification = () => {
n.addEventListener(
'reply',
({ response }) =>
void sdk.call('sendMessage', {
_id: Random.id(),
rid,
msg: response,
void sdk.rest.post('/v1/chat.sendMessage', {
message: {
_id: Random.id(),
rid,
msg: response,
},
}),
);
}
Expand Down
8 changes: 6 additions & 2 deletions apps/meteor/client/lib/chats/flows/sendMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ const process = async (chat: ChatAPI, message: IMessage, previewUrls?: string[],

chat.composer?.clear();
await runOptimisticSendMessage(message);
await sdk.call('sendMessage', message, previewUrls);

// after the request is complete we can go ahead and mark as sent
await sdk.rest.post('/v1/chat.sendMessage', { message, previewUrls });

// Clear the optimistic `temp` flag only if the messages stream hasn't already
// replaced the record. Overwriting with the server response can clobber stream
// updates that arrive first — e.g. read-receipt-driven `unread: false`, async
// URL/quote attachments, or E2EE decrypt — leading to stale UI state.
Messages.state.update(
(record) => record._id === message._id && record.temp === true,
({ temp: _, ...record }) => record,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
import type { IMessage } from '@rocket.chat/core-typings';
import type { IMessage, IRoom } from '@rocket.chat/core-typings';
import { GenericModal, GenericModalSkeleton } from '@rocket.chat/ui-client';
import { useMethod, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import { useQuery } from '@tanstack/react-query';
import { useEndpoint, useStream, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';

import ReadReceiptRow from './ReadReceiptRow';
import { mapReadReceiptFromApi } from '../../../../lib/utils/mapReadReceiptFromApi';

type ReadReceiptsModalProps = {
messageId: IMessage['_id'];
rid?: IRoom['_id'];
onClose: () => void;
};

const ReadReceiptsModal = ({ messageId, onClose }: ReadReceiptsModalProps) => {
const ReadReceiptsModal = ({ messageId, rid, onClose }: ReadReceiptsModalProps): ReactElement => {
const { t } = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();
const queryClient = useQueryClient();
const subscribeToNotifyRoom = useStream('notify-room');

const getReadReceipts = useMethod('getReadReceipts');
const getReadReceipts = useEndpoint('GET', '/v1/chat.getMessageReadReceipts');

const queryKey = ['read-receipts', messageId];

const readReceiptsResult = useQuery({
queryKey: ['read-receipts', messageId],
queryFn: () => getReadReceipts({ messageId }),
queryKey,
queryFn: async () => (await getReadReceipts({ messageId })).receipts.map(mapReadReceiptFromApi),
});

useEffect(() => {
if (!rid) {
return;
}
return subscribeToNotifyRoom(`${rid}/messagesRead`, () => {
queryClient.invalidateQueries({ queryKey });
});
}, [rid, queryClient, queryKey, subscribeToNotifyRoom]);

useEffect(() => {
if (readReceiptsResult.isError) {
dispatchToastMessage({ type: 'error', message: readReceiptsResult.error });
Expand Down
6 changes: 3 additions & 3 deletions apps/meteor/ee/server/lib/message-read-receipt/ReadReceipt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ReadReceiptClass {
return;
}

void this.storeReadReceipts(
await this.storeReadReceipts(
() => {
return Messages.findVisibleUnreadMessagesByRoomAndDate(roomId, userLastSeen).toArray();
},
Expand Down Expand Up @@ -80,7 +80,7 @@ class ReadReceiptClass {
}
}

void this.storeReadReceipts(
await this.storeReadReceipts(
() => {
return Promise.resolve([message]);
},
Expand All @@ -101,7 +101,7 @@ class ReadReceiptClass {
return;
}

void this.storeReadReceipts(
await this.storeReadReceipts(
() => {
return Messages.findUnreadThreadMessagesByDate(message.rid, tmid, userId, userLastSeen).toArray();
},
Expand Down
3 changes: 3 additions & 0 deletions apps/meteor/ee/server/methods/getReadReceipts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { check } from 'meteor/check';
import { Meteor } from 'meteor/meteor';

import { canAccessRoomIdAsync } from '../../../app/authorization/server/functions/canAccessRoom';
import { methodDeprecationLogger } from '../../../app/lib/server/lib/deprecationWarningLogger';
import { ReadReceipt } from '../lib/message-read-receipt/ReadReceipt';

declare module '@rocket.chat/ddp-client' {
Expand Down Expand Up @@ -37,6 +38,8 @@ export const getReadReceiptsFunction = async function (messageId: IMessage['_id'

Meteor.methods<ServerMethods>({
async getReadReceipts({ messageId }) {
methodDeprecationLogger.method('getReadReceipts', '9.0.0', '/v1/chat.getMessageReadReceipts');

check(messageId, String);

const uid = Meteor.userId();
Expand Down
Loading