diff --git a/lib/selectors/thread-selectors.js b/lib/selectors/thread-selectors.js --- a/lib/selectors/thread-selectors.js +++ b/lib/selectors/thread-selectors.js @@ -236,6 +236,19 @@ }, ); +const unreadThickThreadIDsSelector: ( + state: BaseAppState<>, +) => $ReadOnlyArray = createSelector( + (state: BaseAppState<>) => state.threadStore.threadInfos, + (threadInfos: RawThreadInfos): $ReadOnlyArray => + Object.entries(threadInfos) + .filter( + ([, threadInfo]) => + !!threadInfo.thick && !!threadInfo.currentUser.unread, + ) + .map(([id]) => id), +); + const unreadCount: (state: BaseAppState<>) => number = createSelector( (state: BaseAppState<>) => state.threadStore.threadInfos, (threadInfos: RawThreadInfos): number => @@ -538,4 +551,5 @@ savedEmojiAvatarSelectorForThread, threadInfosSelectorForThreadType, thickRawThreadInfosSelector, + unreadThickThreadIDsSelector, }; diff --git a/native/push/push-handler.react.js b/native/push/push-handler.react.js --- a/native/push/push-handler.react.js +++ b/native/push/push-handler.react.js @@ -28,9 +28,11 @@ import { threadInfoSelector, allUnreadCounts, + unreadThickThreadIDsSelector, } from 'lib/selectors/thread-selectors.js'; import { isLoggedIn } from 'lib/selectors/user-selectors.js'; import { mergePrefixIntoBody } from 'lib/shared/notif-utils.js'; +import { useTunnelbroker } from 'lib/tunnelbroker/tunnelbroker-context.js'; import { alertTypes, type AlertInfo, @@ -107,6 +109,7 @@ +activeThread: ?string, // Redux state +unreadCount: { +[keyserverID: string]: number }, + +unreadThickThreadIDs: $ReadOnlyArray, +connection: { +[keyserverID: string]: ?ConnectionInfo }, +deviceTokens: { +[keyserverID: string]: ?string, @@ -134,6 +137,14 @@ // withRootContext +rootContext: ?RootContextType, +localToken: ?string, + +tunnelbrokerSocketState: + | { + +connected: true, + +isAuthorized: boolean, + } + | { + +connected: false, + }, }; type State = { +inAppNotifProps: ?{ @@ -318,6 +329,10 @@ const curUnreadCounts = this.props.unreadCount; const curConnections = this.props.connection; + const currentUnreadThickThreads = this.props.unreadThickThreadIDs; + const currentTunnelbrokerConnectionStatus = + this.props.tunnelbrokerSocketState.connected; + const notifStorageUpdates: Array<{ +id: string, +unreadCount: number, @@ -341,9 +356,21 @@ +unreadCount: number, }> = []; + const handleUnreadThickThreadIDsInNotifsStorage = (async () => { + if (currentTunnelbrokerConnectionStatus) { + await commCoreModule.updateUnreadThickThreadsInNotifsStorage( + currentUnreadThickThreads, + ); + return currentUnreadThickThreads; + } + return await commCoreModule.getUnreadThickThreadIDsFromNotifsStorage(); + })(); + + let unreadThickThreadIDs: $ReadOnlyArray; try { - [queriedKeyserverData] = await Promise.all([ + [queriedKeyserverData, unreadThickThreadIDs] = await Promise.all([ commCoreModule.getKeyserverDataFromNotifStorage(notifsStorageQueries), + handleUnreadThickThreadIDsInNotifsStorage, commCoreModule.updateKeyserverDataInNotifStorage(notifStorageUpdates), ]); } catch (e) { @@ -365,6 +392,7 @@ totalUnreadCount += keyserverData.unreadCount; } + totalUnreadCount += unreadThickThreadIDs.length; if (Platform.OS === 'ios') { CommIOSNotifications.setBadgesCount(totalUnreadCount); } else if (Platform.OS === 'android') { @@ -799,8 +827,9 @@ React.memo(function ConnectedPushHandler(props: BaseProps) { const navContext = React.useContext(NavContext); const activeThread = activeMessageListSelector(navContext); - const boundUnreadCount = useSelector(allUnreadCounts); - const boundConnection = useSelector(allConnectionInfosSelector); + const unreadCount = useSelector(allUnreadCounts); + const unreadThickThreadIDs = useSelector(unreadThickThreadIDsSelector); + const connection = useSelector(allConnectionInfosSelector); const deviceTokens = useSelector(deviceTokensSelector); const threadInfos = useSelector(threadInfoSelector); const notifPermissionAlertInfo = useSelector( @@ -818,12 +847,14 @@ const callSetDeviceToken = useSetDeviceToken(); const callSetDeviceTokenFanout = useSetDeviceTokenFanout(); const rootContext = React.useContext(RootContext); + const { socketState: tunnelbrokerSocketState } = useTunnelbroker(); return ( ); });