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 @@ -17,6 +17,10 @@ includeDeletedSelector, } from './calendar-filter-selectors.js'; import { relativeMemberInfoSelectorForMembersOfThread } from './user-selectors.js'; +import { + getAvatarForThread, + getRandomDefaultEmojiAvatar, +} from '../shared/avatar-utils.js'; import { createEntryInfo } from '../shared/entry-utils.js'; import { getMostRecentNonLocalMessageID } from '../shared/message-utils.js'; import { @@ -31,6 +35,7 @@ threadIsPending, getPendingThreadID, } from '../shared/thread-utils.js'; +import type { 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'; @@ -411,6 +416,32 @@ }, ); +const baseSavedEmojiAvatarSelectorForThread = ( + threadID: string, + containingThreadID: ?string, +) => + createSelector( + (state: BaseAppState<*>) => threadInfoSelector(state)[threadID], + (state: BaseAppState<*>) => + containingThreadID ? threadInfoSelector(state)[containingThreadID] : null, + (threadInfo: ThreadInfo, containingThreadInfo: ?ThreadInfo) => { + return () => { + let threadAvatar = getAvatarForThread(threadInfo, containingThreadInfo); + if (threadAvatar.type !== 'emoji') { + threadAvatar = getRandomDefaultEmojiAvatar(); + } + return threadAvatar; + }; + }, + ); + +const savedEmojiAvatarSelectorForThread: ( + threadID: string, + containingThreadID: ?string, +) => (state: BaseAppState<*>) => () => ClientEmojiAvatar = _memoize( + baseSavedEmojiAvatarSelectorForThread, +); + export { ancestorThreadInfos, threadInfoSelector, @@ -428,4 +459,5 @@ sidebarInfoSelector, threadInfoFromSourceMessageIDSelector, pendingToRealizedThreadIDsSelector, + savedEmojiAvatarSelectorForThread, }; diff --git a/lib/shared/avatar-utils.js b/lib/shared/avatar-utils.js --- a/lib/shared/avatar-utils.js +++ b/lib/shared/avatar-utils.js @@ -106,19 +106,15 @@ return getAvatarForUser(memberInfos[0]); } -function useAvatarForThread(thread: RawThreadInfo | ThreadInfo): ClientAvatar { - const containingThreadID = thread.containingThreadID; - const containingThreadInfo = useSelector(state => - containingThreadID ? threadInfoSelector(state)[containingThreadID] : null, - ); - +function getAvatarForThread( + thread: RawThreadInfo | ThreadInfo, + containingThreadInfo: ?ThreadInfo, +): ClientAvatar { if (thread.avatar) { return thread.avatar; } - if (thread.containingThreadID && thread.containingThreadID !== genesis.id) { - invariant(containingThreadInfo, 'containingThreadInfo should be set'); - + if (containingThreadInfo && containingThreadInfo.id !== genesis.id) { return containingThreadInfo.avatar ? containingThreadInfo.avatar : getDefaultAvatar(containingThreadInfo.id, containingThreadInfo.color); @@ -127,6 +123,15 @@ return getDefaultAvatar(thread.id, thread.color); } +function useAvatarForThread(thread: RawThreadInfo | ThreadInfo): ClientAvatar { + const containingThreadID = thread.containingThreadID; + const containingThreadInfo = useSelector(state => + containingThreadID ? threadInfoSelector(state)[containingThreadID] : null, + ); + + return getAvatarForThread(thread, containingThreadInfo); +} + function useENSResolvedAvatar( avatarInfo: ClientAvatar, userInfo: ?UserInfo, @@ -165,6 +170,7 @@ getRandomDefaultEmojiAvatar, getAvatarForUser, getUserAvatarForThread, + getAvatarForThread, useAvatarForThread, useENSResolvedAvatar, };