mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-22 16:57:00 +08:00
68 lines
2.0 KiB
TypeScript
68 lines
2.0 KiB
TypeScript
import { atom } from 'jotai';
|
|
import { nanoid } from 'nanoid';
|
|
|
|
export type Notification = {
|
|
key?: string;
|
|
title: string;
|
|
message?: string;
|
|
type: 'success' | 'error' | 'warning' | 'info';
|
|
theme?: 'light' | 'dark' | 'default';
|
|
timeout?: number;
|
|
progressingBar?: boolean;
|
|
multimedia?: React.ReactNode | JSX.Element | HTMLElement;
|
|
// actions
|
|
undo?: () => Promise<void>;
|
|
};
|
|
|
|
const notificationsBaseAtom = atom<Notification[]>([]);
|
|
|
|
const expandNotificationCenterBaseAtom = atom(false);
|
|
const cleanupQueueAtom = atom<(() => unknown)[]>([]);
|
|
export const expandNotificationCenterAtom = atom<boolean, [boolean], void>(
|
|
get => get(expandNotificationCenterBaseAtom),
|
|
(get, set, value) => {
|
|
if (value === false) {
|
|
get(cleanupQueueAtom).forEach(cleanup => cleanup());
|
|
set(cleanupQueueAtom, []);
|
|
}
|
|
set(expandNotificationCenterBaseAtom, value);
|
|
}
|
|
);
|
|
|
|
export const notificationsAtom = atom<Notification[]>(get =>
|
|
get(notificationsBaseAtom)
|
|
);
|
|
|
|
export const removeNotificationAtom = atom(null, (_, set, key: string) => {
|
|
set(notificationsBaseAtom, notifications =>
|
|
notifications.filter(notification => notification.key !== key)
|
|
);
|
|
});
|
|
|
|
export const pushNotificationAtom = atom<null, [Notification], void>(
|
|
null,
|
|
(_, set, newNotification) => {
|
|
newNotification.key = newNotification.key || nanoid();
|
|
const key = newNotification.key;
|
|
const removeNotification = () =>
|
|
set(notificationsBaseAtom, notifications =>
|
|
notifications.filter(notification => notification.key !== key)
|
|
);
|
|
const undo: (() => Promise<void>) | undefined = newNotification.undo
|
|
? (() => {
|
|
const undo: () => Promise<void> = newNotification.undo;
|
|
return async function undoNotificationWrapper() {
|
|
removeNotification();
|
|
return undo();
|
|
};
|
|
})()
|
|
: undefined;
|
|
|
|
set(notificationsBaseAtom, notifications => [
|
|
// push to the top
|
|
{ ...newNotification, undo },
|
|
...notifications,
|
|
]);
|
|
}
|
|
);
|