diff --git a/native/chat/message-store-pruner.react.js b/lib/components/message-store-pruner.react.js rename from native/chat/message-store-pruner.react.js rename to lib/components/message-store-pruner.react.js --- a/native/chat/message-store-pruner.react.js +++ b/lib/components/message-store-pruner.react.js @@ -2,31 +2,27 @@ import * as React from 'react'; -import { messageStorePruneActionType } from 'lib/actions/message-actions.js'; -import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils.js'; -import { useDispatch } from 'lib/utils/redux-utils.js'; - -import { NavContext } from '../navigation/navigation-context.js'; -import { useSelector } from '../redux/redux-utils.js'; +import { messageStorePruneActionType } from '../actions/message-actions.js'; import { nextMessagePruneTimeSelector, pruneThreadIDsSelector, -} from '../selectors/message-selectors.js'; +} from '../selectors/message-selector.js'; +import { useIsAppForegrounded } from '../shared/lifecycle-utils.js'; +import { useDispatch, useSelector } from '../utils/redux-utils.js'; + +type Props = { + +frozen?: boolean, + +activeThreadID: ?string, +}; +function MessageStorePruner(props: Props): null { + const { frozen, activeThreadID } = props; -function MessageStorePruner(): null { const nextMessagePruneTime = useSelector(nextMessagePruneTimeSelector); const prevNextMessagePruneTimeRef = React.useRef(nextMessagePruneTime); const foreground = useIsAppForegrounded(); - const frozen = useSelector(state => state.frozen); - const navContext = React.useContext(NavContext); - const pruneThreadIDs = useSelector(state => - pruneThreadIDsSelector({ - redux: state, - navContext, - }), - ); + const pruneThreadIDs = useSelector(pruneThreadIDsSelector); const prunedRef = React.useRef(false); @@ -51,7 +47,7 @@ if (timeUntilExpiration > 0) { return; } - const threadIDs = pruneThreadIDs(); + const threadIDs = pruneThreadIDs(activeThreadID); if (threadIDs.length === 0) { return; } @@ -61,7 +57,14 @@ payload: { threadIDs }, }); // We include foreground so this effect will be called on foreground - }, [nextMessagePruneTime, frozen, foreground, pruneThreadIDs, dispatch]); + }, [ + nextMessagePruneTime, + frozen, + foreground, + pruneThreadIDs, + dispatch, + activeThreadID, + ]); return null; } diff --git a/native/selectors/message-selectors.js b/lib/selectors/message-selector.js rename from native/selectors/message-selectors.js rename to lib/selectors/message-selector.js --- a/native/selectors/message-selectors.js +++ b/lib/selectors/message-selector.js @@ -2,15 +2,14 @@ import { createSelector } from 'reselect'; -import { threadIsPending } from 'lib/shared/thread-utils.js'; -import type { ThreadMessageInfo } from 'lib/types/message-types.js'; -import { defaultNumberPerThread } from 'lib/types/message-types.js'; -import type { ThreadActivityStore } from 'lib/types/thread-activity-types.js'; -import type { RawThreadInfos } from 'lib/types/thread-types.js'; - -import { activeThreadSelector } from '../navigation/nav-selectors.js'; -import type { AppState } from '../redux/state-types.js'; -import type { NavPlusRedux } from '../types/selector-types.js'; +import { threadIsPending } from '../shared/thread-utils.js'; +import { + type ThreadMessageInfo, + defaultNumberPerThread, +} from '../types/message-types.js'; +import type { AppState } from '../types/redux-types.js'; +import type { ThreadActivityStore } from '../types/thread-activity-types.js'; +import type { RawThreadInfos } from '../types/thread-types.js'; const msInHour = 60 * 60 * 1000; @@ -18,12 +17,21 @@ createSelector( (state: AppState) => state.threadStore.threadInfos, (state: AppState) => state.threadActivityStore, + (state: AppState) => state.messageStore.threads, ( threadInfos: RawThreadInfos, threadActivityStore: ThreadActivityStore, + threadMessageInfos: { +[id: string]: ThreadMessageInfo }, ): ?number => { let nextTime; for (const threadID in threadInfos) { + if ( + !threadMessageInfos[threadID] || + threadMessageInfos[threadID].messageIDs.length <= + defaultNumberPerThread + ) { + continue; + } const threadPruneTime = Math.max( (threadActivityStore?.[threadID]?.lastNavigatedTo ?? 0) + msInHour, (threadActivityStore?.[threadID]?.lastPruned ?? 0) + msInHour * 6, @@ -37,17 +45,15 @@ ); const pruneThreadIDsSelector: ( - input: NavPlusRedux, -) => () => $ReadOnlyArray = createSelector( - (input: NavPlusRedux): ThreadActivityStore => input.redux.threadActivityStore, - (input: NavPlusRedux) => input.redux.messageStore.threads, - (input: NavPlusRedux) => activeThreadSelector(input.navContext), + state: AppState, +) => (activeThread: ?string) => $ReadOnlyArray = createSelector( + (state: AppState): ThreadActivityStore => state.threadActivityStore, + (state: AppState) => state.messageStore.threads, ( threadActivityStore: ThreadActivityStore, threadMessageInfos: { +[id: string]: ThreadMessageInfo }, - activeThread: ?string, ) => - (): $ReadOnlyArray => { + (activeThread: ?string): $ReadOnlyArray => { const now = Date.now(); const threadIDsToPrune = []; for (const threadID in threadMessageInfos) { diff --git a/native/chat/chat.react.js b/native/chat/chat.react.js --- a/native/chat/chat.react.js +++ b/native/chat/chat.react.js @@ -25,8 +25,8 @@ import invariant from 'invariant'; import * as React from 'react'; import { Platform, View, useWindowDimensions } from 'react-native'; -import { useSelector } from 'react-redux'; +import MessageStorePruner from 'lib/components/message-store-pruner.react.js'; import ThreadDraftUpdater from 'lib/components/thread-draft-updater.react.js'; import { isLoggedIn } from 'lib/selectors/user-selectors.js'; import { threadIsPending } from 'lib/shared/thread-utils.js'; @@ -44,7 +44,6 @@ import { MessageEditingContext } from './message-editing-context.react.js'; import MessageListContainer from './message-list-container.react.js'; import MessageListHeaderTitle from './message-list-header-title.react.js'; -import MessageStorePruner from './message-store-pruner.react.js'; import PinnedMessagesScreen from './pinned-messages-screen.react.js'; import DeleteThread from './settings/delete-thread.react.js'; import EmojiThreadAvatarCreation from './settings/emoji-thread-avatar-creation.react.js'; @@ -57,6 +56,8 @@ import { InputStateContext } from '../input/input-state.js'; import CommunityDrawerButton from '../navigation/community-drawer-button.react.js'; import HeaderBackButton from '../navigation/header-back-button.react.js'; +import { activeThreadSelector } from '../navigation/nav-selectors.js'; +import { NavContext } from '../navigation/navigation-context.js'; import { defaultStackScreenOptions, transitionPreset, @@ -80,6 +81,7 @@ type NavigationRoute, } from '../navigation/route-names.js'; import type { TabNavigationProp } from '../navigation/tab-navigator.react.js'; +import { useSelector } from '../redux/redux-utils.js'; import ChangeRolesHeaderLeftButton from '../roles/change-roles-header-left-button.react.js'; import ChangeRolesScreen from '../roles/change-roles-screen.react.js'; import MessageSearch from '../search/message-search.react.js'; @@ -410,6 +412,10 @@ [styles.threadListHeaderStyle], ); + const frozen = useSelector(state => state.frozen); + const navContext = React.useContext(NavContext); + const activeThreadID = activeThreadSelector(navContext); + return ( - + {draftUpdater} diff --git a/web/chat/chat.react.js b/web/chat/chat.react.js --- a/web/chat/chat.react.js +++ b/web/chat/chat.react.js @@ -2,6 +2,7 @@ import * as React from 'react'; +import MessageStorePruner from 'lib/components/message-store-pruner.react.js'; import ThreadDraftUpdater from 'lib/components/thread-draft-updater.react.js'; import { isLoggedIn } from 'lib/selectors/user-selectors.js'; @@ -9,6 +10,7 @@ import ChatTabs from './chat-tabs.react.js'; import { ThreadListProvider } from './thread-list-provider.js'; import { useSelector } from '../redux/redux-utils.js'; +import { activeThreadSelector } from '../selectors/nav-selectors.js'; function Chat(): React.Node { const loggedIn = useSelector(isLoggedIn); @@ -37,11 +39,15 @@ if (loggedIn) { threadDraftUpdater = ; } + + const activeThreadID = useSelector(activeThreadSelector); + return ( <> {chatList} {messageList} {threadDraftUpdater} + ); }