Change unread notification count to only cover the selected notification type (#31326)
This commit is contained in:
		@@ -4,8 +4,6 @@ import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
import { Helmet } from 'react-helmet';
 | 
			
		||||
 | 
			
		||||
import { createSelector } from '@reduxjs/toolkit';
 | 
			
		||||
 | 
			
		||||
import { useDebouncedCallback } from 'use-debounce';
 | 
			
		||||
 | 
			
		||||
import DoneAllIcon from '@/material-icons/400-24px/done_all.svg?react';
 | 
			
		||||
@@ -27,16 +25,13 @@ import {
 | 
			
		||||
  selectUnreadNotificationGroupsCount,
 | 
			
		||||
  selectPendingNotificationGroupsCount,
 | 
			
		||||
  selectAnyPendingNotification,
 | 
			
		||||
  selectNotificationGroups,
 | 
			
		||||
} from 'mastodon/selectors/notifications';
 | 
			
		||||
import {
 | 
			
		||||
  selectNeedsNotificationPermission,
 | 
			
		||||
  selectSettingsNotificationsExcludedTypes,
 | 
			
		||||
  selectSettingsNotificationsQuickFilterActive,
 | 
			
		||||
  selectSettingsNotificationsQuickFilterShow,
 | 
			
		||||
  selectSettingsNotificationsShowUnread,
 | 
			
		||||
} from 'mastodon/selectors/settings';
 | 
			
		||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
 | 
			
		||||
import type { RootState } from 'mastodon/store';
 | 
			
		||||
 | 
			
		||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
 | 
			
		||||
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<{
 | 
			
		||||
  columnId?: string;
 | 
			
		||||
  multiColumn?: boolean;
 | 
			
		||||
}> = ({ columnId, multiColumn }) => {
 | 
			
		||||
  const intl = useIntl();
 | 
			
		||||
  const notifications = useAppSelector(getNotifications);
 | 
			
		||||
  const notifications = useAppSelector(selectNotificationGroups);
 | 
			
		||||
  const dispatch = useAppDispatch();
 | 
			
		||||
  const isLoading = useAppSelector((s) => s.notificationGroups.isLoading);
 | 
			
		||||
  const hasMore = notifications.at(-1)?.type === 'gap';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,62 @@
 | 
			
		||||
import { createSelector } from '@reduxjs/toolkit';
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
  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(
 | 
			
		||||
  [
 | 
			
		||||
    (s: RootState) => s.notificationGroups.lastReadId,
 | 
			
		||||
    (s: RootState) => s.notificationGroups.pendingGroups,
 | 
			
		||||
    (s: RootState) => s.notificationGroups.groups,
 | 
			
		||||
    selectNotificationGroups,
 | 
			
		||||
    selectPendingNotificationGroups,
 | 
			
		||||
  ],
 | 
			
		||||
  (notificationMarker, pendingGroups, groups) => {
 | 
			
		||||
  (notificationMarker, groups, pendingGroups) => {
 | 
			
		||||
    return (
 | 
			
		||||
      groups.filter(
 | 
			
		||||
        (group) =>
 | 
			
		||||
@@ -31,7 +78,7 @@ export const selectUnreadNotificationGroupsCount = createSelector(
 | 
			
		||||
export const selectAnyPendingNotification = createSelector(
 | 
			
		||||
  [
 | 
			
		||||
    (s: RootState) => s.notificationGroups.readMarkerId,
 | 
			
		||||
    (s: RootState) => s.notificationGroups.groups,
 | 
			
		||||
    selectNotificationGroups,
 | 
			
		||||
  ],
 | 
			
		||||
  (notificationMarker, groups) => {
 | 
			
		||||
    return groups.some(
 | 
			
		||||
@@ -44,7 +91,7 @@ export const selectAnyPendingNotification = createSelector(
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const selectPendingNotificationGroupsCount = createSelector(
 | 
			
		||||
  [(s: RootState) => s.notificationGroups.pendingGroups],
 | 
			
		||||
  [selectPendingNotificationGroups],
 | 
			
		||||
  (pendingGroups) =>
 | 
			
		||||
    pendingGroups.filter((group) => group.type !== 'gap').length,
 | 
			
		||||
);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user