@@ -102,10 +102,21 @@ export interface AppContextState {
102102export const AppContext = createContext < Partial < AppContextState > > ( { } ) ;
103103
104104export 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