diff --git a/ts/components/leftpane/ActionsPanel.tsx b/ts/components/leftpane/ActionsPanel.tsx index 1186699ef..3c6a535da 100644 --- a/ts/components/leftpane/ActionsPanel.tsx +++ b/ts/components/leftpane/ActionsPanel.tsx @@ -1,3 +1,4 @@ +import { ipcRenderer } from 'electron'; import { debounce } from 'lodash'; import { useEffect, useRef, useState } from 'react'; @@ -13,6 +14,8 @@ import { syncConfigurationIfNeeded } from '../../session/utils/sync/syncUtils'; import { clearSearch } from '../../state/ducks/search'; import { resetLeftOverlayMode, SectionType, showLeftPaneSection } from '../../state/ducks/section'; import { + _getGlobalUnreadCount, + _getSortedConversations, getGlobalUnreadMessageCount, getOurPrimaryConversation, } from '../../state/selectors/conversations'; @@ -37,18 +40,18 @@ import { LeftPaneSectionContainer } from './LeftPaneSectionContainer'; import { SettingsKey } from '../../data/settings-key'; import { useFetchLatestReleaseFromFileServer } from '../../hooks/useFetchLatestReleaseFromFileServer'; +import { useHotkey } from '../../hooks/useHotkey'; import { forceRefreshRandomSnodePool, getFreshSwarmFor, } from '../../session/apis/snode_api/snodePool'; import { ConfigurationSync } from '../../session/utils/job_runners/jobs/ConfigurationSyncJob'; +import { getIsModalVisble } from '../../state/selectors/modal'; import { useIsDarkTheme } from '../../state/selectors/theme'; import { switchThemeTo } from '../../themes/switchTheme'; import { ReleasedFeatures } from '../../util/releaseFeature'; import { getOppositeTheme } from '../../util/theme'; import { SessionNotificationCount } from '../icon/SessionNotificationCount'; -import { useHotkey } from '../../hooks/useHotkey'; -import { getIsModalVisble } from '../../state/selectors/modal'; const Section = (props: { type: SectionType }) => { const ourNumber = useSelector(getOurNumber); @@ -216,6 +219,12 @@ const doAppStartUp = async () => { }, 20000); }; +global.setTimeout(() => { + const unreadMessageCount = useSelector(getGlobalUnreadMessageCount); + // Send the calculated count to the main process to update the badge count + ipcRenderer.send('update-badge-count', unreadMessageCount); +}, 3000); + /** * ActionsPanel is the far left banner (not the left pane). * The panel with buttons to switch between the message/contact/settings/theme views diff --git a/ts/mains/main_node.ts b/ts/mains/main_node.ts index b9b221bc0..80fb672db 100644 --- a/ts/mains/main_node.ts +++ b/ts/mains/main_node.ts @@ -10,6 +10,7 @@ import { dialog, protocol as electronProtocol, ipcMain as ipc, + ipcMain, IpcMainEvent, Menu, nativeTheme, @@ -1023,6 +1024,14 @@ ipc.on('get-start-in-tray', event => { } }); +ipcMain.on('update-badge-count', (_event, count) => { + if (count === 0) { + app.setBadgeCount(0); // Clear the badge + } else { + app.setBadgeCount(count); // Set the badge count + } +}); + ipc.on('get-opengroup-pruning', event => { try { const val = userConfig.get('opengroupPruning'); diff --git a/ts/state/selectors/conversations.ts b/ts/state/selectors/conversations.ts index 5473c6e55..336d02ed4 100644 --- a/ts/state/selectors/conversations.ts +++ b/ts/state/selectors/conversations.ts @@ -306,7 +306,9 @@ const _getContacts = ( }); }; -const _getGlobalUnreadCount = (sortedConversations: Array): number => { +export const _getGlobalUnreadCount = ( + sortedConversations: Array +): number => { let globalUnreadCount = 0; for (const conversation of sortedConversations) { // Blocked conversation are now only visible from the settings, not in the conversation list, so don't add it neither to the contacts list nor the conversation list