Skip to content

Commit 10a7b9c

Browse files
authored
refactor: app state handling (#2415)
Signed-off-by: Adam Setch <adam.setch@outlook.com>
1 parent f9aedf0 commit 10a7b9c

File tree

1 file changed

+69
-65
lines changed

1 file changed

+69
-65
lines changed

src/renderer/context/App.tsx

Lines changed: 69 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,21 @@ export interface AppContextState {
102102
export const AppContext = createContext<Partial<AppContextState>>({});
103103

104104
export const AppProvider = ({ children }: { children: ReactNode }) => {
105+
const existingState = loadState();
106+
107+
const [auth, setAuth] = useState<AuthState>(
108+
existingState.auth
109+
? { ...defaultAuth, ...existingState.auth }
110+
: defaultAuth,
111+
);
112+
113+
const [settings, setSettings] = useState<SettingsState>(
114+
existingState.settings
115+
? { ...defaultSettings, ...existingState.settings }
116+
: defaultSettings,
117+
);
118+
105119
const { setColorMode, setDayScheme, setNightScheme } = useTheme();
106-
const [auth, setAuth] = useState<AuthState>(defaultAuth);
107-
const [settings, setSettings] = useState<SettingsState>(defaultSettings);
108-
const [needsAccountRefresh, setNeedsAccountRefresh] = useState(false);
109120

110121
const {
111122
notifications,
@@ -119,70 +130,26 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
119130
} = useNotifications();
120131

121132
const notificationCount = getNotificationCount(notifications);
133+
122134
const unreadNotificationCount = getUnreadNotificationCount(notifications);
123135

124136
const hasNotifications = useMemo(
125137
() => notificationCount > 0,
126138
[notificationCount],
127139
);
140+
128141
const hasUnreadNotifications = useMemo(
129142
() => unreadNotificationCount > 0,
130143
[unreadNotificationCount],
131144
);
132145

133-
const restorePersistedState = useCallback(async () => {
134-
const existing = loadState();
135-
136-
// Restore settings before accounts to ensure filters are available before fetching notifications
137-
if (existing.settings) {
138-
setSettings({ ...defaultSettings, ...existing.settings });
139-
}
140-
141-
if (existing.auth) {
142-
setAuth({ ...defaultAuth, ...existing.auth });
143-
144-
// Trigger the effect to refresh accounts
145-
setNeedsAccountRefresh(true);
146-
}
147-
}, []);
148-
149-
useEffect(() => {
150-
restorePersistedState();
151-
}, [restorePersistedState]);
152-
153-
// Refresh account details on startup
154-
useEffect(() => {
155-
if (!needsAccountRefresh) {
146+
const refreshAllAccounts = useCallback(() => {
147+
if (!auth.accounts.length) {
156148
return;
157149
}
158150

159-
Promise.all(auth.accounts.map(refreshAccount)).finally(() => {
160-
setNeedsAccountRefresh(false);
161-
});
162-
}, [needsAccountRefresh, auth.accounts]);
163-
164-
// Refresh account details on interval
165-
useIntervalTimer(() => {
166-
Promise.all(auth.accounts.map(refreshAccount));
167-
}, Constants.REFRESH_ACCOUNTS_INTERVAL_MS);
168-
169-
useEffect(() => {
170-
const colorMode = mapThemeModeToColorMode(settings.theme);
171-
const colorScheme = mapThemeModeToColorScheme(
172-
settings.theme,
173-
settings.increaseContrast,
174-
);
175-
176-
setColorMode(colorMode);
177-
setDayScheme(colorScheme ?? DEFAULT_DAY_COLOR_SCHEME);
178-
setNightScheme(colorScheme ?? DEFAULT_NIGHT_COLOR_SCHEME);
179-
}, [
180-
settings.theme,
181-
settings.increaseContrast,
182-
setColorMode,
183-
setDayScheme,
184-
setNightScheme,
185-
]);
151+
return Promise.all(auth.accounts.map(refreshAccount));
152+
}, [auth.accounts]);
186153

187154
// biome-ignore lint/correctness/useExhaustiveDependencies: Fetch new notifications when account count or filters change
188155
useEffect(() => {
@@ -211,6 +178,35 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
211178
settings.fetchType === FetchType.INACTIVITY ? settings.fetchInterval : null,
212179
);
213180

181+
// biome-ignore lint/correctness/useExhaustiveDependencies: Refresh account details on startup
182+
useEffect(() => {
183+
refreshAllAccounts();
184+
}, []);
185+
186+
// Refresh account details on interval
187+
useIntervalTimer(() => {
188+
refreshAllAccounts();
189+
}, Constants.REFRESH_ACCOUNTS_INTERVAL_MS);
190+
191+
// Theme
192+
useEffect(() => {
193+
const colorMode = mapThemeModeToColorMode(settings.theme);
194+
const colorScheme = mapThemeModeToColorScheme(
195+
settings.theme,
196+
settings.increaseContrast,
197+
);
198+
199+
setColorMode(colorMode);
200+
setDayScheme(colorScheme ?? DEFAULT_DAY_COLOR_SCHEME);
201+
setNightScheme(colorScheme ?? DEFAULT_NIGHT_COLOR_SCHEME);
202+
}, [
203+
settings.theme,
204+
settings.increaseContrast,
205+
setColorMode,
206+
setDayScheme,
207+
setNightScheme,
208+
]);
209+
214210
// biome-ignore lint/correctness/useExhaustiveDependencies: We want to update the tray on setting or notification changes
215211
useEffect(() => {
216212
setUseUnreadActiveIcon(settings.useUnreadActiveIcon);
@@ -242,23 +238,29 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
242238
}, []);
243239

244240
const clearFilters = useCallback(() => {
245-
const newSettings = { ...settings, ...defaultFilters };
246-
setSettings(newSettings);
247-
saveState({ auth, settings: newSettings });
248-
}, [auth, settings]);
241+
setSettings((prevSettings) => {
242+
const newSettings = { ...prevSettings, ...defaultFilters };
243+
saveState({ auth, settings: newSettings });
244+
return newSettings;
245+
});
246+
}, [auth]);
249247

250248
const resetSettings = useCallback(() => {
251-
setSettings(defaultSettings);
252-
saveState({ auth, settings: defaultSettings });
249+
setSettings(() => {
250+
saveState({ auth, settings: defaultSettings });
251+
return defaultSettings;
252+
});
253253
}, [auth]);
254254

255255
const updateSetting = useCallback(
256256
(name: keyof SettingsState, value: SettingsValue) => {
257-
const newSettings = { ...settings, [name]: value };
258-
setSettings(newSettings);
259-
saveState({ auth, settings: newSettings });
257+
setSettings((prevSettings) => {
258+
const newSettings = { ...prevSettings, [name]: value };
259+
saveState({ auth, settings: newSettings });
260+
return newSettings;
261+
});
260262
},
261-
[auth, settings],
263+
[auth],
262264
);
263265

264266
const updateFilter = useCallback(
@@ -267,7 +269,7 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
267269
? [...settings[name], value]
268270
: settings[name].filter((item) => item !== value);
269271

270-
updateSetting(name, updatedFilters as FilterValue[]);
272+
updateSetting(name, updatedFilters);
271273
},
272274
[updateSetting, settings],
273275
);
@@ -289,7 +291,9 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
289291
window.gitify.zoom.getLevel(),
290292
);
291293

292-
updateSetting('zoomPercentage', zoomPercentage);
294+
if (zoomPercentage !== settings.zoomPercentage) {
295+
updateSetting('zoomPercentage', zoomPercentage);
296+
}
293297
}, DELAY);
294298
};
295299

0 commit comments

Comments
 (0)