Page MenuHomePhabricator

D7746.id26215.diff
No OneTemporary

D7746.id26215.diff

diff --git a/lib/hooks/message-hooks.js b/lib/hooks/message-hooks.js
new file mode 100644
--- /dev/null
+++ b/lib/hooks/message-hooks.js
@@ -0,0 +1,12 @@
+// @flow
+
+import { getOldestNonLocalMessageID } from '../shared/message-utils.js';
+import { useSelector } from '../utils/redux-utils.js';
+
+function useOldestMessageServerID(threadID: string): ?string {
+ return useSelector(state =>
+ getOldestNonLocalMessageID(threadID, state.messageStore),
+ );
+}
+
+export { useOldestMessageServerID };
diff --git a/lib/shared/message-utils.js b/lib/shared/message-utils.js
--- a/lib/shared/message-utils.js
+++ b/lib/shared/message-utils.js
@@ -380,6 +380,19 @@
return thread?.messageIDs.find(id => !id.startsWith(localIDPrefix));
}
+function getOldestNonLocalMessageID(
+ threadID: string,
+ messageStore: MessageStore,
+): ?string {
+ const thread = messageStore.threads[threadID];
+ if (!thread) {
+ return thread;
+ }
+ const { messageIDs } = thread;
+ const reversedMessageIDs = [...messageIDs].reverse();
+ return reversedMessageIDs.find(id => !id.startsWith(localIDPrefix));
+}
+
function getMessageTitle(
messageInfo:
| ComposableMessageInfo
@@ -604,6 +617,7 @@
createMessageQuote,
createMessageReply,
getMostRecentNonLocalMessageID,
+ getOldestNonLocalMessageID,
getMessageTitle,
mergeThreadMessageInfos,
useMessagePreview,
diff --git a/native/chat/message-list.react.js b/native/chat/message-list.react.js
--- a/native/chat/message-list.react.js
+++ b/native/chat/message-list.react.js
@@ -12,6 +12,7 @@
fetchMostRecentMessagesActionTypes,
fetchMostRecentMessages,
} from 'lib/actions/message-actions.js';
+import { useOldestMessageServerID } from 'lib/hooks/message-hooks.js';
import { registerFetchKey } from 'lib/reducers/loading-reducer.js';
import { messageKey } from 'lib/shared/message-utils.js';
import { useWatchThread } from 'lib/shared/thread-utils.js';
@@ -59,13 +60,10 @@
};
type Props = {
...BaseProps,
- // Redux state
+startReached: boolean,
+styles: typeof unboundStyles,
+indicatorStyle: IndicatorStyle,
- // Redux dispatch functions
+dispatchActionPromise: DispatchActionPromise,
- // async functions that hit server APIs
+fetchMessagesBeforeCursor: (
threadID: string,
beforeMessageID: string,
@@ -73,10 +71,9 @@
+fetchMostRecentMessages: (
threadID: string,
) => Promise<FetchMessageInfosPayload>,
- // withOverlayContext
+overlayContext: ?OverlayContextType,
- // withKeyboardState
+keyboardState: ?KeyboardState,
+ +oldestMessageServerID: ?string,
};
type State = {
+focusedMessageKey: ?string,
@@ -140,15 +137,6 @@
}
componentDidUpdate(prevProps: Props) {
- const newListData = this.props.messageListData;
- const oldListData = prevProps.messageListData;
- if (
- this.state.loadingFromScroll &&
- (newListData.length > oldListData.length || this.props.startReached)
- ) {
- this.setState({ loadingFromScroll: false });
- }
-
const modalIsOpen = MessageList.modalOpen(this.props);
const modalWasOpen = MessageList.modalOpen(prevProps);
if (!modalIsOpen && modalWasOpen) {
@@ -294,30 +282,30 @@
}
this.setState({ loadingFromScroll: true });
- const oldestMessageServerID = this.oldestMessageServerID();
+ const { oldestMessageServerID } = this.props;
const threadID = this.props.threadInfo.id;
- if (oldestMessageServerID) {
- this.props.dispatchActionPromise(
- fetchMessagesBeforeCursorActionTypes,
- this.props.fetchMessagesBeforeCursor(threadID, oldestMessageServerID),
- );
- } else {
- this.props.dispatchActionPromise(
- fetchMostRecentMessagesActionTypes,
- this.props.fetchMostRecentMessages(threadID),
- );
- }
- };
- oldestMessageServerID(): ?string {
- const data = this.props.messageListData;
- for (let i = data.length - 1; i >= 0; i--) {
- if (data[i].itemType === 'message' && data[i].messageInfo.id) {
- return data[i].messageInfo.id;
+ (async () => {
+ try {
+ if (oldestMessageServerID) {
+ await this.props.dispatchActionPromise(
+ fetchMessagesBeforeCursorActionTypes,
+ this.props.fetchMessagesBeforeCursor(
+ threadID,
+ oldestMessageServerID,
+ ),
+ );
+ } else {
+ await this.props.dispatchActionPromise(
+ fetchMostRecentMessagesActionTypes,
+ this.props.fetchMostRecentMessages(threadID),
+ );
+ }
+ } finally {
+ this.setState({ loadingFromScroll: false });
}
- }
- return null;
- }
+ })();
+ };
}
const unboundStyles = {
@@ -359,6 +347,8 @@
);
const callFetchMostRecentMessages = useServerCall(fetchMostRecentMessages);
+ const oldestMessageServerID = useOldestMessageServerID(threadID);
+
useWatchThread(props.threadInfo);
return (
@@ -372,6 +362,7 @@
fetchMostRecentMessages={callFetchMostRecentMessages}
overlayContext={overlayContext}
keyboardState={keyboardState}
+ oldestMessageServerID={oldestMessageServerID}
/>
);
});
diff --git a/web/chat/chat-message-list.react.js b/web/chat/chat-message-list.react.js
--- a/web/chat/chat-message-list.react.js
+++ b/web/chat/chat-message-list.react.js
@@ -11,6 +11,7 @@
fetchMostRecentMessagesActionTypes,
fetchMostRecentMessages,
} from 'lib/actions/message-actions.js';
+import { useOldestMessageServerID } from 'lib/hooks/message-hooks.js';
import { registerFetchKey } from 'lib/reducers/loading-reducer.js';
import {
type ChatMessageItem,
@@ -46,13 +47,10 @@
type Props = {
...BaseProps,
- // Redux state
+activeChatThreadID: ?string,
+messageListData: ?$ReadOnlyArray<ChatMessageItem>,
+startReached: boolean,
- // Redux dispatch functions
+dispatchActionPromise: DispatchActionPromise,
- // async functions that hit server APIs
+fetchMessagesBeforeCursor: (
threadID: string,
beforeMessageID: string,
@@ -60,9 +58,9 @@
+fetchMostRecentMessages: (
threadID: string,
) => Promise<FetchMessageInfosPayload>,
- // withInputState
+inputState: ?InputState,
+clearTooltip: () => mixed,
+ +oldestMessageServerID: ?string,
};
type Snapshot = {
+scrollTop: number,
@@ -107,16 +105,6 @@
const { messageListData } = this.props;
const prevMessageListData = prevProps.messageListData;
- if (
- this.loadingFromScroll &&
- messageListData &&
- (!prevMessageListData ||
- messageListData.length > prevMessageListData.length ||
- this.props.startReached)
- ) {
- this.loadingFromScroll = false;
- }
-
const { messageContainer } = this;
if (messageContainer && prevMessageListData !== messageListData) {
this.onScroll();
@@ -229,7 +217,7 @@
this.possiblyLoadMoreMessages();
};
- possiblyLoadMoreMessages() {
+ async possiblyLoadMoreMessages() {
if (!this.messageContainer) {
return;
}
@@ -250,29 +238,22 @@
const threadID = this.props.activeChatThreadID;
invariant(threadID, 'should be set');
- const oldestMessageServerID = this.oldestMessageServerID();
- if (oldestMessageServerID) {
- this.props.dispatchActionPromise(
- fetchMessagesBeforeCursorActionTypes,
- this.props.fetchMessagesBeforeCursor(threadID, oldestMessageServerID),
- );
- } else {
- this.props.dispatchActionPromise(
- fetchMostRecentMessagesActionTypes,
- this.props.fetchMostRecentMessages(threadID),
- );
- }
- }
-
- oldestMessageServerID(): ?string {
- const data = this.props.messageListData;
- invariant(data, 'should be set');
- for (let i = data.length - 1; i >= 0; i--) {
- if (data[i].itemType === 'message' && data[i].messageInfo.id) {
- return data[i].messageInfo.id;
+ try {
+ const { oldestMessageServerID } = this.props;
+ if (oldestMessageServerID) {
+ await this.props.dispatchActionPromise(
+ fetchMessagesBeforeCursorActionTypes,
+ this.props.fetchMessagesBeforeCursor(threadID, oldestMessageServerID),
+ );
+ } else {
+ await this.props.dispatchActionPromise(
+ fetchMostRecentMessagesActionTypes,
+ this.props.fetchMostRecentMessages(threadID),
+ );
}
+ } finally {
+ this.loadingFromScroll = false;
}
- return null;
}
}
@@ -324,6 +305,8 @@
return { getTextMessageMarkdownRules };
}, [getTextMessageMarkdownRules]);
+ const oldestMessageServerID = useOldestMessageServerID(threadInfo.id);
+
return (
<MessageListContext.Provider value={messageListContext}>
<ChatMessageList
@@ -336,6 +319,7 @@
fetchMessagesBeforeCursor={callFetchMessagesBeforeCursor}
fetchMostRecentMessages={callFetchMostRecentMessages}
clearTooltip={clearTooltip}
+ oldestMessageServerID={oldestMessageServerID}
/>
</MessageListContext.Provider>
);

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 10, 5:15 PM (17 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2852623
Default Alt Text
D7746.id26215.diff (8 KB)

Event Timeline