98 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
import { createSelector } from '@reduxjs/toolkit';
 | 
						|
 | 
						|
import { compareId } from 'flavours/glitch/compare_id';
 | 
						|
import type { NotificationGroup } from 'flavours/glitch/models/notification_group';
 | 
						|
import type { NotificationGap } from 'flavours/glitch/reducers/notification_groups';
 | 
						|
import type { RootState } from 'flavours/glitch/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,
 | 
						|
    selectNotificationGroups,
 | 
						|
    selectPendingNotificationGroups,
 | 
						|
  ],
 | 
						|
  (notificationMarker, groups, pendingGroups) => {
 | 
						|
    return (
 | 
						|
      groups.filter(
 | 
						|
        (group) =>
 | 
						|
          group.type !== 'gap' &&
 | 
						|
          group.page_max_id &&
 | 
						|
          compareId(group.page_max_id, notificationMarker) > 0,
 | 
						|
      ).length +
 | 
						|
      pendingGroups.filter(
 | 
						|
        (group) =>
 | 
						|
          group.type !== 'gap' &&
 | 
						|
          group.page_max_id &&
 | 
						|
          compareId(group.page_max_id, notificationMarker) > 0,
 | 
						|
      ).length
 | 
						|
    );
 | 
						|
  },
 | 
						|
);
 | 
						|
 | 
						|
// Whether there is any unread notification according to the user-facing state
 | 
						|
export const selectAnyPendingNotification = createSelector(
 | 
						|
  [
 | 
						|
    (s: RootState) => s.notificationGroups.readMarkerId,
 | 
						|
    selectNotificationGroups,
 | 
						|
  ],
 | 
						|
  (notificationMarker, groups) => {
 | 
						|
    return groups.some(
 | 
						|
      (group) =>
 | 
						|
        group.type !== 'gap' &&
 | 
						|
        group.page_max_id &&
 | 
						|
        compareId(group.page_max_id, notificationMarker) > 0,
 | 
						|
    );
 | 
						|
  },
 | 
						|
);
 | 
						|
 | 
						|
export const selectPendingNotificationGroupsCount = createSelector(
 | 
						|
  [selectPendingNotificationGroups],
 | 
						|
  (pendingGroups) =>
 | 
						|
    pendingGroups.filter((group) => group.type !== 'gap').length,
 | 
						|
);
 |