Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/renderer/hooks/useNotifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ export const useNotifications = (): UseNotificationsResult => {
const notificationCount = getNotificationCount(notifications);
const hasNotifications = notificationCount > 0;
const hasMoreAccountNotifications = hasMoreNotifications(notifications);
const hasAnyAccountError = notifications.some(
(account) => account.error !== null,
);

const isErrorOrPaused = isError || isPaused;

Expand Down Expand Up @@ -211,9 +214,9 @@ export const useNotifications = (): UseNotificationsResult => {
.updateNotificationStatus(
notificationCount,
hasMoreAccountNotifications,
isErrorOrPaused,
hasAnyAccountError,
);
}, [notificationCount, hasMoreAccountNotifications, isErrorOrPaused]);
}, [notificationCount, hasMoreAccountNotifications, hasAnyAccountError]);

const refetchNotifications = useCallback(async () => {
await refetch();
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/stores/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const DEFAULT_FILTERS_STATE: FiltersState = {
export const DEFAULT_RUNTIME_STATE = {
notificationCount: 0,
hasMoreAccountNotifications: false,
isError: false,
hasAnyAccountError: false,
isOnline: true,
};

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/stores/subscriptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ describe('renderer/stores/subscriptions.ts', () => {
expect(tray.setTrayIconColorAndTitle).toHaveBeenCalledTimes(1);
});

it('should trigger setTrayIconColorAndTitle when isError changes', () => {
it('should trigger setTrayIconColorAndTitle when hasAnyAccountError changes', () => {
useRuntimeStore.getState().updateNotificationStatus(0, false, true);

expect(tray.setTrayIconColorAndTitle).toHaveBeenCalledTimes(1);
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/stores/subscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export function initializeStoreSubscriptions(): () => void {
(state) => ({
notificationCount: state.notificationCount,
hasMoreAccountNotifications: state.hasMoreAccountNotifications,
isError: state.isError,
hasAnyAccountError: state.hasAnyAccountError,
isOnline: state.isOnline,
}),
setTrayIconColorAndTitle,
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/stores/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ export type SettingsStore = SettingsState & SettingsActions;
export interface RuntimeState {
notificationCount: number;
hasMoreAccountNotifications: boolean;
isError: boolean;
hasAnyAccountError: boolean;
isOnline: boolean;
}

Expand All @@ -322,7 +322,7 @@ export interface RuntimeActions {
updateNotificationStatus: (
notificationCount: number,
hasMoreAccountNotifications: boolean,
isError: boolean,
hasAnyAccountError: boolean,
) => void;

/**
Expand Down
19 changes: 11 additions & 8 deletions src/renderer/stores/useRuntimeStore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,34 @@ describe('renderer/stores/useRuntimeStore.ts', () => {
const {
notificationCount,
hasMoreAccountNotifications,
isError,
hasAnyAccountError,
isOnline,
} = useRuntimeStore.getState();

expect(notificationCount).toBe(0);
expect(hasMoreAccountNotifications).toBe(false);
expect(isError).toBe(false);
expect(hasAnyAccountError).toBe(false);
expect(isOnline).toBe(true);
});

it('should update notification status', () => {
useRuntimeStore.getState().updateNotificationStatus(10, true, false);
useRuntimeStore.getState().updateNotificationStatus(10, true, true);

const { notificationCount, hasMoreAccountNotifications, isError } =
useRuntimeStore.getState();
const {
notificationCount,
hasMoreAccountNotifications,
hasAnyAccountError,
} = useRuntimeStore.getState();

expect(notificationCount).toBe(10);
expect(hasMoreAccountNotifications).toBe(true);
expect(isError).toBe(false);
expect(hasAnyAccountError).toBe(true);
});

it('should reflect error state', () => {
it('should reflect hasAnyAccountError state', () => {
useRuntimeStore.getState().updateNotificationStatus(0, false, true);

expect(useRuntimeStore.getState().isError).toBe(true);
expect(useRuntimeStore.getState().hasAnyAccountError).toBe(true);
});

it('should update online status', () => {
Expand Down
10 changes: 7 additions & 3 deletions src/renderer/stores/useRuntimeStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ const useRuntimeStore = create<RuntimeStore>()(
subscribeWithSelector((set) => ({
...DEFAULT_RUNTIME_STATE,

/** Updates the notification count, hasMore flag, and error flag from the latest fetch result. */
/** Updates the notification count, hasMore flag, and account error flag from the latest fetch result. */
updateNotificationStatus: (
notificationCount: number,
hasMoreAccountNotifications: boolean,
isError: boolean,
hasAnyAccountError: boolean,
) => {
set({ notificationCount, hasMoreAccountNotifications, isError });
set({
notificationCount,
hasMoreAccountNotifications,
hasAnyAccountError,
});
},

/** Updates the online/offline connectivity status. */
Expand Down
10 changes: 5 additions & 5 deletions src/renderer/utils/system/tray.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('renderer/utils/system/tray.ts', () => {
useRuntimeStore.setState({
notificationCount: 0,
hasMoreAccountNotifications: false,
isError: false,
hasAnyAccountError: false,
isOnline: true,
});
useSettingsStore.setState({
Expand Down Expand Up @@ -121,8 +121,8 @@ describe('renderer/utils/system/tray.ts', () => {
);
});

it('should pass appState error when isError is true', () => {
useRuntimeStore.setState({ isError: true });
it('should pass appState error when any account has an error', () => {
useRuntimeStore.setState({ hasAnyAccountError: true });

setTrayIconColorAndTitle();

Expand All @@ -135,8 +135,8 @@ describe('renderer/utils/system/tray.ts', () => {
expect(updateTrayTitleSpy).toHaveBeenCalledWith('');
});

it('should pass appState offline (not error) when both isError and isOnline are false', () => {
useRuntimeStore.setState({ isError: true, isOnline: false });
it('should pass appState offline (not error) when both hasAnyAccountError and isOnline are false', () => {
useRuntimeStore.setState({ hasAnyAccountError: true, isOnline: false });

setTrayIconColorAndTitle();

Expand Down
14 changes: 9 additions & 5 deletions src/renderer/utils/system/tray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@
* Updates the tray icon and title using the current notification status,
* online status, and settings store values.
*
* Notification status (count, hasMore, isError) is read from useRuntimeStore,
* Notification status (count, hasMore, hasAnyAccountError) is read from useRuntimeStore,
* which is kept up-to-date by useNotifications with already-filtered values.
* This avoids re-applying filter logic against the raw query cache.
*
* Designed to be called any time the tray needs to reflect current state,
* whether triggered by a notification fetch, a settings change, or an online/offline event.
*/
export function setTrayIconColorAndTitle() {
const { notificationCount, hasMoreAccountNotifications, isError, isOnline } =
useRuntimeStore.getState();
const {
notificationCount,
hasMoreAccountNotifications,
hasAnyAccountError,
isOnline,
} = useRuntimeStore.getState();
const {
showNotificationsCountInTray,
useUnreadActiveIcon,
Expand All @@ -31,7 +35,7 @@
let title = '';
if (
isOnline &&
!isError &&
!hasAnyAccountError &&
notificationCount > 0 &&
showNotificationsCountInTray
) {
Expand All @@ -40,9 +44,9 @@

const appState: TrayAppState = !isOnline
? 'offline'
: isError
: hasAnyAccountError
? 'error'
: 'online';

Check warning on line 49 in src/renderer/utils/system/tray.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested ternary operation into an independent statement.

See more on https://sonarcloud.io/project/issues?id=setchy_atlassify&issues=AZ4CwfDySJamc8Nh8nIE&open=AZ4CwfDySJamc8Nh8nIE&pullRequest=2816

const idleIconVariant: TrayIdleIconVariant = useAlternateIdleIcon
? 'alternative'
Expand Down
Loading