Service Notifications: Fix marking as read

This commit is contained in:
Alexander Zinchuk 2021-11-12 18:45:45 +03:00
parent 8b959f3fb1
commit ac8eee48ec
5 changed files with 42 additions and 18 deletions

View File

@ -77,7 +77,6 @@ type StateProps = {
isBot?: boolean;
messageIds?: number[];
messagesById?: Record<number, ApiMessage>;
isUnread?: boolean;
firstUnreadId?: number;
isViewportNewest?: boolean;
isRestricted?: boolean;
@ -125,7 +124,6 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
messageIds,
messagesById,
firstUnreadId,
isUnread,
isViewportNewest,
threadFirstMessageId,
isRestricted,
@ -174,12 +172,11 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
}, [firstUnreadId]);
// Updated only once when messages are loaded (as we want the unread divider to keep its position)
const withUnreadDivider = areMessagesLoaded && isUnread;
useOnChange(() => {
if (withUnreadDivider) {
if (areMessagesLoaded) {
memoUnreadDividerBeforeIdRef.current = memoFirstUnreadIdRef.current;
}
}, [withUnreadDivider]);
}, [areMessagesLoaded]);
useOnChange(() => {
memoFocusingIdRef.current = focusingId;
@ -506,7 +503,7 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
messageIds={messageIds || [lastMessage!.id]}
messageGroups={messageGroups || groupMessages([lastMessage!])}
isViewportNewest={Boolean(isViewportNewest)}
isUnread={Boolean(isUnread)}
isUnread={Boolean(firstUnreadId)}
withUsers={withUsers}
noAvatars={noAvatars}
containerRef={containerRef}
@ -581,7 +578,6 @@ export default memo(withGlobal<OwnProps>(
isBot: Boolean(chatBot),
messageIds,
messagesById,
isUnread: Boolean(chat.unreadCount),
firstUnreadId: selectFirstUnreadId(global, chatId, threadId),
isViewportNewest: type !== 'thread' || selectIsViewportNewest(global, chatId, threadId),
threadFirstMessageId: selectFirstMessageId(global, chatId, threadId),

View File

@ -76,6 +76,7 @@ export interface ServiceNotification {
id: number;
message: ApiMessage;
version?: string;
isUnread?: boolean;
}
export type GlobalState = {

View File

@ -485,15 +485,24 @@ addReducer('markMessageListRead', (global, actions, payload) => {
return undefined;
}
if (chatId === SERVICE_NOTIFICATIONS_USER_ID) {
global = {
...global,
serviceNotifications: global.serviceNotifications.map((notification) => {
return notification.isUnread && notification.id <= maxId ? { ...notification, isUnread: false } : notification;
}),
};
}
const viewportIds = selectViewportIds(global, chatId, threadId);
const minId = selectFirstUnreadId(global, chatId, threadId);
if (!viewportIds || !minId || !chat.unreadCount) {
return undefined;
return global;
}
const readCount = countSortedIds(viewportIds!, minId, maxId);
if (!readCount) {
return undefined;
return global;
}
return updateChat(global, chatId, {

View File

@ -43,7 +43,7 @@ import parseMessageInput from '../../../util/parseMessageInput';
const FOCUS_DURATION = 1500;
const FOCUS_NO_HIGHLIGHT_DURATION = FAST_SMOOTH_MAX_DURATION + ANIMATION_END_DELAY;
const POLL_RESULT_OPEN_DELAY_MS = 450;
const SERVICE_NOTIFICATIONS_MAX_AMOUNT = 1e4;
const SERVICE_NOTIFICATIONS_MAX_AMOUNT = 1e3;
let blurTimeout: number | undefined;
@ -609,12 +609,13 @@ addReducer('createServiceNotification', (global, actions, payload) => {
id,
message,
version,
isUnread: true,
};
setGlobal({
...global,
serviceNotifications: [
...serviceNotifications,
...serviceNotifications.slice(-SERVICE_NOTIFICATIONS_MAX_AMOUNT),
serviceNotification,
],
});

View File

@ -7,7 +7,7 @@ import {
MAIN_THREAD_ID,
} from '../../api/types';
import { LOCAL_MESSAGE_ID_BASE } from '../../config';
import { LOCAL_MESSAGE_ID_BASE, SERVICE_NOTIFICATIONS_USER_ID } from '../../config';
import {
selectChat, selectIsChatWithBot, selectIsChatWithSelf,
} from './chats';
@ -583,19 +583,36 @@ export function selectFirstUnreadId(global: GlobalState, chatId: string, threadI
return undefined;
}
if (outlyingIds) {
const found = !lastReadId ? outlyingIds[0] : outlyingIds.find((id) => {
return id > lastReadId && byId[id] && (!byId[id].isOutgoing || byId[id].isFromScheduled);
const lastReadServiceNotificationId = chatId === SERVICE_NOTIFICATIONS_USER_ID
? global.serviceNotifications.reduce((max, notification) => {
return !notification.isUnread && notification.id > max ? notification.id : max;
}, -1)
: -1;
function findAfterLastReadId(listIds: number[]) {
if (!lastReadId) {
return listIds[0];
}
return listIds.find((id) => {
return (
id > lastReadId
&& byId[id]
&& (!byId[id].isOutgoing || byId[id].isFromScheduled)
&& id > lastReadServiceNotificationId
);
});
}
if (outlyingIds) {
const found = findAfterLastReadId(outlyingIds);
if (found) {
return found;
}
}
if (listedIds) {
const found = !lastReadId ? listedIds[0] : listedIds.find((id) => {
return id > lastReadId && byId[id] && (!byId[id].isOutgoing || byId[id].isFromScheduled);
});
const found = findAfterLastReadId(listedIds);
if (found) {
return found;
}