mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-01 08:06:13 +00:00
feat: refetch filters and vacation on push and fan state changes out to screens
This commit is contained in:
@@ -10,6 +10,9 @@ import { Mail, Calendar, BookUser, HardDrive, Settings } from 'lucide-react-nati
|
|||||||
import { startLiveUpdates, type LiveUpdatesHandle } from './src/api/push-stream';
|
import { startLiveUpdates, type LiveUpdatesHandle } from './src/api/push-stream';
|
||||||
import { jmapClient } from './src/api/jmap-client';
|
import { jmapClient } from './src/api/jmap-client';
|
||||||
import type { StateChange } from './src/api/types';
|
import type { StateChange } from './src/api/types';
|
||||||
|
import { dispatchStateChange } from './src/lib/state-change-bus';
|
||||||
|
import { useFilterStore } from './src/stores/filter-store';
|
||||||
|
import { useVacationStore } from './src/stores/vacation-store';
|
||||||
import {
|
import {
|
||||||
addMessageListener,
|
addMessageListener,
|
||||||
addNotificationTapListener,
|
addNotificationTapListener,
|
||||||
@@ -406,10 +409,19 @@ export default function App() {
|
|||||||
let appActive = AppState.currentState !== 'background' && AppState.currentState !== 'inactive';
|
let appActive = AppState.currentState !== 'background' && AppState.currentState !== 'inactive';
|
||||||
|
|
||||||
const onStateChange = async (change: StateChange) => {
|
const onStateChange = async (change: StateChange) => {
|
||||||
|
// Filters / vacation edited elsewhere (webmail, another device): refetch
|
||||||
|
// so the settings panes don't save stale state over the newer script.
|
||||||
|
const primary = (() => { try { return jmapClient.accountId; } catch { return null; } })();
|
||||||
|
const own = primary ? change.changed?.[primary] : undefined;
|
||||||
|
const extra: Promise<unknown>[] = [];
|
||||||
|
if (own?.SieveScript) extra.push(useFilterStore.getState().fetchFilters().catch(() => undefined));
|
||||||
|
if (own?.VacationResponse) extra.push(useVacationStore.getState().fetch().catch(() => undefined));
|
||||||
|
dispatchStateChange(change);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
useEmailStore.getState().handleStateChange(change),
|
useEmailStore.getState().handleStateChange(change),
|
||||||
useContactsStore.getState().handleStateChange(change),
|
useContactsStore.getState().handleStateChange(change),
|
||||||
useCalendarStore.getState().handleStateChange(change),
|
useCalendarStore.getState().handleStateChange(change),
|
||||||
|
...extra,
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
// Fan-out of JMAP StateChange events to screens that have no store of their
|
||||||
|
// own (Scheduled list, Files). The mail/contacts/calendar stores subscribe
|
||||||
|
// directly in App.tsx; anything else listens here for the type it cares about.
|
||||||
|
|
||||||
|
import type { StateChange } from '../api/types';
|
||||||
|
|
||||||
|
type Listener = (accountId: string, state: string, change: StateChange) => void;
|
||||||
|
|
||||||
|
const listeners = new Map<string, Set<Listener>>();
|
||||||
|
|
||||||
|
/** Subscribe to changes of one JMAP type (e.g. `EmailSubmission`, `FileNode`). */
|
||||||
|
export function onStateChangeType(type: string, listener: Listener): () => void {
|
||||||
|
let set = listeners.get(type);
|
||||||
|
if (!set) {
|
||||||
|
set = new Set();
|
||||||
|
listeners.set(type, set);
|
||||||
|
}
|
||||||
|
set.add(listener);
|
||||||
|
return () => {
|
||||||
|
set?.delete(listener);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dispatchStateChange(change: StateChange): void {
|
||||||
|
for (const [accountId, types] of Object.entries(change.changed ?? {})) {
|
||||||
|
for (const [type, state] of Object.entries(types ?? {})) {
|
||||||
|
const set = listeners.get(type);
|
||||||
|
if (!set) continue;
|
||||||
|
for (const l of set) {
|
||||||
|
try {
|
||||||
|
l(accountId, state, change);
|
||||||
|
} catch {
|
||||||
|
// a broken listener must not break the others
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user