[FIX] Read receipts showing first messages of the room as read even if not read by everyone (#24508)

Co-authored-by: dougfabris <devfabris@gmail.com>
pull/24532/head
Diego Sampaio 4 years ago committed by GitHub
parent a1095a464b
commit 9fd4c04d74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/models/server/models/Subscriptions.js
  2. 24
      client/hooks/useFormatDateAndTime.js
  3. 29
      client/hooks/useFormatDateAndTime.ts
  4. 3
      client/views/account/tokens/AccountTokensRow.tsx
  5. 2
      client/views/room/modals/ReadReceiptsModal/ReadReceiptRow.tsx
  6. 2
      imports/message-read-receipt/server/hooks.js
  7. 25
      imports/message-read-receipt/server/lib/ReadReceipt.js

@ -556,9 +556,6 @@ export class Subscriptions extends Base {
return this.db.findOne(
{
rid,
ls: {
$exists: true,
},
},
{
sort: {

@ -1,24 +0,0 @@
import moment from 'moment';
import { useCallback } from 'react';
import { useSetting } from '../contexts/SettingsContext';
import { useUserPreference } from '../contexts/UserContext';
export const useFormatDateAndTime = () => {
const clockMode = useUserPreference('clockMode', false);
const format = useSetting('Message_TimeAndDateFormat');
return useCallback(
(time) => {
switch (clockMode) {
case 1:
return moment(time).format('MMMM D, Y h:mm A');
case 2:
return moment(time).format('MMMM D, Y H:mm');
default:
return moment(time).format(format);
}
},
[clockMode, format],
);
};

@ -0,0 +1,29 @@
import moment, { MomentInput } from 'moment';
import { useCallback } from 'react';
import { useSetting } from '../contexts/SettingsContext';
import { useUserPreference } from '../contexts/UserContext';
type UseFormatDateAndTimeParams = {
withSeconds?: boolean;
};
export const useFormatDateAndTime = ({ withSeconds }: UseFormatDateAndTimeParams = {}): ((input: MomentInput) => string) => {
const clockMode = useUserPreference('clockMode');
const format = useSetting('Message_TimeAndDateFormat') as string;
return useCallback(
(time) => {
switch (clockMode) {
case 1:
return moment(time).format(withSeconds ? 'MMMM D, Y h:mm:ss A' : 'MMMM D, Y h:mm A');
case 2:
return moment(time).format(withSeconds ? 'MMMM D, Y H:mm:ss' : 'MMMM D, Y H:mm');
default:
return moment(time).format(withSeconds ? 'L LTS' : format);
}
},
[clockMode, format, withSeconds],
);
};

@ -1,4 +1,5 @@
import { Button, ButtonGroup, Icon, Table } from '@rocket.chat/fuselage';
import type { MomentInput } from 'moment';
import React, { useCallback, FC } from 'react';
import { useTranslation } from '../../../contexts/TranslationContext';
@ -6,7 +7,7 @@ import { useFormatDateAndTime } from '../../../hooks/useFormatDateAndTime';
type AccountTokensRowProps = {
bypassTwoFactor: unknown;
createdAt: unknown;
createdAt: MomentInput;
isMedium: boolean;
lastTokenPart: string;
name: string;

@ -16,7 +16,7 @@ const hoverStyle = css`
const ReadReceiptRow = ({ user, ts }: ReadReceipt): ReactElement => {
const displayName = useUserDisplayName(user);
const formatDateAndTime = useFormatDateAndTime();
const formatDateAndTime = useFormatDateAndTime({ withSeconds: true });
return (
<Box

@ -16,7 +16,7 @@ callbacks.add(
}
// mark message as read as well
ReadReceipt.markMessageAsReadBySender(message, room._id, message.u._id);
ReadReceipt.markMessageAsReadBySender(message, room, message.u._id);
return message;
},

@ -22,7 +22,7 @@ const updateMessages = debounceByRoomId(
Meteor.bindEnvironment(({ _id, lm }) => {
// @TODO maybe store firstSubscription in room object so we don't need to call the above update method
const firstSubscription = Subscriptions.getMinimumLastSeenByRoomId(_id);
if (!firstSubscription) {
if (!firstSubscription || !firstSubscription.ls) {
return;
}
@ -42,31 +42,32 @@ export const ReadReceipt = {
const room = Rooms.findOneById(roomId, { fields: { lm: 1 } });
// if users last seen is greadebounceByRoomIdter than room's last message, it means the user already have this room marked as read
// if users last seen is greater than room's last message, it means the user already have this room marked as read
if (userLastSeen > room.lm) {
return;
}
if (userLastSeen) {
this.storeReadReceipts(Messages.findUnreadMessagesByRoomAndDate(roomId, userLastSeen), roomId, userId);
}
this.storeReadReceipts(Messages.findUnreadMessagesByRoomAndDate(roomId, userLastSeen), roomId, userId);
updateMessages(room);
},
markMessageAsReadBySender(message, roomId, userId) {
markMessageAsReadBySender(message, { _id: roomId, t }, userId) {
if (!settings.get('Message_Read_Receipt_Enabled')) {
return;
}
// this will usually happens if the message sender is the only one on the room
const firstSubscription = Subscriptions.getMinimumLastSeenByRoomId(roomId);
if (firstSubscription && message.unread && message.ts < firstSubscription.ls) {
Messages.setAsReadById(message._id, firstSubscription.ls);
if (!message.unread) {
return;
}
// mark message as read if the sender is the only one in the room
const isUserAlone = Subscriptions.findByRoomIdAndNotUserId(roomId, userId, { fields: { _id: 1 } }).count() === 0;
if (isUserAlone) {
Messages.setAsReadById(message._id);
}
const room = Rooms.findOneById(roomId, { fields: { t: 1 } });
const extraData = roomTypes.getConfig(room.t).getReadReceiptsExtraData(message);
const extraData = roomTypes.getConfig(t).getReadReceiptsExtraData(message);
this.storeReadReceipts([{ _id: message._id }], roomId, userId, extraData);
},

Loading…
Cancel
Save