diff --git a/web/redux/nav-reducer.js b/web/redux/nav-reducer.js index f6397c806..f4e9005c4 100644 --- a/web/redux/nav-reducer.js +++ b/web/redux/nav-reducer.js @@ -1,43 +1,43 @@ // @flow import { pendingToRealizedThreadIDsSelector } from 'lib/selectors/thread-selectors.js'; import { threadIsPending } from 'lib/shared/thread-utils.js'; -import type { LegacyRawThreadInfos } from 'lib/types/thread-types.js'; +import type { RawThreadInfos } from 'lib/types/thread-types.js'; import { updateNavInfoActionType } from '../redux/action-types.js'; import type { Action } from '../redux/redux-setup.js'; import { type NavInfo } from '../types/nav-types.js'; export default function reduceNavInfo( oldState: NavInfo, action: Action, - newThreadInfos: LegacyRawThreadInfos, + newThreadInfos: RawThreadInfos, ): NavInfo { let state = oldState; if (action.type === updateNavInfoActionType) { state = { ...state, ...action.payload, }; } const { activeChatThreadID } = state; if (activeChatThreadID) { const pendingToRealizedThreadIDs = pendingToRealizedThreadIDsSelector(newThreadInfos); const realizedThreadID = pendingToRealizedThreadIDs.get(activeChatThreadID); if (realizedThreadID) { state = { ...state, activeChatThreadID: realizedThreadID, }; } } if (state.pendingThread && !threadIsPending(state.activeChatThreadID)) { const { pendingThread, ...stateWithoutPendingThread } = state; state = stateWithoutPendingThread; } return state; } diff --git a/web/selectors/thread-selectors.js b/web/selectors/thread-selectors.js index 6a46e4f09..ca20a0e54 100644 --- a/web/selectors/thread-selectors.js +++ b/web/selectors/thread-selectors.js @@ -1,162 +1,159 @@ // @flow import invariant from 'invariant'; import * as React from 'react'; import { createSelector } from 'reselect'; import { ENSCacheContext } from 'lib/components/ens-cache-provider.react.js'; import { useLoggedInUserInfo } from 'lib/hooks/account-hooks.js'; import { useThreadChatMentionCandidates } from 'lib/hooks/chat-mention-hooks.js'; import { createPendingSidebar, threadInHomeChatList, } from 'lib/shared/thread-utils.js'; import type { ComposableMessageInfo, RobotextMessageInfo, } from 'lib/types/message-types.js'; -import type { - LegacyRawThreadInfos, - ThreadInfo, -} from 'lib/types/thread-types.js'; +import type { RawThreadInfos, ThreadInfo } from 'lib/types/thread-types.js'; import { values } from 'lib/utils/objects.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; import { getDefaultTextMessageRules } from '../markdown/rules.react.js'; import { updateNavInfoActionType } from '../redux/action-types.js'; import type { AppState } from '../redux/redux-setup.js'; import { useSelector } from '../redux/redux-utils.js'; function useOnClickThread( thread: ?ThreadInfo, ): (event: SyntheticEvent) => void { const dispatch = useDispatch(); return React.useCallback( (event: SyntheticEvent) => { invariant( thread?.id, 'useOnClickThread should be called with threadID set', ); event.preventDefault(); const { id: threadID } = thread; let payload; if (threadID.includes('pending')) { payload = { chatMode: 'view', activeChatThreadID: threadID, pendingThread: thread, tab: 'chat', }; } else { payload = { chatMode: 'view', activeChatThreadID: threadID, tab: 'chat', }; } dispatch({ type: updateNavInfoActionType, payload }); }, [dispatch, thread], ); } function useThreadIsActive(threadID: string): boolean { return useSelector(state => threadID === state.navInfo.activeChatThreadID); } function useOnClickPendingSidebar( messageInfo: ComposableMessageInfo | RobotextMessageInfo, threadInfo: ThreadInfo, ): (event: SyntheticEvent) => mixed { const dispatch = useDispatch(); const loggedInUserInfo = useLoggedInUserInfo(); const cacheContext = React.useContext(ENSCacheContext); const { getENSNames } = cacheContext; const chatMentionCandidates = useThreadChatMentionCandidates(threadInfo); return React.useCallback( async (event: SyntheticEvent) => { event.preventDefault(); if (!loggedInUserInfo) { return; } const pendingSidebarInfo = await createPendingSidebar({ sourceMessageInfo: messageInfo, parentThreadInfo: threadInfo, loggedInUserInfo, markdownRules: getDefaultTextMessageRules(chatMentionCandidates) .simpleMarkdownRules, getENSNames, }); dispatch({ type: updateNavInfoActionType, payload: { activeChatThreadID: pendingSidebarInfo.id, pendingThread: pendingSidebarInfo, }, }); }, [ loggedInUserInfo, chatMentionCandidates, threadInfo, messageInfo, getENSNames, dispatch, ], ); } function useOnClickNewThread(): (event: SyntheticEvent) => void { const dispatch = useDispatch(); return React.useCallback( (event: SyntheticEvent) => { event.preventDefault(); dispatch({ type: updateNavInfoActionType, payload: { chatMode: 'create', selectedUserList: [], }, }); }, [dispatch], ); } function useDrawerSelectedThreadID(): ?string { const activeChatThreadID = useSelector( state => state.navInfo.activeChatThreadID, ); const pickedCommunityID = useSelector( state => state.communityPickerStore.calendar, ); const inCalendar = useSelector(state => state.navInfo.tab === 'calendar'); return inCalendar ? pickedCommunityID : activeChatThreadID; } const unreadCountInSelectedCommunity: (state: AppState) => number = createSelector( (state: AppState) => state.threadStore.threadInfos, (state: AppState) => state.communityPickerStore.chat, - (threadInfos: LegacyRawThreadInfos, communityID: ?string): number => + (threadInfos: RawThreadInfos, communityID: ?string): number => values(threadInfos).filter( threadInfo => threadInHomeChatList(threadInfo) && threadInfo.currentUser.unread && (!communityID || communityID === threadInfo.community), ).length, ); export { useOnClickThread, useThreadIsActive, useOnClickPendingSidebar, useOnClickNewThread, useDrawerSelectedThreadID, unreadCountInSelectedCommunity, };