From 111638b9ba5c8324cdbcb555771645c2a5153c76 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 28 Jan 2022 02:12:17 +0100 Subject: [PATCH] Middle Header: Fix not updating unread counter --- src/components/main/Main.tsx | 6 ++--- src/components/middle/MiddleHeader.tsx | 21 +++------------ src/components/middle/UnreadCount.tsx | 31 +++++++++++++++++++++ src/modules/actions/api/sync.ts | 4 +-- src/modules/actions/apiUpdaters/chats.ts | 8 +++--- src/modules/selectors/chats.ts | 34 ++++++++++++++---------- 6 files changed, 64 insertions(+), 40 deletions(-) create mode 100644 src/components/middle/UnreadCount.tsx diff --git a/src/components/main/Main.tsx b/src/components/main/Main.tsx index f7dfa2c1..ef73d96e 100644 --- a/src/components/main/Main.tsx +++ b/src/components/main/Main.tsx @@ -12,7 +12,7 @@ import { } from '../../config'; import { selectChatMessage, - selectCountNotMutedUnread, + selectCountNotMutedUnreadOptimized, selectIsForwardModalOpen, selectIsMediaViewerOpen, selectIsRightColumnShown, @@ -248,7 +248,7 @@ const Main: FC = ({ const handleBlur = useCallback(() => { updateIsOnline(false); - const initialUnread = selectCountNotMutedUnread(getGlobal()); + const initialUnread = selectCountNotMutedUnreadOptimized(getGlobal()); let index = 0; clearInterval(notificationInterval); @@ -259,7 +259,7 @@ const Main: FC = ({ } if (index % 2 === 0) { - const newUnread = selectCountNotMutedUnread(getGlobal()) - initialUnread; + const newUnread = selectCountNotMutedUnreadOptimized(getGlobal()) - initialUnread; if (newUnread > 0) { updatePageTitle(`${newUnread} notification${newUnread > 1 ? 's' : ''}`); updateIcon(true); diff --git a/src/components/middle/MiddleHeader.tsx b/src/components/middle/MiddleHeader.tsx index 729d41c9..5893355b 100644 --- a/src/components/middle/MiddleHeader.tsx +++ b/src/components/middle/MiddleHeader.tsx @@ -1,7 +1,7 @@ import React, { - FC, memo, useCallback, useEffect, useMemo, useRef, useState, + FC, memo, useCallback, useEffect, useRef, useState, } from '../../lib/teact/teact'; -import { getDispatch, getGlobal, withGlobal } from '../../lib/teact/teactn'; +import { getDispatch, withGlobal } from '../../lib/teact/teactn'; import cycleRestrict from '../../util/cycleRestrict'; import { GlobalState, MessageListType } from '../../global/types'; @@ -26,7 +26,6 @@ import { selectChat, selectChatMessage, selectChatMessages, - selectCountNotMutedUnread, selectForwardedSender, selectIsChatWithBot, selectIsChatWithSelf, @@ -41,7 +40,6 @@ import useEnsureMessage from '../../hooks/useEnsureMessage'; import useWindowSize from '../../hooks/useWindowSize'; import useShowTransition from '../../hooks/useShowTransition'; import useCurrentOrPrev from '../../hooks/useCurrentOrPrev'; -import { formatIntegerCompact } from '../../util/textFormat'; import buildClassName from '../../util/buildClassName'; import useLang from '../../hooks/useLang'; import useConnectionStatus from '../../hooks/useConnectionStatus'; @@ -54,6 +52,7 @@ import HeaderActions from './HeaderActions'; import HeaderPinnedMessage from './HeaderPinnedMessage'; import AudioPlayer from './AudioPlayer'; import GroupCallTopPane from '../calls/group/GroupCallTopPane'; +import UnreadCount from './UnreadCount'; import './MiddleHeader.scss'; @@ -221,14 +220,6 @@ const MiddleHeader: FC = ({ openChat, toggleLeftColumn, exitMessageSelectMode, setBackButtonActive, ]); - const unreadCount = useMemo(() => { - if (!isLeftColumnHideable) { - return undefined; - } - - return selectCountNotMutedUnread(getGlobal()) || undefined; - }, [isLeftColumnHideable]); - const canToolsCollideWithChatInfo = ( windowWidth >= MIN_SCREEN_WIDTH_FOR_STATIC_LEFT_COLUMN && windowWidth < SAFE_SCREEN_WIDTH_FOR_CHAT_INFO @@ -367,11 +358,7 @@ const MiddleHeader: FC = ({ >
- {withUnreadCount && unreadCount && ( -
- {formatIntegerCompact(unreadCount)} -
- )} + {withUnreadCount && }
); } diff --git a/src/components/middle/UnreadCount.tsx b/src/components/middle/UnreadCount.tsx new file mode 100644 index 00000000..af3cf398 --- /dev/null +++ b/src/components/middle/UnreadCount.tsx @@ -0,0 +1,31 @@ +import React, { FC, memo } from '../../lib/teact/teact'; +import { withGlobal } from '../../lib/teact/teactn'; + +import { GlobalState } from '../../global/types'; + +import { selectCountNotMutedUnreadOptimized } from '../../modules/selectors'; +import { formatIntegerCompact } from '../../util/textFormat'; + +type StateProps = { + unreadCount: number; +}; + +const UnreadCount: FC = ({ + unreadCount, +}) => { + if (!unreadCount) { + return undefined; + } + + return ( +
{formatIntegerCompact(unreadCount)}
+ ); +}; + +export default memo(withGlobal( + (global: GlobalState): StateProps => { + return { + unreadCount: selectCountNotMutedUnreadOptimized(global), + }; + }, +)(UnreadCount)); diff --git a/src/modules/actions/api/sync.ts b/src/modules/actions/api/sync.ts index 370da89b..0a5c26a3 100644 --- a/src/modules/actions/api/sync.ts +++ b/src/modules/actions/api/sync.ts @@ -34,7 +34,7 @@ import { selectDraft, selectChatMessage, selectThreadInfo, - selectCountNotMutedUnread, + selectCountNotMutedUnreadOptimized, selectLastServiceNotification, } from '../../selectors'; import { isUserId } from '../../helpers'; @@ -102,7 +102,7 @@ async function afterSync() { await callApi('fetchCurrentUser'); - updateAppBadge(selectCountNotMutedUnread(getGlobal())); + updateAppBadge(selectCountNotMutedUnreadOptimized(getGlobal())); if (DEBUG) { // eslint-disable-next-line no-console diff --git a/src/modules/actions/apiUpdaters/chats.ts b/src/modules/actions/apiUpdaters/chats.ts index 0558e118..875a6971 100644 --- a/src/modules/actions/apiUpdaters/chats.ts +++ b/src/modules/actions/apiUpdaters/chats.ts @@ -19,7 +19,7 @@ import { selectIsChatListed, selectChatListType, selectCurrentMessageList, - selectCountNotMutedUnread, + selectCountNotMutedUnreadOptimized, } from '../../selectors'; import { throttle } from '../../../util/schedulers'; @@ -40,7 +40,7 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => { const newGlobal = updateChat(global, update.id, update.chat, update.newProfilePhoto); setGlobal(newGlobal); - runThrottledForUpdateAppBadge(() => updateAppBadge(selectCountNotMutedUnread(getGlobal()))); + runThrottledForUpdateAppBadge(() => updateAppBadge(selectCountNotMutedUnreadOptimized(getGlobal()))); if (update.chat.id) { closeMessageNotifications({ @@ -77,7 +77,7 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => { case 'updateChatInbox': { setGlobal(updateChat(global, update.id, update.chat)); - runThrottledForUpdateAppBadge(() => updateAppBadge(selectCountNotMutedUnread(getGlobal()))); + runThrottledForUpdateAppBadge(() => updateAppBadge(selectCountNotMutedUnreadOptimized(getGlobal()))); break; } @@ -129,7 +129,7 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => { })); } - updateAppBadge(selectCountNotMutedUnread(getGlobal())); + updateAppBadge(selectCountNotMutedUnreadOptimized(getGlobal())); notifyAboutNewMessage({ chat, message, diff --git a/src/modules/selectors/chats.ts b/src/modules/selectors/chats.ts index 132d3d21..f6642a47 100644 --- a/src/modules/selectors/chats.ts +++ b/src/modules/selectors/chats.ts @@ -9,6 +9,7 @@ import { ALL_FOLDER_ID, ARCHIVED_FOLDER_ID, MEMBERS_LOAD_SLICE, SERVICE_NOTIFICATIONS_USER_ID, } from '../../config'; import { selectNotifyExceptions, selectNotifySettings } from './settings'; +import memoized from '../../util/memoized'; export function selectChat(global: GlobalState, chatId: string): ApiChat | undefined { return global.chats.byId[chatId]; @@ -153,19 +154,14 @@ export function selectChatByUsername(global: GlobalState, username: string) { ); } -// Slow, not to be used in `withGlobal` -export function selectCountNotMutedUnread(global: GlobalState) { - const activeChatIds = global.chats.listIds.active; - if (!activeChatIds) { - return 0; - } - - const chats = global.chats.byId; - const notifySettings = selectNotifySettings(global); - const notifyExceptions = selectNotifyExceptions(global); - - return activeChatIds.reduce((acc, chatId) => { - const chat = chats[chatId]; +const selectCountNotMutedUnreadMemo = memoized(( + activeChatIds: GlobalState['chats']['listIds']['active'], + chatsById: GlobalState['chats']['byId'], + notifySettings: GlobalState['settings']['byKey'], + notifyExceptions: GlobalState['settings']['notifyExceptions'], +) => { + return activeChatIds?.reduce((acc, chatId) => { + const chat = chatsById[chatId]; if ( chat @@ -179,7 +175,17 @@ export function selectCountNotMutedUnread(global: GlobalState) { } return acc; - }, 0); + }, 0) || 0; +}); + +// Still slow but at least memoized +export function selectCountNotMutedUnreadOptimized(global: GlobalState) { + return selectCountNotMutedUnreadMemo( + global.chats.listIds.active, + global.chats.byId, + selectNotifySettings(global), + selectNotifyExceptions(global), + ); } export function selectIsServiceChatReady(global: GlobalState) {