Change unread notification count to only cover the selected notification type (#31326)

This commit is contained in:
Claire 2024-08-08 22:20:52 +02:00 committed by GitHub
parent 2095d0f2b0
commit 6ca731e9b6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 54 additions and 34 deletions

View file

@ -4,8 +4,6 @@ import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import { createSelector } from '@reduxjs/toolkit';
import { useDebouncedCallback } from 'use-debounce'; import { useDebouncedCallback } from 'use-debounce';
import DoneAllIcon from '@/material-icons/400-24px/done_all.svg?react'; import DoneAllIcon from '@/material-icons/400-24px/done_all.svg?react';
@ -27,16 +25,13 @@ import {
selectUnreadNotificationGroupsCount, selectUnreadNotificationGroupsCount,
selectPendingNotificationGroupsCount, selectPendingNotificationGroupsCount,
selectAnyPendingNotification, selectAnyPendingNotification,
selectNotificationGroups,
} from 'mastodon/selectors/notifications'; } from 'mastodon/selectors/notifications';
import { import {
selectNeedsNotificationPermission, selectNeedsNotificationPermission,
selectSettingsNotificationsExcludedTypes,
selectSettingsNotificationsQuickFilterActive,
selectSettingsNotificationsQuickFilterShow,
selectSettingsNotificationsShowUnread, selectSettingsNotificationsShowUnread,
} from 'mastodon/selectors/settings'; } from 'mastodon/selectors/settings';
import { useAppDispatch, useAppSelector } from 'mastodon/store'; import { useAppDispatch, useAppSelector } from 'mastodon/store';
import type { RootState } from 'mastodon/store';
import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
import { submitMarkers } from '../../actions/markers'; import { submitMarkers } from '../../actions/markers';
@ -62,34 +57,12 @@ const messages = defineMessages({
}, },
}); });
const getNotifications = createSelector(
[
selectSettingsNotificationsQuickFilterShow,
selectSettingsNotificationsQuickFilterActive,
selectSettingsNotificationsExcludedTypes,
(state: RootState) => state.notificationGroups.groups,
],
(showFilterBar, allowedType, excludedTypes, notifications) => {
if (!showFilterBar || allowedType === 'all') {
// used if user changed the notification settings after loading the notifications from the server
// otherwise a list of notifications will come pre-filtered from the backend
// we need to turn it off for FilterBar in order not to block ourselves from seeing a specific category
return notifications.filter(
(item) => item.type === 'gap' || !excludedTypes.includes(item.type),
);
}
return notifications.filter(
(item) => item.type === 'gap' || allowedType === item.type,
);
},
);
export const Notifications: React.FC<{ export const Notifications: React.FC<{
columnId?: string; columnId?: string;
multiColumn?: boolean; multiColumn?: boolean;
}> = ({ columnId, multiColumn }) => { }> = ({ columnId, multiColumn }) => {
const intl = useIntl(); const intl = useIntl();
const notifications = useAppSelector(getNotifications); const notifications = useAppSelector(selectNotificationGroups);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const isLoading = useAppSelector((s) => s.notificationGroups.isLoading); const isLoading = useAppSelector((s) => s.notificationGroups.isLoading);
const hasMore = notifications.at(-1)?.type === 'gap'; const hasMore = notifications.at(-1)?.type === 'gap';

View file

@ -1,15 +1,62 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { compareId } from 'mastodon/compare_id'; import { compareId } from 'mastodon/compare_id';
import type { NotificationGroup } from 'mastodon/models/notification_group';
import type { NotificationGap } from 'mastodon/reducers/notification_groups';
import type { RootState } from 'mastodon/store'; import type { RootState } from 'mastodon/store';
import {
selectSettingsNotificationsExcludedTypes,
selectSettingsNotificationsQuickFilterActive,
selectSettingsNotificationsQuickFilterShow,
} from './settings';
const filterNotificationsByAllowedTypes = (
showFilterBar: boolean,
allowedType: string,
excludedTypes: string[],
notifications: (NotificationGroup | NotificationGap)[],
) => {
if (!showFilterBar || allowedType === 'all') {
// used if user changed the notification settings after loading the notifications from the server
// otherwise a list of notifications will come pre-filtered from the backend
// we need to turn it off for FilterBar in order not to block ourselves from seeing a specific category
return notifications.filter(
(item) => item.type === 'gap' || !excludedTypes.includes(item.type),
);
}
return notifications.filter(
(item) => item.type === 'gap' || allowedType === item.type,
);
};
export const selectNotificationGroups = createSelector(
[
selectSettingsNotificationsQuickFilterShow,
selectSettingsNotificationsQuickFilterActive,
selectSettingsNotificationsExcludedTypes,
(state: RootState) => state.notificationGroups.groups,
],
filterNotificationsByAllowedTypes,
);
const selectPendingNotificationGroups = createSelector(
[
selectSettingsNotificationsQuickFilterShow,
selectSettingsNotificationsQuickFilterActive,
selectSettingsNotificationsExcludedTypes,
(state: RootState) => state.notificationGroups.pendingGroups,
],
filterNotificationsByAllowedTypes,
);
export const selectUnreadNotificationGroupsCount = createSelector( export const selectUnreadNotificationGroupsCount = createSelector(
[ [
(s: RootState) => s.notificationGroups.lastReadId, (s: RootState) => s.notificationGroups.lastReadId,
(s: RootState) => s.notificationGroups.pendingGroups, selectNotificationGroups,
(s: RootState) => s.notificationGroups.groups, selectPendingNotificationGroups,
], ],
(notificationMarker, pendingGroups, groups) => { (notificationMarker, groups, pendingGroups) => {
return ( return (
groups.filter( groups.filter(
(group) => (group) =>
@ -31,7 +78,7 @@ export const selectUnreadNotificationGroupsCount = createSelector(
export const selectAnyPendingNotification = createSelector( export const selectAnyPendingNotification = createSelector(
[ [
(s: RootState) => s.notificationGroups.readMarkerId, (s: RootState) => s.notificationGroups.readMarkerId,
(s: RootState) => s.notificationGroups.groups, selectNotificationGroups,
], ],
(notificationMarker, groups) => { (notificationMarker, groups) => {
return groups.some( return groups.some(
@ -44,7 +91,7 @@ export const selectAnyPendingNotification = createSelector(
); );
export const selectPendingNotificationGroupsCount = createSelector( export const selectPendingNotificationGroupsCount = createSelector(
[(s: RootState) => s.notificationGroups.pendingGroups], [selectPendingNotificationGroups],
(pendingGroups) => (pendingGroups) =>
pendingGroups.filter((group) => group.type !== 'gap').length, pendingGroups.filter((group) => group.type !== 'gap').length,
); );