diff --git a/lib/actions/community-actions.js b/lib/actions/community-actions.js new file mode 100644 --- /dev/null +++ b/lib/actions/community-actions.js @@ -0,0 +1,4 @@ +// @flow + +export const updateCalendarCommunityFilter = 'UPDATE_CALENDAR_COMMUNITY_FILTER'; +export const clearCalendarCommunityFilter = 'CLEAR_CALENDAR_COMMUNITY_FILTER'; 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 @@ -1,5 +1,9 @@ // @flow +import { + updateCalendarCommunityFilter, + clearCalendarCommunityFilter, +} from '../actions/community-actions.js'; import { siweAuthActionTypes } from '../actions/siwe-actions.js'; import { newThreadActionTypes, @@ -32,17 +36,19 @@ fullStateSyncActionType, incrementalStateSyncActionType, } from '../types/socket-types.js'; -import type { RawThreadInfo } from '../types/thread-types.js'; +import type { RawThreadInfo, ThreadStore } from '../types/thread-types.js'; import { updateTypes } from '../types/update-types-enum.js'; import { type ClientUpdateInfo, processUpdatesActionType, } from '../types/update-types.js'; import { setNewSessionActionType } from '../utils/action-utils.js'; +import { filterThreadIDsBelongingToCommunity } from '../utils/drawer-utils.react.js'; export default function reduceCalendarFilters( state: $ReadOnlyArray, action: BaseAction, + threadStore: ThreadStore, ): $ReadOnlyArray { if ( action.type === logOutActionTypes.success || @@ -101,6 +107,25 @@ state, action.payload.threadInfos, ); + } else if (action.type === updateCalendarCommunityFilter) { + const nonThreadFilters = nonThreadCalendarFilters(state); + + const threadIDs = Array.from( + filterThreadIDsBelongingToCommunity( + action.payload, + threadStore.threadInfos, + ), + ); + return [ + ...nonThreadFilters, + { + type: calendarThreadFilterTypes.THREAD_LIST, + threadIDs, + }, + ]; + } else if (action.type === clearCalendarCommunityFilter) { + const nonThreadFilters = nonThreadCalendarFilters(state); + return nonThreadFilters; } return state; } diff --git a/lib/reducers/master-reducer.js b/lib/reducers/master-reducer.js --- a/lib/reducers/master-reducer.js +++ b/lib/reducers/master-reducer.js @@ -98,7 +98,11 @@ messageStore, updatesCurrentAsOf, urlPrefix: reduceURLPrefix(state.urlPrefix, action), - calendarFilters: reduceCalendarFilters(state.calendarFilters, action), + calendarFilters: reduceCalendarFilters( + state.calendarFilters, + action, + threadStore, + ), notifPermissionAlertInfo: reduceNotifPermissionAlertInfo( state.notifPermissionAlertInfo, action, diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js --- a/lib/types/redux-types.js +++ b/lib/types/redux-types.js @@ -1046,6 +1046,14 @@ +error: true, +payload: Error, +loadingInfo: LoadingInfo, + } + | { + +type: 'UPDATE_CALENDAR_COMMUNITY_FILTER', + +payload: string, + } + | { + +type: 'CLEAR_CALENDAR_COMMUNITY_FILTER', + +payload: void, }; export type ActionPayload = ?(Object | Array<*> | $ReadOnlyArray<*> | string); diff --git a/lib/utils/drawer-utils.react.js b/lib/utils/drawer-utils.react.js --- a/lib/utils/drawer-utils.react.js +++ b/lib/utils/drawer-utils.react.js @@ -1,10 +1,12 @@ // @flow -import { threadIsChannel } from '../shared/thread-utils.js'; +import { values } from './objects.js'; +import { threadInFilterList, threadIsChannel } from '../shared/thread-utils.js'; import { communitySubthreads } from '../types/thread-types-enum.js'; -import { - type ThreadInfo, - type ResolvedThreadInfo, +import type { + RawThreadInfo, + ThreadInfo, + ResolvedThreadInfo, } from '../types/thread-types.js'; export type CommunityDrawerItemData = { @@ -81,4 +83,23 @@ return result; } -export { createRecursiveDrawerItemsData, appendSuffix }; +function filterThreadIDsBelongingToCommunity( + communityID: string, + threadInfosObj: { +[id: string]: ThreadInfo | RawThreadInfo }, +): $ReadOnlySet { + const threadInfos = values(threadInfosObj); + const threadIDs = threadInfos + .filter( + thread => + (thread.community === communityID || thread.id === communityID) && + threadInFilterList(thread), + ) + .map(item => item.id); + return new Set(threadIDs); +} + +export { + createRecursiveDrawerItemsData, + appendSuffix, + filterThreadIDsBelongingToCommunity, +}; diff --git a/web/redux/action-types.js b/web/redux/action-types.js --- a/web/redux/action-types.js +++ b/web/redux/action-types.js @@ -4,5 +4,3 @@ export const updateWindowDimensionsActionType = 'UPDATE_WINDOW_DIMENSIONS'; export const updateWindowActiveActionType = 'UPDATE_WINDOW_ACTIVE'; export const setDeviceIDActionType = 'SET_DEVICE_ID'; -export const updateCalendarCommunityFilter = 'UPDATE_CALENDAR_COMMUNITY_FILTER'; -export const clearCalendarCommunityFilter = 'CLEAR_CALENDAR_COMMUNITY_FILTER'; diff --git a/web/redux/community-picker-reducer.js b/web/redux/community-picker-reducer.js new file mode 100644 --- /dev/null +++ b/web/redux/community-picker-reducer.js @@ -0,0 +1,28 @@ +// @flow + +import { + updateCalendarCommunityFilter, + clearCalendarCommunityFilter, +} from 'lib/actions/community-actions.js'; +import type { ThreadStore } from 'lib/types/thread-types.js'; + +import type { Action, CommunityPickerStore } from './redux-setup'; + +export function reduceCommunityPickerStore( + communityPickerStore: CommunityPickerStore, + threadStore: ThreadStore, + action: Action, +): CommunityPickerStore { + if (action.type === updateCalendarCommunityFilter) { + return { + ...communityPickerStore, + calendar: action.payload, + }; + } else if (action.type === clearCalendarCommunityFilter) { + return { + ...communityPickerStore, + calendar: null, + }; + } + return communityPickerStore; +} diff --git a/web/redux/redux-setup.js b/web/redux/redux-setup.js --- a/web/redux/redux-setup.js +++ b/web/redux/redux-setup.js @@ -8,7 +8,6 @@ deleteAccountActionTypes, } from 'lib/actions/user-actions.js'; import baseReducer from 'lib/reducers/master-reducer.js'; -import { nonThreadCalendarFilters } from 'lib/selectors/calendar-filter-selectors.js'; import { mostRecentlyReadThreadSelector } from 'lib/selectors/thread-selectors.js'; import { isLoggedIn } from 'lib/selectors/user-selectors.js'; import { invalidSessionDowngrade } from 'lib/shared/session-utils.js'; @@ -21,10 +20,7 @@ import type { DraftStore } from 'lib/types/draft-types.js'; import type { EnabledApps } from 'lib/types/enabled-apps.js'; import type { EntryStore } from 'lib/types/entry-types.js'; -import { - type CalendarFilter, - calendarThreadFilterTypes, -} from 'lib/types/filter-types.js'; +import { type CalendarFilter } from 'lib/types/filter-types.js'; import type { LifecycleState } from 'lib/types/lifecycle-state-types.js'; import type { LoadingStatus } from 'lib/types/loading-types.js'; import type { MessageStore } from 'lib/types/message-types.js'; @@ -42,9 +38,8 @@ setDeviceIDActionType, updateNavInfoActionType, updateWindowDimensionsActionType, - updateCalendarCommunityFilter, - clearCalendarCommunityFilter, } from './action-types.js'; +import { reduceCommunityPickerStore } from './community-picker-reducer.js'; import { reduceCryptoStore, setPrimaryIdentityKeys, @@ -56,7 +51,6 @@ import reduceNavInfo from './nav-reducer.js'; import { getVisibility } from './visibility.js'; import { databaseModule } from '../database/database-module-provider.js'; -import { filterThreadIDsBelongingToCommunity } from '../selectors/calendar-selectors.js'; import { activeThreadSelector } from '../selectors/nav-selectors.js'; import { type NavInfo } from '../types/nav-types.js'; import { workerRequestMessageTypes } from '../types/worker-types.js'; @@ -121,15 +115,7 @@ | { +type: 'SET_PRIMARY_IDENTITY_KEYS', payload: ?OLMIdentityKeys } | { +type: 'SET_NOTIFICATION_IDENTITY_KEYS', payload: ?OLMIdentityKeys } | { +type: 'SET_PICKLED_PRIMARY_ACCOUNT', payload: ?PickledOLMAccount } - | { +type: 'SET_PICKLED_NOTIFICATION_ACCOUNT', payload: ?PickledOLMAccount } - | { - +type: 'UPDATE_CALENDAR_COMMUNITY_FILTER', - +payload: string, - } - | { - +type: 'CLEAR_CALENDAR_COMMUNITY_FILTER', - +payload: void, - }; + | { +type: 'SET_PICKLED_NOTIFICATION_ACCOUNT', payload: ?PickledOLMAccount }; export function reducer(oldState: AppState | void, action: Action): AppState { invariant(oldState, 'should be set'); @@ -145,39 +131,6 @@ ...state, windowActive: action.payload, }); - } else if (action.type === updateCalendarCommunityFilter) { - const nonThreadFilters = nonThreadCalendarFilters(state.calendarFilters); - - const threadIDs = Array.from( - filterThreadIDsBelongingToCommunity( - action.payload, - state.threadStore.threadInfos, - ), - ); - return { - ...state, - calendarFilters: [ - ...nonThreadFilters, - { - type: calendarThreadFilterTypes.THREAD_LIST, - threadIDs, - }, - ], - communityPickerStore: { - ...state.communityPickerStore, - calendar: action.payload, - }, - }; - } else if (action.type === clearCalendarCommunityFilter) { - const nonThreadFilters = nonThreadCalendarFilters(state.calendarFilters); - return { - ...state, - calendarFilters: nonThreadFilters, - communityPickerStore: { - ...state.communityPickerStore, - calendar: null, - }, - }; } else if (action.type === setNewSessionActionType) { if ( invalidSessionDowngrade( @@ -237,6 +190,12 @@ } } + const communityPickerStore = reduceCommunityPickerStore( + state.communityPickerStore, + state.threadStore, + action, + ); + state = { ...state, navInfo: reduceNavInfo( @@ -246,6 +205,7 @@ ), deviceID: reduceDeviceID(state.deviceID, action), cryptoStore: reduceCryptoStore(state.cryptoStore, action), + communityPickerStore, }; return validateState(oldState, state); diff --git a/web/selectors/calendar-selectors.js b/web/selectors/calendar-selectors.js --- a/web/selectors/calendar-selectors.js +++ b/web/selectors/calendar-selectors.js @@ -8,10 +8,9 @@ } from 'lib/selectors/calendar-selectors.js'; import { threadInfoSelector } from 'lib/selectors/thread-selectors.js'; import type SearchIndex from 'lib/shared/search-index.js'; -import { threadInFilterList } from 'lib/shared/thread-utils.js'; import type { FilterThreadInfo } from 'lib/types/filter-types.js'; -import type { ThreadInfo, RawThreadInfo } from 'lib/types/thread-types.js'; -import { values } from 'lib/utils/objects.js'; +import type { ThreadInfo } from 'lib/types/thread-types.js'; +import { filterThreadIDsBelongingToCommunity } from 'lib/utils/drawer-utils.react.js'; import type { AppState } from '../redux/redux-setup.js'; import { useSelector } from '../redux/redux-utils.js'; @@ -26,21 +25,6 @@ return baseUseFilterThreadSearchIndex(calendarActive); } -function filterThreadIDsBelongingToCommunity( - communityID: string, - threadInfosObj: { +[id: string]: ThreadInfo | RawThreadInfo }, -): $ReadOnlySet { - const threadInfos = values(threadInfosObj); - const threadIDs = threadInfos - .filter( - thread => - (thread.community === communityID || thread.id === communityID) && - threadInFilterList(thread), - ) - .map(item => item.id); - return new Set(threadIDs); -} - const filterThreadIDsBelongingToCommunitySelector: ( state: AppState, ) => ?$ReadOnlySet = createSelector( diff --git a/web/sidebar/community-drawer-item-handlers.react.js b/web/sidebar/community-drawer-item-handlers.react.js --- a/web/sidebar/community-drawer-item-handlers.react.js +++ b/web/sidebar/community-drawer-item-handlers.react.js @@ -3,10 +3,10 @@ import * as React from 'react'; import { useDispatch } from 'react-redux'; +import { updateCalendarCommunityFilter } from 'lib/actions/community-actions.js'; import type { ThreadInfo } from 'lib/types/thread-types.js'; import type { CommunityDrawerItemHandler } from './community-drawer-item-handler.react.js'; -import { updateCalendarCommunityFilter } from '../redux/action-types.js'; import { useCommunityIsPickedCalendar } from '../selectors/calendar-selectors.js'; import { useOnClickThread, diff --git a/web/sidebar/community-picker.react.js b/web/sidebar/community-picker.react.js --- a/web/sidebar/community-picker.react.js +++ b/web/sidebar/community-picker.react.js @@ -4,16 +4,14 @@ import * as React from 'react'; import { useDispatch } from 'react-redux'; +import { clearCalendarCommunityFilter } from 'lib/actions/community-actions.js'; import { useModalContext } from 'lib/components/modal-provider.react.js'; import SWMansionIcon from 'lib/components/SWMansionIcon.react.js'; import CommunityCreationModal from './community-creation/community-creation-modal.react.js'; import CommunityDrawer from './community-drawer.react.js'; import css from './community-picker.css'; -import { - clearCalendarCommunityFilter, - updateNavInfoActionType, -} from '../redux/action-types.js'; +import { updateNavInfoActionType } from '../redux/action-types.js'; import { useSelector } from '../redux/redux-utils.js'; function CommunityPicker(): React.Node {