Files
cinny/src/app/hooks/useReminders.ts
T

53 lines
1.6 KiB
TypeScript
Raw Normal View History

import { useCallback } from 'react';
import { useMatrixClient } from './useMatrixClient';
import { createAccountDataListStore } from './createAccountDataListStore';
export type Reminder = {
roomId: string;
eventId: string;
timestamp: number;
message: string;
};
const REMINDERS_KEY = 'io.lotus.reminders';
type RemindersContent = {
reminders: Reminder[];
};
// Shared, concurrency-safe store. See createAccountDataListStore for why the
// snapshot + write queue must be module-scoped (writes are serialized to avoid
// lost updates, since setAccountData replaces the whole content with no merge).
const remindersStore = createAccountDataListStore<Reminder[], RemindersContent>({
eventType: REMINDERS_KEY,
read: (content) => content?.reminders ?? [],
write: (reminders) => ({ reminders }),
});
export function useReminders(): {
reminders: Reminder[];
addReminder: (r: Reminder) => Promise<void>;
removeReminder: (eventId: string, timestamp: number) => Promise<void>;
getReminders: () => Reminder[];
} {
const mx = useMatrixClient();
const reminders = remindersStore.useValue(mx);
const addReminder = useCallback(
(r: Reminder) => remindersStore.enqueueWrite(mx, (current) => [...current, r]),
[mx],
);
const removeReminder = useCallback(
(eventId: string, timestamp: number) =>
remindersStore.enqueueWrite(mx, (current) =>
current.filter((r) => !(r.eventId === eventId && r.timestamp === timestamp)),
),
[mx],
);
const getReminders = useCallback(() => remindersStore.getLatest(mx), [mx]);
return { reminders, addReminder, removeReminder, getReminders };
}