1 |
- {"version":3,"file":"index.js","sources":["../../../src/addons/use-notification-center/useNotificationCenter.ts"],"sourcesContent":["import { useState, useEffect, useRef } from 'react';\nimport { toast, ToastItem, Id } from 'react-toastify';\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;\n\nexport interface NotificationCenterItem<Data = {}>\n extends Optional<ToastItem<Data>, 'content' | 'data'> {\n read: boolean;\n createdAt: number;\n}\n\nexport type SortFn<Data> = (\n l: NotificationCenterItem<Data>,\n r: NotificationCenterItem<Data>\n) => number;\n\nexport type FilterFn<Data = {}> = (\n item: NotificationCenterItem<Data>\n) => boolean;\n\nexport interface UseNotificationCenterParams<Data = {}> {\n /**\n * initial data to rehydrate the notification center\n */\n data?: NotificationCenterItem<Data>[];\n\n /**\n * By default, the notifications are sorted from the newest to the oldest using\n * the `createdAt` field. Use this to provide your own sort function\n *\n * Usage:\n * ```\n * // old notifications first\n * useNotificationCenter({\n * sort: ((l, r) => l.createdAt - r.createdAt)\n * })\n * ```\n */\n sort?: SortFn<Data>;\n\n /**\n * Keep the toast that meets the condition specified in the callback function.\n *\n * Usage:\n * ```\n * // keep only the toasts when hidden is set to false\n * useNotificationCenter({\n * filter: item => item.data.hidden === false\n * })\n * ```\n */\n filter?: FilterFn<Data>;\n}\n\nexport interface UseNotificationCenter<Data> {\n /**\n * Contains all the notifications\n */\n notifications: NotificationCenterItem<Data>[];\n\n /**\n * Clear all notifications\n */\n clear(): void;\n\n /**\n * Mark all notification as read\n */\n markAllAsRead(): void;\n\n /**\n * Mark all notification as read or not.\n *\n * Usage:\n * ```\n * markAllAsRead(false) // mark all notification as not read\n *\n * markAllAsRead(true) // same as calling markAllAsRead()\n * ```\n */\n markAllAsRead(read?: boolean): void;\n\n /**\n * Mark one or more notifications as read.\n *\n * Usage:\n * ```\n * markAsRead(\"anId\")\n * markAsRead([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n markAsRead(id: Id | Id[]): void;\n\n /**\n * Mark one or more notifications as read.The second parameter let you mark the notificaiton as read or not.\n *\n * Usage:\n * ```\n * markAsRead(\"anId\", false)\n * markAsRead([\"a\",\"list\", \"of\", \"id\"], false)\n *\n * markAsRead(\"anId\", true) // same as markAsRead(\"anId\")\n * ```\n */\n markAsRead(id: Id | Id[], read?: boolean): void;\n\n /**\n * Remove one or more notifications\n *\n * Usage:\n * ```\n * remove(\"anId\")\n * remove([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n remove(id: Id | Id[]): void;\n\n /**\n * Push a notification to the notification center.\n * Returns null when an item with the given id already exists\n *\n * Usage:\n * ```\n * const id = add({id: \"id\", content: \"test\", data: { foo: \"hello\" } })\n *\n * // Return the id of the notificaiton, generate one if none provided\n * const id = add({ data: {title: \"a title\", text: \"some text\"} })\n * ```\n */\n add(item: Partial<NotificationCenterItem<Data>>): Id | null;\n\n /**\n * Update the notification that match the id\n * Returns null when no matching notification found\n *\n * Usage:\n * ```\n * const id = update(\"anId\", {content: \"test\", data: { foo: \"hello\" } })\n *\n * // It's also possible to update the id\n * const id = update(\"anId\"m { id:\"anotherOne\", data: {title: \"a title\", text: \"some text\"} })\n * ```\n */\n update(id: Id, item: Partial<NotificationCenterItem<Data>>): Id | null;\n\n /**\n * Retrive one or more notifications\n *\n * Usage:\n * ```\n * find(\"anId\")\n * find([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n find(id: Id): NotificationCenterItem<Data> | undefined;\n\n /**\n * Retrive one or more notifications\n *\n * Usage:\n * ```\n * find(\"anId\")\n * find([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n find(id: Id[]): NotificationCenterItem<Data>[] | undefined;\n\n /**\n * Retrieve the count for unread notifications\n */\n unreadCount: number;\n\n /**\n * Sort notifications using the newly provided function\n *\n * Usage:\n * ```\n * // old notifications first\n * sort((l, r) => l.createdAt - r.createdAt)\n * ```\n */\n sort(sort: SortFn<Data>): void;\n}\n\nexport function useNotificationCenter<Data = {}>(\n params: UseNotificationCenterParams<Data> = {}\n): UseNotificationCenter<Data> {\n const sortFn = useRef(params.sort || defaultSort);\n const filterFn = useRef(params.filter || null);\n const [notifications, setNotifications] = useState<\n NotificationCenterItem<Data>[]\n >(() => {\n if (params.data) {\n return filterFn.current\n ? params.data.filter(filterFn.current).sort(sortFn.current)\n : [...params.data].sort(sortFn.current);\n }\n return [];\n });\n // used to method to be used inside effect without having stale `notifications`\n const notificationsRef = useRef(notifications);\n\n useEffect(() => {\n notificationsRef.current = notifications;\n }, [notifications]);\n\n useEffect(() => {\n return toast.onChange(toast => {\n if (toast.status === 'added' || toast.status === 'updated') {\n const newItem = decorate(toast as NotificationCenterItem<Data>);\n if (filterFn.current && !filterFn.current(newItem)) return;\n\n setNotifications(prev => {\n let nextState: NotificationCenterItem<Data>[] = [];\n const updateIdx = prev.findIndex(v => v.id === newItem.id);\n\n if (updateIdx !== -1) {\n nextState = prev.slice();\n Object.assign(nextState[updateIdx], newItem, {\n createdAt: Date.now()\n });\n } else if (prev.length === 0) {\n nextState = [newItem];\n } else {\n nextState = [newItem, ...prev];\n }\n return nextState.sort(sortFn.current);\n });\n }\n });\n }, []);\n\n const remove = (id: Id | Id[]) => {\n setNotifications(prev =>\n prev.filter(\n Array.isArray(id) ? v => !id.includes(v.id) : v => v.id !== id\n )\n );\n };\n\n const clear = () => {\n setNotifications([]);\n };\n\n const markAllAsRead = (read = true) => {\n setNotifications(prev =>\n prev.map(v => {\n v.read = read;\n return v;\n })\n );\n };\n\n const markAsRead = (id: Id | Id[], read = true) => {\n let map = (v: NotificationCenterItem<Data>) => {\n if (v.id === id) v.read = read;\n return v;\n };\n\n if (Array.isArray(id)) {\n map = v => {\n if (id.includes(v.id)) v.read = read;\n return v;\n };\n }\n\n setNotifications(prev => prev.map(map));\n };\n\n const find = (id: Id | Id[]) => {\n return Array.isArray(id)\n ? notificationsRef.current.filter(v => id.includes(v.id))\n : notificationsRef.current.find(v => v.id === id);\n };\n\n const add = (item: Partial<NotificationCenterItem<Data>>) => {\n if (notificationsRef.current.find(v => v.id === item.id)) return null;\n\n const newItem = decorate(item);\n\n setNotifications(prev => [...prev, newItem].sort(sortFn.current));\n\n return newItem.id;\n };\n\n const update = (id: Id, item: Partial<NotificationCenterItem<Data>>) => {\n const index = notificationsRef.current.findIndex(v => v.id === id);\n\n if (index !== -1) {\n setNotifications(prev => {\n const nextState = [...prev];\n Object.assign(nextState[index], item, {\n createdAt: item.createdAt || Date.now()\n });\n\n return nextState.sort(sortFn.current);\n });\n\n return item.id as Id;\n }\n\n return null;\n };\n\n const sort = (compareFn: SortFn<Data>) => {\n sortFn.current = compareFn;\n setNotifications(prev => prev.slice().sort(compareFn));\n };\n\n return {\n notifications,\n clear,\n markAllAsRead,\n markAsRead,\n add,\n update,\n remove,\n // @ts-ignore fixme: overloading issue\n find,\n sort,\n get unreadCount() {\n return notifications.reduce(\n (prev, cur) => (!cur.read ? prev + 1 : prev),\n 0\n );\n }\n };\n}\n\nfunction decorate<Data>(\n item: NotificationCenterItem<Data> | Partial<NotificationCenterItem<Data>>\n) {\n if (item.id == null) item.id = Date.now().toString(36).substring(2, 9);\n if (!item.createdAt) item.createdAt = Date.now();\n if (item.read == null) item.read = false;\n return item as NotificationCenterItem<Data>;\n}\n\n// newest to oldest\nfunction defaultSort<Data>(\n l: NotificationCenterItem<Data>,\n r: NotificationCenterItem<Data>\n) {\n return r.createdAt - l.createdAt;\n}\n"],"names":["useNotificationCenter","params","sortFn","useRef","sort","defaultSort","filterFn","filter","notifications","setNotifications","useState","data","current","notificationsRef","useEffect","toast","onChange","status","newItem","decorate","prev","nextState","updateIdx","findIndex","v","id","slice","Object","assign","createdAt","Date","now","length","remove","Array","isArray","includes","clear","markAllAsRead","read","map","markAsRead","find","add","item","update","index","compareFn","unreadCount","reduce","cur","toString","substring","l","r"],"mappings":"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"}
|