Page MenuHomePhorge

D8074.1768328389.diff
No OneTemporary

Size
7 KB
Referenced Files
None
Subscribers
None

D8074.1768328389.diff

diff --git a/lib/hooks/message-hooks.js b/lib/hooks/message-hooks.js
--- a/lib/hooks/message-hooks.js
+++ b/lib/hooks/message-hooks.js
@@ -1,6 +1,21 @@
// @flow
+import _max from 'lodash/fp/max.js';
+import _min from 'lodash/fp/min.js';
+import * as React from 'react';
+
+import {
+ fetchLatestMessages,
+ fetchLatestMessagesActionTypes,
+} from '../actions/message-actions.js';
+import { createLoadingStatusSelector } from '../selectors/loading-selectors.js';
import { getOldestNonLocalMessageID } from '../shared/message-utils.js';
+import type { LoadingStatus } from '../types/loading-types.js';
+import {
+ useDispatchActionPromise,
+ useServerCall,
+} from '../utils/action-utils.js';
+import { values } from '../utils/objects.js';
import { useSelector } from '../utils/redux-utils.js';
function useOldestMessageServerID(threadID: string): ?string {
@@ -9,4 +24,80 @@
);
}
-export { useOldestMessageServerID };
+type FetchLatestMessagesState =
+ | { type: 'everything_loaded' }
+ | { type: 'loaded_upto_message', message: string };
+
+function useFetchLatestMessages(home: boolean): {
+ fetchMoreLatestMessages: () => Promise<void>,
+ loadingStatus: LoadingStatus,
+} {
+ const dispatchActionPromise = useDispatchActionPromise();
+ const callFetchLatestMessages = useServerCall(fetchLatestMessages);
+
+ const messageStoreThreads = useSelector(state => state.messageStore.threads);
+ const [fetchState, setFetchState] =
+ React.useState<?FetchLatestMessagesState>(null);
+
+ React.useEffect(() => {
+ if (values(messageStoreThreads).length === 0) {
+ setFetchState(null);
+ } else if (fetchState === null) {
+ const latestMessageForThread = thread =>
+ _max(thread.messageIDs.map(Number));
+
+ const oldestLatestMessage = _min(
+ values(messageStoreThreads).map(latestMessageForThread),
+ );
+
+ if (oldestLatestMessage) {
+ setFetchState({
+ type: 'loaded_upto_message',
+ message: oldestLatestMessage.toString(),
+ });
+ }
+ }
+ }, [fetchState, messageStoreThreads]);
+
+ const fetchMoreLatestMessages = React.useCallback(async () => {
+ if (fetchState?.type !== 'loaded_upto_message') {
+ return;
+ }
+
+ await dispatchActionPromise(
+ fetchLatestMessagesActionTypes,
+ (async () => {
+ const result = await callFetchLatestMessages({
+ home,
+ fromMessage: fetchState.message,
+ });
+
+ if (
+ !result.oldestMessage ||
+ result.oldestMessage === fetchState.message
+ ) {
+ setFetchState({ type: 'everything_loaded' });
+ } else {
+ setFetchState({
+ type: 'loaded_upto_message',
+ message: result.oldestMessage,
+ });
+ }
+
+ return result;
+ })(),
+ );
+ }, [fetchState, dispatchActionPromise, callFetchLatestMessages, home]);
+
+ const loadingStatusSelector = createLoadingStatusSelector(
+ fetchLatestMessagesActionTypes,
+ );
+ const loadingStatus = useSelector(loadingStatusSelector);
+
+ return {
+ fetchMoreLatestMessages,
+ loadingStatus,
+ };
+}
+
+export { useOldestMessageServerID, useFetchLatestMessages };
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
@@ -127,12 +127,17 @@
messageStore: MessageStore,
messages: { +[id: string]: ?MessageInfo },
sidebarInfos: ?$ReadOnlyArray<SidebarInfo>,
-): ChatThreadItem {
+): ?ChatThreadItem {
const mostRecentMessageInfo = getMostRecentMessageInfo(
threadInfo,
messageStore,
messages,
);
+
+ if (!mostRecentMessageInfo) {
+ return null;
+ }
+
const mostRecentNonLocalMessage = getMostRecentNonLocalMessageID(
threadInfo.id,
messageStore,
@@ -256,7 +261,7 @@
): $ReadOnlyArray<ChatThreadItem> {
return _flow(
_filter(filterFunction),
- _map((threadInfo: ThreadInfo): ChatThreadItem =>
+ _map((threadInfo: ThreadInfo): ?ChatThreadItem =>
createChatThreadItem(
threadInfo,
messageStore,
@@ -264,6 +269,7 @@
sidebarInfos[threadInfo.id],
),
),
+ _filter(Boolean),
_orderBy('lastUpdatedTimeIncludingSidebars')('desc'),
)(threadInfos);
}
diff --git a/native/chat/chat-thread-list.react.js b/native/chat/chat-thread-list.react.js
--- a/native/chat/chat-thread-list.react.js
+++ b/native/chat/chat-thread-list.react.js
@@ -18,6 +18,7 @@
import { searchUsers } from 'lib/actions/user-actions.js';
import { useLoggedInUserInfo } from 'lib/hooks/account-hooks.js';
+import { useFetchLatestMessages } from 'lib/hooks/message-hooks.js';
import {
type ChatThreadItem,
useFlattenedChatListData,
@@ -29,6 +30,7 @@
createPendingThread,
getThreadListSearchResults,
} from 'lib/shared/thread-utils.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
import type { UserSearchResult } from 'lib/types/search-types.js';
import { threadTypes } from 'lib/types/thread-types-enum.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
@@ -112,6 +114,8 @@
+navigateToThread: (params: MessageListParams) => void,
// async functions that hit server APIs
+searchUsers: (usernamePrefix: string) => Promise<UserSearchResult>,
+ +fetchMoreLatestMessages: () => Promise<void>,
+ +loadingStatus: LoadingStatus,
};
type SearchStatus = 'inactive' | 'activating' | 'active';
type State = {
@@ -215,6 +219,10 @@
this.searchCancelButtonOpen.setValue(0);
}
+ if (this.listData.length < 3 && this.props.loadingStatus !== 'loading') {
+ this.props.fetchMoreLatestMessages();
+ }
+
const { flatList } = this;
if (!flatList) {
return;
@@ -440,12 +448,13 @@
}
onEndReached = () => {
- if (this.listData.length === this.fullListData.length) {
- return;
+ if (this.listData.length !== this.fullListData.length) {
+ this.setState(prevState => ({
+ numItemsToDisplay: prevState.numItemsToDisplay + 25,
+ }));
+ } else if (this.props.loadingStatus !== 'loading') {
+ this.props.fetchMoreLatestMessages();
}
- this.setState(prevState => ({
- numItemsToDisplay: prevState.numItemsToDisplay + 25,
- }));
};
render() {
@@ -488,6 +497,7 @@
scrollEnabled={scrollEnabled}
onEndReached={this.onEndReached}
onEndReachedThreshold={1}
+ refreshing={this.props.loadingStatus === 'loading'}
ref={this.flatListRef}
/>
{floatingAction}
@@ -629,6 +639,10 @@
const navigateToThread = useNavigateToThread();
+ const { fetchMoreLatestMessages, loadingStatus } = useFetchLatestMessages(
+ props.route.name === 'HomeChatThreadList',
+ );
+
return (
<ChatThreadList
{...props}
@@ -638,6 +652,8 @@
styles={styles}
indicatorStyle={indicatorStyle}
searchUsers={callSearchUsers}
+ fetchMoreLatestMessages={fetchMoreLatestMessages}
+ loadingStatus={loadingStatus}
usersWithPersonalThread={usersWithPersonalThread}
navigateToThread={navigateToThread}
/>

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 13, 6:19 PM (1 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5928681
Default Alt Text
D8074.1768328389.diff (7 KB)

Event Timeline