Notifications: handle view while fetching categories
## Issue "No notifications" briefly appear when your previous filter is not "All". ## Change When splitting up the category-fetch, the render logic was not updated accordingly.
This commit is contained in:
parent
449398b88f
commit
fad3f6ed78
1 changed files with 47 additions and 45 deletions
|
@ -43,14 +43,18 @@ export default function NotificationsPage(props: Props) {
|
||||||
activeChannel,
|
activeChannel,
|
||||||
doCommentReactList,
|
doCommentReactList,
|
||||||
} = props;
|
} = props;
|
||||||
const initialFetchDone = useFetched(fetching);
|
|
||||||
const [name, setName] = usePersistedState('notifications--rule', NOTIFICATIONS.NOTIFICATION_NAME_ALL);
|
const [name, setName] = usePersistedState('notifications--rule', NOTIFICATIONS.NOTIFICATION_NAME_ALL);
|
||||||
const isFiltered = name !== NOTIFICATIONS.NOTIFICATION_NAME_ALL;
|
const isFiltered = name !== NOTIFICATIONS.NOTIFICATION_NAME_ALL;
|
||||||
const list = isFiltered ? notificationsFiltered : notifications;
|
const list = isFiltered ? notificationsFiltered : notifications;
|
||||||
|
|
||||||
|
const fetchedOnce = useFetched(fetching);
|
||||||
|
const categoriesReady = notificationCategories;
|
||||||
|
const notificationsReady = !isFiltered || fetchedOnce;
|
||||||
|
const ready = categoriesReady && notificationsReady;
|
||||||
|
|
||||||
// Fetch reacts
|
// Fetch reacts
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if ((!fetching || initialFetchDone) && activeChannel) {
|
if (ready && !fetching && activeChannel) {
|
||||||
let idsForReactionFetch = [];
|
let idsForReactionFetch = [];
|
||||||
list.map((notification) => {
|
list.map((notification) => {
|
||||||
const { notification_rule, notification_parameters } = notification;
|
const { notification_rule, notification_parameters } = notification;
|
||||||
|
@ -73,8 +77,9 @@ export default function NotificationsPage(props: Props) {
|
||||||
doCommentReactList(idsForReactionFetch);
|
doCommentReactList(idsForReactionFetch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [doCommentReactList, list, activeChannel, fetching, initialFetchDone]);
|
}, [ready, doCommentReactList, list, activeChannel, fetching]);
|
||||||
|
|
||||||
|
// Mark all as seen
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (unseenCount > 0) {
|
if (unseenCount > 0) {
|
||||||
doSeeAllNotifications();
|
doSeeAllNotifications();
|
||||||
|
@ -82,59 +87,70 @@ export default function NotificationsPage(props: Props) {
|
||||||
}, [unseenCount, doSeeAllNotifications]);
|
}, [unseenCount, doSeeAllNotifications]);
|
||||||
|
|
||||||
const stringifiedNotificationCategories = notificationCategories ? JSON.stringify(notificationCategories) : '';
|
const stringifiedNotificationCategories = notificationCategories ? JSON.stringify(notificationCategories) : '';
|
||||||
|
|
||||||
|
// Fetch filtered notifications
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (stringifiedNotificationCategories) {
|
if (stringifiedNotificationCategories) {
|
||||||
const arrayNotificationCategories = JSON.parse(stringifiedNotificationCategories);
|
const arrayNotificationCategories = JSON.parse(stringifiedNotificationCategories);
|
||||||
|
|
||||||
if (name !== NOTIFICATIONS.NOTIFICATION_NAME_ALL) {
|
if (name !== NOTIFICATIONS.NOTIFICATION_NAME_ALL) {
|
||||||
// Fetch filtered list when:
|
|
||||||
// (1) 'name' changed
|
|
||||||
// (2) new "all" notifications received (e.g. from websocket).
|
|
||||||
try {
|
try {
|
||||||
const matchingCategory = arrayNotificationCategories.find((category) => category.name === name);
|
const matchingCategory = arrayNotificationCategories.find((category) => category.name === name);
|
||||||
if (matchingCategory) {
|
if (matchingCategory) {
|
||||||
doNotificationList(matchingCategory.types);
|
doNotificationList(matchingCategory.types);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e); // eslint-disable-line no-console
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [name, notifications, stringifiedNotificationCategories]);
|
}, [name, notifications, stringifiedNotificationCategories, doNotificationList]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!notificationCategories) {
|
if (!notificationCategories) {
|
||||||
doNotificationCategories();
|
doNotificationCategories();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
const notificationListElement = (
|
return (
|
||||||
<>
|
<Page className="notification-page">
|
||||||
<BrowserNotificationBanner />
|
<BrowserNotificationBanner />
|
||||||
|
|
||||||
<div className="claim-list__header">
|
{ready && (
|
||||||
<h1 className="card__title">{__('Notifications')}</h1>
|
<div className="claim-list__header">
|
||||||
<div className="claim-list__alt-controls--wrap">
|
<h1 className="card__title">{__('Notifications')}</h1>
|
||||||
{fetching && <Spinner type="small" />}
|
<div className="claim-list__alt-controls--wrap">
|
||||||
|
{fetching && <Spinner type="small" delayed />}
|
||||||
|
|
||||||
{unreadCount > 0 && (
|
{unreadCount > 0 && (
|
||||||
<Button icon={ICONS.EYE} onClick={doReadNotifications} button="secondary" label={__('Mark all as read')} />
|
<Button
|
||||||
)}
|
icon={ICONS.EYE}
|
||||||
{notificationCategories && (
|
onClick={doReadNotifications}
|
||||||
<FormField type="select" name="filter" value={name} onChange={(e) => setName(e.target.value)}>
|
button="secondary"
|
||||||
{notificationCategories.map((category) => {
|
label={__('Mark all as read')}
|
||||||
return (
|
/>
|
||||||
<option key={category.name} value={category.name}>
|
)}
|
||||||
{__(category.name)}
|
|
||||||
</option>
|
{notificationCategories && (
|
||||||
);
|
<FormField type="select" name="filter" value={name} onChange={(e) => setName(e.target.value)}>
|
||||||
})}
|
{notificationCategories.map((category) => {
|
||||||
</FormField>
|
return (
|
||||||
)}
|
<option key={category.name} value={category.name}>
|
||||||
|
{__(category.name)}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</FormField>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
{list && list.length > 0 && !(isFiltered && fetching) ? (
|
{!ready ? (
|
||||||
|
<div className="main--empty">
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
|
) : list && list.length > 0 && !(isFiltered && fetching) ? (
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="notification_list">
|
<div className="notification_list">
|
||||||
{list.map((notification) => {
|
{list.map((notification) => {
|
||||||
|
@ -161,20 +177,6 @@ export default function NotificationsPage(props: Props) {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Page className="notification-page">
|
|
||||||
{initialFetchDone ? (
|
|
||||||
notificationListElement
|
|
||||||
) : fetching ? (
|
|
||||||
<div className="main--empty">
|
|
||||||
<Spinner delayed />
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
notificationListElement
|
|
||||||
)}
|
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue