44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
import { useCallback } from 'react';
|
|||
|
|
import { useMatrixClient } from './useMatrixClient';
|
||
|
|
import { createAccountDataListStore } from './createAccountDataListStore';
|
||
|
|
import { StatusPreset, upsertPreset } from '../utils/statusPresets';
|
||
|
|
|
||
|
|
const STATUS_PRESETS_KEY = 'io.lotus.status_presets';
|
||
|
|
const MAX_PRESETS = 20;
|
||
|
|
|
||
|
|
type StatusPresetsContent = {
|
||
|
|
presets: StatusPreset[];
|
||
|
|
};
|
||
|
|
|
||
|
|
// 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 statusPresetsStore = createAccountDataListStore<StatusPreset[], StatusPresetsContent>({
|
||
|
|
eventType: STATUS_PRESETS_KEY,
|
||
|
|
read: (content) => content?.presets ?? [],
|
||
|
|
write: (presets) => ({ presets }),
|
||
|
|
});
|
||
|
|
|
||
|
|
export function useStatusPresets(): {
|
||
|
|
presets: StatusPreset[];
|
||
|
|
addPreset: (preset: StatusPreset) => Promise<void>;
|
||
|
|
removePreset: (id: string) => Promise<void>;
|
||
|
|
} {
|
||
|
|
const mx = useMatrixClient();
|
||
|
|
const presets = statusPresetsStore.useValue(mx);
|
||
|
|
|
||
|
|
const addPreset = useCallback(
|
||
|
|
(preset: StatusPreset) =>
|
||
|
|
statusPresetsStore.enqueueWrite(mx, (current) => upsertPreset(current, preset, MAX_PRESETS)),
|
||
|
|
[mx],
|
||
|
|
);
|
||
|
|
|
||
|
|
const removePreset = useCallback(
|
||
|
|
(id: string) =>
|
||
|
|
statusPresetsStore.enqueueWrite(mx, (current) => current.filter((p) => p.id !== id)),
|
||
|
|
[mx],
|
||
|
|
);
|
||
|
|
|
||
|
|
return { presets, addPreset, removePreset };
|
||
|
|
}
|