diff --git a/apps/ui/src/lib/http-api-client.ts b/apps/ui/src/lib/http-api-client.ts index e92ab311..9b06d75e 100644 --- a/apps/ui/src/lib/http-api-client.ts +++ b/apps/ui/src/lib/http-api-client.ts @@ -2763,6 +2763,21 @@ export class HttpApiClient implements ElectronAPI { headers?: Record; enabled?: boolean; }>; + eventHooks?: Array<{ + id: string; + trigger: string; + enabled: boolean; + action: Record; + name?: string; + }>; + ntfyEndpoints?: Array<{ + id: string; + name: string; + serverUrl: string; + topic: string; + authType: string; + enabled: boolean; + }>; }; error?: string; }> => this.get('/api/settings/global'), diff --git a/apps/ui/src/routes/__root.tsx b/apps/ui/src/routes/__root.tsx index 6f5d0758..403c31e3 100644 --- a/apps/ui/src/routes/__root.tsx +++ b/apps/ui/src/routes/__root.tsx @@ -613,7 +613,10 @@ function RootLayoutContent() { // Reconcile ntfy endpoints from server (same rationale as eventHooks) const serverEndpoints = (finalSettings as GlobalSettings).ntfyEndpoints ?? []; const currentEndpoints = useAppStore.getState().ntfyEndpoints; - if (JSON.stringify(serverEndpoints) !== JSON.stringify(currentEndpoints)) { + if ( + JSON.stringify(serverEndpoints) !== JSON.stringify(currentEndpoints) && + serverEndpoints.length > 0 + ) { logger.info( `[FAST_HYDRATE] Reconciling ntfyEndpoints from server (server=${serverEndpoints.length}, store=${currentEndpoints.length})` ); diff --git a/apps/ui/src/store/app-store.ts b/apps/ui/src/store/app-store.ts index 8e4918d1..e4b96eb2 100644 --- a/apps/ui/src/store/app-store.ts +++ b/apps/ui/src/store/app-store.ts @@ -1506,7 +1506,11 @@ export const useAppStore = create()((set, get) => ({ set({ eventHooks: hooks }); try { const httpApi = getHttpApiClient(); - await httpApi.settings.updateGlobal({ eventHooks: hooks }); + await httpApi.settings.updateGlobal({ + eventHooks: hooks, + // Signal the server that an empty array is intentional (not a wipe from stale state) + ...(hooks.length === 0 ? { __allowEmptyEventHooks: true } : {}), + }); } catch (error) { logger.error('Failed to sync event hooks:', error); } @@ -1517,7 +1521,11 @@ export const useAppStore = create()((set, get) => ({ set({ ntfyEndpoints: endpoints }); try { const httpApi = getHttpApiClient(); - await httpApi.settings.updateGlobal({ ntfyEndpoints: endpoints }); + await httpApi.settings.updateGlobal({ + ntfyEndpoints: endpoints, + // Signal the server that an empty array is intentional (not a wipe from stale state) + ...(endpoints.length === 0 ? { __allowEmptyNtfyEndpoints: true } : {}), + }); } catch (error) { logger.error('Failed to sync ntfy endpoints:', error); }