diff --git a/lib/reducers/calendar-filters-reducer.js b/lib/reducers/calendar-filters-reducer.js --- a/lib/reducers/calendar-filters-reducer.js +++ b/lib/reducers/calendar-filters-reducer.js @@ -23,6 +23,7 @@ nonExcludeDeletedCalendarFilters, } from '../selectors/calendar-filter-selectors.js'; import { threadInFilterList } from '../shared/thread-utils.js'; +import { updateSpecs } from '../shared/updates/update-specs.js'; import { type CalendarFilter, defaultCalendarFilters, @@ -37,7 +38,6 @@ incrementalStateSyncActionType, } from '../types/socket-types.js'; import type { RawThreadInfo, ThreadStore } from '../types/thread-types.js'; -import { updateTypes } from '../types/update-types-enum.js'; import { type ClientUpdateInfo, processUpdatesActionType, @@ -138,36 +138,19 @@ if (!currentlyFilteredIDs) { return state; } - let changeOccurred = false; - for (const update of updateInfos) { - if (update.type === updateTypes.DELETE_THREAD) { - const result = currentlyFilteredIDs.delete(update.threadID); - if (result) { - changeOccurred = true; - } - } else if (update.type === updateTypes.JOIN_THREAD) { - if ( - !threadInFilterList(update.threadInfo) || - currentlyFilteredIDs.has(update.threadInfo.id) - ) { - continue; - } - currentlyFilteredIDs.add(update.threadInfo.id); - changeOccurred = true; - } else if (update.type === updateTypes.UPDATE_THREAD) { - if (threadInFilterList(update.threadInfo)) { - continue; - } - const result = currentlyFilteredIDs.delete(update.threadInfo.id); - if (result) { - changeOccurred = true; - } - } - } - if (changeOccurred) { + const newFilteredThreadIDs = updateInfos.reduce( + (reducedFilteredThreadIDs, update) => { + const { reduceCalendarThreadFilters } = updateSpecs[update.type]; + return reduceCalendarThreadFilters + ? reduceCalendarThreadFilters(reducedFilteredThreadIDs, update) + : reducedFilteredThreadIDs; + }, + currentlyFilteredIDs, + ); + if (currentlyFilteredIDs !== newFilteredThreadIDs) { return [ ...nonThreadCalendarFilters(state), - { type: 'threads', threadIDs: [...currentlyFilteredIDs] }, + { type: 'threads', threadIDs: [...newFilteredThreadIDs] }, ]; } return state; diff --git a/lib/shared/updates/delete-thread-spec.js b/lib/shared/updates/delete-thread-spec.js --- a/lib/shared/updates/delete-thread-spec.js +++ b/lib/shared/updates/delete-thread-spec.js @@ -22,4 +22,15 @@ } return null; }, + reduceCalendarThreadFilters( + filteredThreadIDs: $ReadOnlySet, + update: ThreadDeletionUpdateInfo, + ) { + if (!filteredThreadIDs.has(update.threadID)) { + return filteredThreadIDs; + } + return new Set( + [...filteredThreadIDs].filter(id => id !== update.threadID), + ); + }, }); diff --git a/lib/shared/updates/join-thread-spec.js b/lib/shared/updates/join-thread-spec.js --- a/lib/shared/updates/join-thread-spec.js +++ b/lib/shared/updates/join-thread-spec.js @@ -6,6 +6,7 @@ import type { RawEntryInfo } from '../../types/entry-types.js'; import type { RawThreadInfos } from '../../types/thread-types.js'; import type { ThreadJoinUpdateInfo } from '../../types/update-types.js'; +import { threadInFilterList } from '../thread-utils.js'; export const joinThreadSpec: UpdateSpec = Object.freeze({ generateOpsForThreadUpdates( @@ -39,4 +40,16 @@ entryIDs.add(entryID); } }, + reduceCalendarThreadFilters( + filteredThreadIDs: $ReadOnlySet, + update: ThreadJoinUpdateInfo, + ) { + if ( + !threadInFilterList(update.threadInfo) || + filteredThreadIDs.has(update.threadInfo.id) + ) { + return filteredThreadIDs; + } + return new Set([...filteredThreadIDs, update.threadInfo.id]); + }, }); diff --git a/lib/shared/updates/update-spec.js b/lib/shared/updates/update-spec.js --- a/lib/shared/updates/update-spec.js +++ b/lib/shared/updates/update-spec.js @@ -21,4 +21,8 @@ update: UpdateInfo, ) => ?CurrentUserInfo, +reduceUserInfos?: (state: UserInfos, update: UpdateInfo) => UserInfos, + +reduceCalendarThreadFilters?: ( + filteredThreadIDs: $ReadOnlySet, + update: UpdateInfo, + ) => $ReadOnlySet, }; diff --git a/lib/shared/updates/update-thread-spec.js b/lib/shared/updates/update-thread-spec.js --- a/lib/shared/updates/update-thread-spec.js +++ b/lib/shared/updates/update-thread-spec.js @@ -5,6 +5,7 @@ import type { UpdateSpec } from './update-spec.js'; import type { RawThreadInfos } from '../../types/thread-types.js'; import type { ThreadUpdateInfo } from '../../types/update-types.js'; +import { threadInFilterList } from '../thread-utils.js'; export const updateThreadSpec: UpdateSpec = Object.freeze({ generateOpsForThreadUpdates( @@ -24,4 +25,18 @@ }, ]; }, + reduceCalendarThreadFilters( + filteredThreadIDs: $ReadOnlySet, + update: ThreadUpdateInfo, + ) { + if ( + threadInFilterList(update.threadInfo) || + !filteredThreadIDs.has(update.threadInfo.id) + ) { + return filteredThreadIDs; + } + return new Set( + [...filteredThreadIDs].filter(id => id !== update.threadInfo.id), + ); + }, });