ohctechv3/.svn/pristine/68/6892e725e07db88c6ecab01ed1f237a1ef246e7e.svn-base
2024-10-28 15:03:36 +05:30

147 lines
3.6 KiB
Plaintext

import { useRef, useState, useEffect } from 'react';
import { toast } from 'react-toastify';
function useNotificationCenter(params) {
if (params === void 0) {
params = {};
}
const sortFn = useRef(params.sort || defaultSort);
const filterFn = useRef(params.filter || null);
const [notifications, setNotifications] = useState(() => {
if (params.data) {
return filterFn.current ? params.data.filter(filterFn.current).sort(sortFn.current) : [...params.data].sort(sortFn.current);
}
return [];
});
useEffect(() => {
return toast.onChange(item => {
if (item.status === 'added' || item.status === 'updated') {
const newItem = decorate(item);
if (filterFn.current && !filterFn.current(newItem)) return;
setNotifications(prev => {
let nextState = [];
const updateIdx = prev.findIndex(v => v.id === newItem.id);
if (updateIdx !== -1) {
nextState = prev.slice();
Object.assign(nextState[updateIdx], newItem, {
createdAt: Date.now()
});
} else if (prev.length === 0) {
nextState = [newItem];
} else {
nextState = [newItem, ...prev];
}
return nextState.sort(sortFn.current);
});
}
});
}, []);
const remove = id => {
setNotifications(prev => prev.filter(Array.isArray(id) ? v => !id.includes(v.id) : v => v.id !== id));
};
const clear = () => {
setNotifications([]);
};
const markAllAsRead = function (read) {
if (read === void 0) {
read = true;
}
setNotifications(prev => prev.map(v => {
v.read = read;
return v;
}));
};
const markAsRead = function (id, read) {
if (read === void 0) {
read = true;
}
let map = v => {
if (v.id === id) v.read = read;
return v;
};
if (Array.isArray(id)) {
map = v => {
if (id.includes(v.id)) v.read = read;
return v;
};
}
setNotifications(prev => prev.map(map));
};
const find = id => {
return Array.isArray(id) ? notifications.filter(v => id.includes(v.id)) : notifications.find(v => v.id === id);
};
const add = item => {
if (notifications.find(v => v.id === item.id)) return null;
const newItem = decorate(item);
setNotifications(prev => [...prev, newItem].sort(sortFn.current));
return newItem.id;
};
const update = (id, item) => {
const index = notifications.findIndex(v => v.id === id);
if (index !== -1) {
setNotifications(prev => {
const nextState = [...prev];
Object.assign(nextState[index], item, {
createdAt: item.createdAt || Date.now()
});
return nextState.sort(sortFn.current);
});
return item.id;
}
return null;
};
const sort = compareFn => {
sortFn.current = compareFn;
setNotifications(prev => prev.slice().sort(compareFn));
};
return {
notifications,
clear,
markAllAsRead,
markAsRead,
add,
update,
remove,
// @ts-ignore fixme: overloading issue
find,
sort,
get unreadCount() {
return notifications.reduce((prev, cur) => !cur.read ? prev + 1 : prev, 0);
}
};
}
function decorate(item) {
if (item.id == null) item.id = Date.now().toString(36).substring(2, 9);
if (!item.createdAt) item.createdAt = Date.now();
if (item.read == null) item.read = false;
return item;
} // newest to oldest
function defaultSort(l, r) {
return r.createdAt - l.createdAt;
}
export { decorate, useNotificationCenter };
//# sourceMappingURL=index.esm.mjs.map