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 @@ -587,7 +587,7 @@ const baseMessageListData = ( threadID: ?string, additionalMessages: $ReadOnlyArray, -) => +): ((state: BaseAppState<>) => ?(ChatMessageItem[])) => createSelector( (state: BaseAppState<>) => state.messageStore, messageInfoSelector, @@ -636,7 +636,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 @@ -38,13 +38,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 @@ -77,7 +78,7 @@ boundStateSyncSpecsSelector, currentCalendarQuery, ( - { specsPerHashKey, specPerInnerHashKey }, + boundStateSyncSpecs: BoundStateSyncSpecs, calendarQuery: (calendarActive: boolean) => CalendarQuery, ) => { return async ( @@ -91,6 +92,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 { @@ -114,7 +114,7 @@ ( inputThreadIDs: ?$ReadOnlySet, threadInfos: $ReadOnlyArray, - ) => { + ): $ReadOnlyArray => { const threadIDs = inputThreadIDs; if (!threadIDs) { return threadInfos; @@ -127,7 +127,7 @@ state: BaseAppState<>, ) => $ReadOnlyArray = createSelector( onScreenThreadInfos, - (threadInfos: $ReadOnlyArray) => + (threadInfos: $ReadOnlyArray): $ReadOnlyArray => threadInfos.filter(threadInfo => threadHasPermission(threadInfo, threadPermissions.EDIT_ENTRIES), ), @@ -294,7 +294,9 @@ ).length, ); -const baseAncestorThreadInfos = (threadID: string) => +const baseAncestorThreadInfos: ( + threadID: string, +) => (BaseAppState<>) => $ReadOnlyArray = (threadID: string) => createSelector( (state: BaseAppState<>) => threadInfoSelector(state), (threadInfos: { @@ -317,7 +319,9 @@ baseAncestorThreadInfos, ); -const baseOtherUsersButNoOtherAdmins = (threadID: string) => +const baseOtherUsersButNoOtherAdmins: ( + threadID: string, +) => (BaseAppState<>) => boolean = (threadID: string) => createSelector( (state: BaseAppState<>) => state.threadStore.threadInfos[threadID], relativeMemberInfoSelectorForMembersOfThread(threadID), @@ -450,7 +454,10 @@ }, ); -const baseSavedEmojiAvatarSelectorForThread = ( +const baseSavedEmojiAvatarSelectorForThread: ( + threadID: string, + containingThreadID: ?string, +) => (BaseAppState<>) => () => ClientAvatar = ( threadID: string, containingThreadID: ?string, ) => @@ -476,7 +483,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 @@ -18,6 +18,7 @@ import { type RawThreadInfo, type RelativeMemberInfo, + type RawThreadInfos, } from '../types/thread-types.js'; import type { UserInfos, @@ -96,7 +97,9 @@ const emptyArray: $ReadOnlyArray = []; // Includes current user at the start -const baseRelativeMemberInfoSelectorForMembersOfThread = ( +const baseRelativeMemberInfoSelectorForMembersOfThread: ( + threadID: ?string, +) => (state: BaseAppState<>) => $ReadOnlyArray = ( threadID: ?string, ) => { if (!threadID) { @@ -206,9 +209,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) {