diff --git a/lib/selectors/chat-selectors.js b/lib/selectors/chat-selectors.js --- a/lib/selectors/chat-selectors.js +++ b/lib/selectors/chat-selectors.js @@ -569,7 +569,7 @@ const baseMessageListData = ( threadID: ?string, additionalMessages: $ReadOnlyArray, -) => +): ((state: BaseAppState<>) => ?(ChatMessageItem[])) => createSelector( (state: BaseAppState<>) => state.messageStore, messageInfoSelector, @@ -618,7 +618,11 @@ const messageInfos = useSelector(messageInfoSelector); const containingThread = useSelector(state => { - if (!threadInfo || threadInfo.type !== threadTypes.SIDEBAR) { + if ( + !threadInfo || + threadInfo.type !== threadTypes.SIDEBAR || + !threadInfo.containingThreadID + ) { return null; } return state.messageStore.threads[threadInfo.containingThreadID]; diff --git a/lib/selectors/socket-selectors.js b/lib/selectors/socket-selectors.js --- a/lib/selectors/socket-selectors.js +++ b/lib/selectors/socket-selectors.js @@ -37,13 +37,14 @@ // We pass all selectors specified in stateSyncSpecs and get the resulting // BoundStateSyncSpecs in the specs array. We do it so we don't have to // modify the selector when we add a new spec. +type BoundStateSyncSpecs = { + +specsPerHashKey: { +[string]: BoundStateSyncSpec }, + +specPerInnerHashKey: { +[string]: BoundStateSyncSpec }, +}; const stateSyncSpecSelectors = values(stateSyncSpecs).map( spec => spec.selector, ); -const boundStateSyncSpecsSelector: AppState => { - specsPerHashKey: { +[string]: BoundStateSyncSpec }, - specPerInnerHashKey: { +[string]: BoundStateSyncSpec }, -} = +const boundStateSyncSpecsSelector: AppState => BoundStateSyncSpecs = // The FlowFixMe is needed because createSelector types require flow // to know the number of subselectors at compile time. // $FlowFixMe @@ -76,7 +77,7 @@ boundStateSyncSpecsSelector, currentCalendarQuery, ( - { specsPerHashKey, specPerInnerHashKey }, + boundStateSyncSpecs: BoundStateSyncSpecs, calendarQuery: (calendarActive: boolean) => CalendarQuery, ) => { return async ( @@ -90,6 +91,7 @@ const serverRequestedPlatformDetails = serverRequests.some( request => request.type === serverRequestTypes.PLATFORM_DETAILS, ); + const { specsPerHashKey, specPerInnerHashKey } = boundStateSyncSpecs; for (const serverRequest of serverRequests) { if ( serverRequest.type === serverRequestTypes.PLATFORM && diff --git a/lib/selectors/thread-selectors.js b/lib/selectors/thread-selectors.js --- a/lib/selectors/thread-selectors.js +++ b/lib/selectors/thread-selectors.js @@ -36,7 +36,7 @@ threadIsPending, getPendingThreadID, } from '../shared/thread-utils.js'; -import type { ClientEmojiAvatar } from '../types/avatar-types'; +import type { ClientAvatar, ClientEmojiAvatar } from '../types/avatar-types'; import type { EntryInfo } from '../types/entry-types.js'; import type { MessageStore, RawMessageInfo } from '../types/message-types.js'; import type { BaseAppState } from '../types/redux-types.js'; @@ -109,7 +109,7 @@ ( inputThreadIDs: ?$ReadOnlySet, threadInfos: $ReadOnlyArray, - ) => { + ): $ReadOnlyArray => { const threadIDs = inputThreadIDs; if (!threadIDs) { return threadInfos; @@ -122,7 +122,7 @@ state: BaseAppState<>, ) => $ReadOnlyArray = createSelector( onScreenThreadInfos, - (threadInfos: $ReadOnlyArray) => + (threadInfos: $ReadOnlyArray): $ReadOnlyArray => threadInfos.filter(threadInfo => threadHasPermission(threadInfo, threadPermissions.EDIT_ENTRIES), ), @@ -289,7 +289,9 @@ ).length, ); -const baseAncestorThreadInfos = (threadID: string) => +const baseAncestorThreadInfos: ( + threadID: string, +) => (BaseAppState<>) => $ReadOnlyArray = (threadID: string) => createSelector( (state: BaseAppState<>) => threadInfoSelector(state), (threadInfos: { @@ -312,7 +314,9 @@ baseAncestorThreadInfos, ); -const baseOtherUsersButNoOtherAdmins = (threadID: string) => +const baseOtherUsersButNoOtherAdmins: ( + threadID: string, +) => (BaseAppState<>) => boolean = (threadID: string) => createSelector( (state: BaseAppState<>) => state.threadStore.threadInfos[threadID], relativeMemberInfoSelectorForMembersOfThread(threadID), @@ -443,7 +447,10 @@ }, ); -const baseSavedEmojiAvatarSelectorForThread = ( +const baseSavedEmojiAvatarSelectorForThread: ( + threadID: string, + containingThreadID: ?string, +) => (BaseAppState<>) => () => ClientAvatar = ( threadID: string, containingThreadID: ?string, ) => @@ -469,7 +476,11 @@ baseSavedEmojiAvatarSelectorForThread, ); -const baseThreadInfosSelectorForThreadType = (threadType: ThreadType) => +const baseThreadInfosSelectorForThreadType: ( + threadType: ThreadType, +) => (BaseAppState<>) => $ReadOnlyArray = ( + threadType: ThreadType, +) => createSelector( (state: BaseAppState<>) => threadInfoSelector(state), (threadInfos: { diff --git a/lib/selectors/user-selectors.js b/lib/selectors/user-selectors.js --- a/lib/selectors/user-selectors.js +++ b/lib/selectors/user-selectors.js @@ -17,6 +17,7 @@ import { type RawThreadInfo, type RelativeMemberInfo, + type RawThreadInfos, } from '../types/thread-types.js'; import type { UserInfos, @@ -95,7 +96,9 @@ const emptyArray: $ReadOnlyArray = []; // Includes current user at the start -const baseRelativeMemberInfoSelectorForMembersOfThread = ( +const baseRelativeMemberInfoSelectorForMembersOfThread: ( + threadID: ?string, +) => (state: BaseAppState<>) => $ReadOnlyArray = ( threadID: ?string, ) => { if (!threadID) { @@ -204,9 +207,9 @@ const usersWithPersonalThreadSelector: ( state: BaseAppState<>, ) => $ReadOnlySet = createSelector( - state => state.currentUserInfo && state.currentUserInfo.id, - state => state.threadStore.threadInfos, - (viewerID, threadInfos) => { + (state: BaseAppState<>) => state.currentUserInfo && state.currentUserInfo.id, + (state: BaseAppState<>) => state.threadStore.threadInfos, + (viewerID: ?string, threadInfos: RawThreadInfos) => { const personalThreadMembers = new Set(); for (const threadID in threadInfos) {