@droppii-org/chat-mobile 0.2.42 → 0.2.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/lib/module/components/messages/quotedMessage/index.js +6 -4
  2. package/lib/module/components/messages/quotedMessage/index.js.map +1 -1
  3. package/lib/module/context/ChatContext.js +11 -0
  4. package/lib/module/context/ChatContext.js.map +1 -1
  5. package/lib/module/core/useChatListener.js +12 -3
  6. package/lib/module/core/useChatListener.js.map +1 -1
  7. package/lib/module/hooks/message/useMessages.js +65 -0
  8. package/lib/module/hooks/message/useMessages.js.map +1 -0
  9. package/lib/module/hooks/message/useSendMessage.js +10 -2
  10. package/lib/module/hooks/message/useSendMessage.js.map +1 -1
  11. package/lib/module/index.js +0 -1
  12. package/lib/module/index.js.map +1 -1
  13. package/lib/module/screens/chat-detail/ChatDetail.js +35 -30
  14. package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
  15. package/lib/module/screens/chat-detail/ChatListLegend.js +83 -84
  16. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  17. package/lib/module/screens/chat-detail/PinnedMessagesSheet.js +9 -9
  18. package/lib/module/screens/chat-detail/PinnedMessagesSheet.js.map +1 -1
  19. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +9 -3
  20. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  21. package/lib/module/services/attachmentOrchestrator.js +4 -0
  22. package/lib/module/services/attachmentOrchestrator.js.map +1 -1
  23. package/lib/module/store/message.js +148 -6
  24. package/lib/module/store/message.js.map +1 -1
  25. package/lib/module/types/chat.js.map +1 -1
  26. package/lib/module/types/events.js +8 -0
  27. package/lib/module/types/events.js.map +1 -0
  28. package/lib/module/utils/conversation.js +13 -1
  29. package/lib/module/utils/conversation.js.map +1 -1
  30. package/lib/typescript/src/components/messages/quotedMessage/index.d.ts +0 -1
  31. package/lib/typescript/src/components/messages/quotedMessage/index.d.ts.map +1 -1
  32. package/lib/typescript/src/context/ChatContext.d.ts +1 -1
  33. package/lib/typescript/src/context/ChatContext.d.ts.map +1 -1
  34. package/lib/typescript/src/core/useChatListener.d.ts.map +1 -1
  35. package/lib/typescript/src/hooks/message/useMessages.d.ts +16 -0
  36. package/lib/typescript/src/hooks/message/useMessages.d.ts.map +1 -0
  37. package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
  38. package/lib/typescript/src/index.d.ts +0 -1
  39. package/lib/typescript/src/index.d.ts.map +1 -1
  40. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts +1 -1
  41. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
  42. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts +1 -1
  43. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
  44. package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheet.d.ts +2 -1
  45. package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheet.d.ts.map +1 -1
  46. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +1 -1
  47. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  48. package/lib/typescript/src/screens/chat-detail/types.d.ts +7 -7
  49. package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
  50. package/lib/typescript/src/services/attachmentOrchestrator.d.ts.map +1 -1
  51. package/lib/typescript/src/store/message.d.ts.map +1 -1
  52. package/lib/typescript/src/types/chat.d.ts +19 -2
  53. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  54. package/lib/typescript/src/types/events.d.ts +8 -0
  55. package/lib/typescript/src/types/events.d.ts.map +1 -0
  56. package/lib/typescript/src/utils/conversation.d.ts +1 -0
  57. package/lib/typescript/src/utils/conversation.d.ts.map +1 -1
  58. package/package.json +2 -2
  59. package/src/components/messages/quotedMessage/index.tsx +8 -8
  60. package/src/context/ChatContext.tsx +11 -0
  61. package/src/core/useChatListener.ts +18 -2
  62. package/src/hooks/message/useMessages.ts +82 -0
  63. package/src/hooks/message/useSendMessage.ts +13 -2
  64. package/src/index.tsx +0 -1
  65. package/src/screens/chat-detail/ChatDetail.tsx +37 -28
  66. package/src/screens/chat-detail/ChatListLegend.tsx +96 -90
  67. package/src/screens/chat-detail/PinnedMessagesSheet.tsx +12 -7
  68. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +11 -3
  69. package/src/screens/chat-detail/types.ts +7 -7
  70. package/src/services/attachmentOrchestrator.ts +5 -0
  71. package/src/store/message.ts +174 -8
  72. package/src/types/chat.ts +21 -2
  73. package/src/types/events.ts +8 -0
  74. package/src/utils/conversation.ts +14 -0
  75. package/lib/module/hooks/useChatMessages.js +0 -155
  76. package/lib/module/hooks/useChatMessages.js.map +0 -1
  77. package/lib/typescript/src/hooks/useChatMessages.d.ts +0 -21
  78. package/lib/typescript/src/hooks/useChatMessages.d.ts.map +0 -1
  79. package/src/hooks/useChatMessages.ts +0 -246
@@ -29,6 +29,7 @@ interface PinnedMessagesSheetContentProps {
29
29
  currentUserId?: string;
30
30
  unpinMessage: (message: MessageItem) => void | Promise<void>;
31
31
  customMessageItemFactory?: (item: MessageItem) => ReactNode;
32
+ onPressMessage?: (message: MessageItem) => void;
32
33
  }
33
34
 
34
35
  const PinnedMessagesSheetContent = memo(
@@ -36,6 +37,7 @@ const PinnedMessagesSheetContent = memo(
36
37
  currentUserId,
37
38
  unpinMessage,
38
39
  customMessageItemFactory,
40
+ onPressMessage,
39
41
  }: PinnedMessagesSheetContentProps) => {
40
42
  const messages = usePinnedMessageStore((state) => state.messages);
41
43
 
@@ -49,13 +51,13 @@ const PinnedMessagesSheetContent = memo(
49
51
  [unpinMessage]
50
52
  );
51
53
 
52
- const handlePressMessage = useCallback(() => {
53
- UIUtils.bottomSheet.dismiss();
54
- UIUtils.alert.open({
55
- title: trans('chat:view_original_message'),
56
- message: trans('chat:scroll_to_message_todo'),
57
- });
58
- }, []);
54
+ const handlePressMessage = useCallback(
55
+ (message: MessageItem) => {
56
+ UIUtils.bottomSheet.dismiss();
57
+ onPressMessage?.(message);
58
+ },
59
+ [onPressMessage]
60
+ );
59
61
 
60
62
  return (
61
63
  <KContainer.View paddingV="0.5rem">
@@ -181,12 +183,14 @@ export interface OpenPinnedMessagesSheetParams {
181
183
  currentUserId?: string;
182
184
  unpinMessage: (message: MessageItem) => void | Promise<void>;
183
185
  customMessageItemFactory?: (item: MessageItem) => ReactNode;
186
+ onPressMessage?: (message: MessageItem) => void;
184
187
  }
185
188
 
186
189
  export const openPinnedMessagesSheet = ({
187
190
  currentUserId,
188
191
  unpinMessage,
189
192
  customMessageItemFactory,
193
+ onPressMessage,
190
194
  }: OpenPinnedMessagesSheetParams) => {
191
195
  UIUtils.bottomSheet.open({
192
196
  header: {
@@ -201,6 +205,7 @@ export const openPinnedMessagesSheet = ({
201
205
  currentUserId={currentUserId}
202
206
  unpinMessage={unpinMessage}
203
207
  customMessageItemFactory={customMessageItemFactory}
208
+ onPressMessage={onPressMessage}
204
209
  />
205
210
  ),
206
211
  },
@@ -1,6 +1,6 @@
1
1
  import { KContainer, KImage, KColors } from '@droppii/libs';
2
2
  import { StyleSheet } from 'react-native';
3
- import { memo, useMemo } from 'react';
3
+ import { memo, useCallback, useMemo } from 'react';
4
4
  import type { ComponentType, PropsWithChildren, ReactNode } from 'react';
5
5
  import { MessageType } from '@droppii/openim-rn-client-sdk';
6
6
  import type { MessageItem } from '@droppii/openim-rn-client-sdk';
@@ -31,7 +31,7 @@ interface LegendChatMessageProps {
31
31
  onMediaPress?: (items: MediaItem[], index?: number) => void;
32
32
  onPressUrl?: (url: string) => void;
33
33
  onRetry?: (message: MessageItem) => void;
34
- onPress?: () => void;
34
+ onPress?: (message: MessageItem) => void;
35
35
  onLongPress?: () => void;
36
36
  customMessageItemFactory?: (m: MessageItem) => ReactNode;
37
37
  }
@@ -71,6 +71,14 @@ export const LegendChatMessage = memo(
71
71
  onLongPress,
72
72
  customMessageItemFactory,
73
73
  }: LegendChatMessageProps) => {
74
+ const handlePress = useCallback(() => {
75
+ onPress?.(message);
76
+ }, [onPress, message]);
77
+
78
+ const handleLongPress = useCallback(() => {
79
+ onLongPress?.();
80
+ }, [onLongPress]);
81
+
74
82
  const customNode = customMessageItemFactory?.(message);
75
83
 
76
84
  if (customNode) {
@@ -93,7 +101,7 @@ export const LegendChatMessage = memo(
93
101
  onRetry={onRetry}
94
102
  />
95
103
  <KContainer.View style={styles.content}>
96
- <LongPressWrapper onPress={onPress} onLongPress={onLongPress}>
104
+ <LongPressWrapper onPress={handlePress} onLongPress={handleLongPress}>
97
105
  <MessageComponent
98
106
  message={message}
99
107
  isOutgoing={isOutgoing}
@@ -71,15 +71,15 @@ export interface ChatComposerProps {
71
71
 
72
72
  export interface ChatListProps {
73
73
  messages?: MessageItem[];
74
- currentUserId?: string;
74
+ conversationId?: string;
75
75
  customMessageItemFactory?: (item: MessageItem) => ReactNode;
76
- onLoadEarlier?: () => void;
76
+ onLoadMoreOld?: (loadMore: boolean) => void;
77
77
  isLoading?: boolean;
78
- isLoadingEarlier?: boolean;
79
- hasMoreEarlier?: boolean;
80
- onLoadNewer?: () => void;
81
- isLoadingNewer?: boolean;
82
- hasMoreNewer?: boolean;
78
+ moreOldLoading?: boolean;
79
+ hasMoreOld?: boolean;
80
+ onLoadMoreNew?: (loadMore: boolean) => void;
81
+ moreNewLoading?: boolean;
82
+ hasMoreNew?: boolean;
83
83
  onMediaPress?: (items: MediaItem[], index?: number) => void;
84
84
  onPressUrl?: (url: string) => void;
85
85
  onLongPress?: (message: MessageItem, rect: MeasuredRect) => void;
@@ -2,6 +2,8 @@ import OpenIMSDK, {
2
2
  MessageStatus,
3
3
  type MessageItem,
4
4
  } from '@droppii/openim-rn-client-sdk';
5
+ import { DeviceEventEmitter } from 'react-native';
6
+ import { ChatEvent } from '../types/events';
5
7
 
6
8
  import type {
7
9
  Attachment,
@@ -320,6 +322,9 @@ export namespace AttachmentOrchestratorService {
320
322
  throw firstSendError;
321
323
  }
322
324
 
325
+ await new Promise((resolve) => setTimeout(resolve, 300));
326
+ DeviceEventEmitter.emit(ChatEvent.ScrollToBottom);
327
+
323
328
  return lastMsgId;
324
329
  }
325
330
  }
@@ -1,16 +1,30 @@
1
1
  import { create } from 'zustand';
2
- import { MessageType } from '@droppii/openim-rn-client-sdk';
2
+ import { DeviceEventEmitter } from 'react-native';
3
+ import OpenIMSDK, {
4
+ MessageType,
5
+ ViewType,
6
+ } from '@droppii/openim-rn-client-sdk';
7
+ import { ChatEvent } from '../types/events';
3
8
  import type { MessageItem } from '@droppii/openim-rn-client-sdk';
4
- import type { MessageStore } from '../types/chat';
9
+ import type {
10
+ IGetMessagesParams,
11
+ ISearchMessagesParams,
12
+ MessageStore,
13
+ } from '../types/chat';
5
14
  import { mergeMessages } from '../utils/message';
15
+ import { useConversationStore } from './conversation';
16
+
17
+ const PAGE_SIZE = 10;
6
18
 
7
19
  export const useMessageStore = create<MessageStore>()((set, get) => ({
8
20
  messages: [],
9
- hasMoreEarlier: false,
10
- hasMoreNewer: false,
11
-
21
+ hasMoreOld: true,
22
+ hasMoreNew: false,
23
+ initLoading: true,
24
+ moreOldLoading: false,
25
+ moreNewLoading: false,
12
26
  setMessages: (messages, hasMore) => {
13
- set({ messages, hasMoreEarlier: hasMore });
27
+ set({ messages, hasMoreOld: hasMore });
14
28
  },
15
29
 
16
30
  pushNewMessage: (message: MessageItem) => {
@@ -35,11 +49,163 @@ export const useMessageStore = create<MessageStore>()((set, get) => ({
35
49
  }));
36
50
  },
37
51
 
52
+ getMoreOldMessages: async ({
53
+ loadMore,
54
+ applicationType,
55
+ conversationId,
56
+ }: IGetMessagesParams) => {
57
+ if (!conversationId) return;
58
+ try {
59
+ if (loadMore) {
60
+ set({ moreOldLoading: true });
61
+ } else {
62
+ set({ initLoading: true });
63
+ }
64
+ const params = {
65
+ count: PAGE_SIZE,
66
+ startClientMsgID: loadMore
67
+ ? get().messages?.[0]?.clientMsgID || ''
68
+ : '',
69
+ conversationID: conversationId || '',
70
+ viewType: ViewType.History,
71
+ applicationType: applicationType,
72
+ };
73
+ const res = await OpenIMSDK.getAdvancedHistoryMessageListApp(params);
74
+ if (
75
+ conversationId === useConversationStore.getState().currentConversationId
76
+ ) {
77
+ set((state) => ({
78
+ messages: loadMore
79
+ ? mergeMessages(state.messages, res.messageList || [])
80
+ : res.messageList || [],
81
+ hasMoreOld: !res.isEnd,
82
+ initLoading: false,
83
+ moreOldLoading: false,
84
+ }));
85
+ }
86
+ } catch (error) {
87
+ console.log('Failed to get more old messages', error);
88
+ set({ initLoading: false, moreOldLoading: false });
89
+ }
90
+ },
91
+
92
+ getMoreNewMessages: async ({
93
+ loadMore,
94
+ applicationType,
95
+ conversationId,
96
+ }: IGetMessagesParams) => {
97
+ if (!conversationId) return;
98
+ try {
99
+ set({ moreNewLoading: true });
100
+ const params = {
101
+ count: PAGE_SIZE,
102
+ startClientMsgID: loadMore
103
+ ? get().messages?.[get().messages.length - 1]?.clientMsgID || ''
104
+ : '',
105
+ conversationID: conversationId || '',
106
+ applicationType,
107
+ viewType: ViewType.History,
108
+ };
109
+ const res =
110
+ await OpenIMSDK.getAdvancedHistoryMessageListReverseApp(params);
111
+ if (
112
+ conversationId === useConversationStore.getState().currentConversationId
113
+ ) {
114
+ set((state) => ({
115
+ messages: mergeMessages(state.messages, res.messageList || []),
116
+ hasMoreNew: !res.isEnd,
117
+ initLoading: false,
118
+ moreNewLoading: false,
119
+ }));
120
+ if (!loadMore) {
121
+ await new Promise((resolve) => setTimeout(resolve, 300));
122
+ DeviceEventEmitter.emit(ChatEvent.ScrollToBottom);
123
+ }
124
+ }
125
+ } catch (error) {
126
+ console.log('Failed to get more new messages', error);
127
+ set({ initLoading: false, moreNewLoading: false });
128
+ }
129
+ },
130
+
131
+ searchMessages: async ({
132
+ applicationType,
133
+ conversationId,
134
+ startClientMsgId,
135
+ }: ISearchMessagesParams) => {
136
+ if (!conversationId || !startClientMsgId) return;
137
+ try {
138
+ set({ initLoading: true });
139
+ const searchPrevParams = {
140
+ count: PAGE_SIZE,
141
+ startClientMsgID: startClientMsgId,
142
+ conversationID: conversationId || '',
143
+ viewType: ViewType.Search,
144
+ applicationType,
145
+ };
146
+ const searchNextParams = {
147
+ count: PAGE_SIZE,
148
+ startClientMsgID: startClientMsgId,
149
+ conversationID: conversationId || '',
150
+ viewType: ViewType.Search,
151
+ applicationType,
152
+ };
153
+ const searchCurrentParams = [
154
+ {
155
+ conversationID: conversationId || '',
156
+ clientMsgIDList: [startClientMsgId],
157
+ },
158
+ ];
159
+ const searchMessages =
160
+ await OpenIMSDK.findMessageList(searchCurrentParams);
161
+ const searchPrevRes =
162
+ await OpenIMSDK.getAdvancedHistoryMessageListApp(searchPrevParams);
163
+ const searchNextRes =
164
+ await OpenIMSDK.getAdvancedHistoryMessageListReverseApp(
165
+ searchNextParams
166
+ );
167
+ if (
168
+ conversationId === useConversationStore.getState().currentConversationId
169
+ ) {
170
+ const currentMessages =
171
+ searchMessages?.findResultItems?.find(
172
+ (item) => item.conversationID === conversationId
173
+ )?.messageList || [];
174
+ const newMessages = mergeMessages(
175
+ [
176
+ ...(searchPrevRes?.messageList || []),
177
+ ...currentMessages,
178
+ ...(searchNextRes?.messageList || []),
179
+ ],
180
+ []
181
+ );
182
+ set({
183
+ messages: newMessages,
184
+ hasMoreOld: !searchPrevRes.isEnd,
185
+ hasMoreNew: !searchNextRes.isEnd,
186
+ initLoading: false,
187
+ });
188
+ if (currentMessages?.length > 0) {
189
+ await new Promise((resolve) => setTimeout(resolve, 300));
190
+ DeviceEventEmitter.emit(ChatEvent.ScrollToMessage, {
191
+ clientMessageId: startClientMsgId,
192
+ });
193
+ }
194
+ }
195
+ } catch (error) {
196
+ console.error('Failed to search messages', error);
197
+ set({ initLoading: false });
198
+ }
199
+ },
200
+
38
201
  reset: () => {
39
202
  set({
40
203
  messages: [],
41
- hasMoreEarlier: false,
42
- hasMoreNewer: false,
204
+ hasMoreOld: true,
205
+ hasMoreNew: false,
206
+ initLoading: true,
207
+ moreOldLoading: false,
208
+ moreNewLoading: false,
43
209
  });
44
210
  },
45
211
  }));
package/src/types/chat.ts CHANGED
@@ -45,6 +45,7 @@ export type ChatProviderProps = PropsWithChildren<{
45
45
  applicationType: DChatApplicationType;
46
46
  getChatToken: () => Promise<GetOpenIMTokenResponse | null>;
47
47
  onFlashMessagePress?: (c: ConversationItem) => void;
48
+ enabled?: boolean;
48
49
  }>;
49
50
 
50
51
  export enum DChatApplicationType {
@@ -144,16 +145,34 @@ export interface IMessageItemEx {
144
145
  flow?: IRunConversationFlowPayload;
145
146
  }
146
147
 
148
+ export interface IGetMessagesParams {
149
+ loadMore: boolean;
150
+ applicationType: DChatApplicationType;
151
+ conversationId?: string;
152
+ }
153
+
154
+ export interface ISearchMessagesParams {
155
+ applicationType: DChatApplicationType;
156
+ conversationId?: string;
157
+ startClientMsgId: string;
158
+ }
159
+
147
160
  export interface MessageStore {
148
161
  messages: MessageItem[];
149
- hasMoreEarlier: boolean;
150
- hasMoreNewer: boolean;
162
+ hasMoreOld: boolean;
163
+ hasMoreNew: boolean;
164
+ initLoading: boolean;
165
+ moreOldLoading: boolean;
166
+ moreNewLoading: boolean;
151
167
  setMessages: (messages: MessageItem[], hasMore: boolean) => void;
152
168
  pushNewMessage: (message: MessageItem) => void;
153
169
  updateOneMessage: (
154
170
  message: Partial<MessageItem> & Pick<MessageItem, 'clientMsgID'>
155
171
  ) => void;
156
172
  deleteOneMessage: (clientMsgID: string) => void;
173
+ getMoreOldMessages: (params: IGetMessagesParams) => Promise<void>;
174
+ getMoreNewMessages: (params: IGetMessagesParams) => Promise<void>;
175
+ searchMessages: (params: ISearchMessagesParams) => Promise<void>;
157
176
  reset: () => void;
158
177
  }
159
178
 
@@ -0,0 +1,8 @@
1
+ export enum ChatEvent {
2
+ ScrollToMessage = 'chat:scroll_to_message',
3
+ ScrollToBottom = 'chat:scroll_to_bottom',
4
+ }
5
+
6
+ export interface ScrollToMessagePayload {
7
+ clientMessageId: string;
8
+ }
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  MessageType,
3
+ PeerType,
3
4
  SessionType,
4
5
  type ConversationItem,
5
6
  } from '@droppii/openim-rn-client-sdk';
@@ -70,3 +71,16 @@ export const generateContentBasedOnMessageType = (
70
71
  return '';
71
72
  }
72
73
  };
74
+
75
+ export const getBotId = (conversation?: ConversationItem) => {
76
+ if (conversation && conversation?.peerType === PeerType.Bot) {
77
+ try {
78
+ const id = JSON.parse(conversation?.ex ?? '{}')?.sessionInfo?.data?.botId;
79
+ return id;
80
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
81
+ } catch (_: any) {
82
+ return undefined;
83
+ }
84
+ }
85
+ return undefined;
86
+ };
@@ -1,155 +0,0 @@
1
- "use strict";
2
-
3
- import OpenIMSDK, { OpenIMEvent } from '@droppii/openim-rn-client-sdk';
4
- import { useCallback, useEffect, useRef, useState } from 'react';
5
- import { ChatMessageAPI } from "../services/message.js";
6
- import { belongsToConversation, hasNewHistoryMessages, mergeMessages } from "../utils/message.js";
7
- import { useMessageStore } from "../store/message.js";
8
- import { useUserStore } from "../store/user.js";
9
- import { useChatContext } from "../context/index.js";
10
- import { allSettled } from "../utils/promise.js";
11
- import { useSetIsShowFLashMessage } from "../context/global.js";
12
- export function useChatMessages({
13
- conversationId,
14
- enabled = true,
15
- pageSize = 20
16
- }) {
17
- const messages = useMessageStore(s => s.messages);
18
- const hasMoreEarlier = useMessageStore(s => s.hasMoreEarlier);
19
- const hasMoreNewer = useMessageStore(s => s.hasMoreNewer);
20
- const setMessages = useMessageStore(s => s.setMessages);
21
- const pushNewMessage = useMessageStore(s => s.pushNewMessage);
22
- const reset = useMessageStore(s => s.reset);
23
- const {
24
- applicationType
25
- } = useChatContext();
26
- const cachedUserId = useUserStore(s => s.user?.userID);
27
- const [currentUserId, setCurrentUserId] = useState(cachedUserId);
28
- const [isLoading, setIsLoading] = useState(false);
29
- const [isLoadingEarlier, setIsLoadingEarlier] = useState(false);
30
- const [isLoadingNewer, setIsLoadingNewer] = useState(false);
31
- const [error, setError] = useState(null);
32
- const conversationIdRef = useRef(conversationId);
33
- conversationIdRef.current = conversationId;
34
- const setIsShowFlashMessage = useSetIsShowFLashMessage();
35
- const fetchInitial = useCallback(async () => {
36
- if (!conversationId) return;
37
- setIsLoading(true);
38
- setError(null);
39
- try {
40
- // Fetch userId and history independently so an offline SDK state
41
- // doesn't block reading local SQLite history.
42
- const [historyResult, userIdResult] = await allSettled([ChatMessageAPI.fetchHistoryMessages(conversationId, {
43
- count: pageSize,
44
- applicationType
45
- }), ChatMessageAPI.getCurrentUserId()]);
46
- if (userIdResult.status === 'fulfilled') {
47
- setCurrentUserId(userIdResult.value);
48
- }
49
- if (historyResult.status === 'fulfilled') {
50
- const initialMessages = historyResult.value.messageList;
51
- setMessages(mergeMessages([], initialMessages), !historyResult.value.isEnd);
52
- ChatMessageAPI.markConversationAsRead(conversationId).catch(() => undefined);
53
- } else {
54
- // Fallback: try searchLocalMessages to verify local SQLite is accessible offline
55
- console.warn('[useChatMessages] getAdvancedHistoryMessageList failed, trying searchLocalMessages fallback:', historyResult.reason);
56
- const localResult = await ChatMessageAPI.searchLocalMessages(conversationId, {
57
- count: pageSize
58
- });
59
- const localMessages = (localResult?.searchResultItems ?? []).flatMap(item => item.messageList ?? []);
60
- console.log('[useChatMessages] searchLocalMessages fallback result:', localMessages.length, 'messages');
61
- if (localMessages.length > 0) {
62
- setMessages(mergeMessages([], localMessages), false);
63
- } else {
64
- throw historyResult.reason;
65
- }
66
- }
67
- } catch (err) {
68
- setError(err instanceof Error ? err : new Error(String(err)));
69
- } finally {
70
- setIsLoading(false);
71
- }
72
- }, [applicationType, conversationId, pageSize, setMessages]);
73
- const onLoadEarlier = useCallback(async () => {
74
- if (isLoadingEarlier || !hasMoreEarlier || !messages.length) return;
75
- setIsLoadingEarlier(true);
76
- setError(null);
77
- try {
78
- const history = await ChatMessageAPI.fetchHistoryMessages(conversationId, {
79
- count: pageSize,
80
- startClientMsgID: messages[0].clientMsgID
81
- });
82
- const incoming = history.messageList;
83
- const hasNew = hasNewHistoryMessages(messages, incoming);
84
- if (hasNew) {
85
- setMessages(mergeMessages(messages, incoming), !history.isEnd && hasNew);
86
- } else {
87
- setMessages(messages, false);
88
- }
89
- } catch (err) {
90
- setError(err instanceof Error ? err : new Error(String(err)));
91
- } finally {
92
- setIsLoadingEarlier(false);
93
- }
94
- }, [conversationId, hasMoreEarlier, isLoadingEarlier, messages, pageSize, setMessages]);
95
- const onLoadNewer = useCallback(async () => {
96
- if (isLoadingNewer || !hasMoreNewer || !messages.length) return;
97
- setIsLoadingNewer(true);
98
- setError(null);
99
- try {
100
- const history = await ChatMessageAPI.fetchHistoryMessages(conversationId, {
101
- count: pageSize,
102
- startClientMsgID: messages[messages.length - 1].clientMsgID
103
- });
104
- const incoming = history.messageList;
105
- const hasNew = incoming.length > 0;
106
- if (hasNew) {
107
- setMessages(mergeMessages(messages, incoming), !history.isEnd && hasNew);
108
- }
109
- } catch (err) {
110
- setError(err instanceof Error ? err : new Error(String(err)));
111
- } finally {
112
- setIsLoadingNewer(false);
113
- }
114
- }, [conversationId, hasMoreNewer, isLoadingNewer, messages, pageSize, setMessages]);
115
- const appendIncomingMessages = useCallback(incoming => {
116
- console.log('[Listener] OnRecvNewMessages', {
117
- total: incoming.length,
118
- conversationId: conversationIdRef.current,
119
- clientMsgIDs: incoming.map(m => m.clientMsgID)
120
- });
121
- const relevant = incoming.filter(message => belongsToConversation(message, conversationIdRef.current));
122
- if (!relevant.length) return;
123
- relevant.forEach(msg => pushNewMessage(msg));
124
- ChatMessageAPI.markConversationAsRead(conversationIdRef.current).catch(() => undefined);
125
- }, [pushNewMessage]);
126
- useEffect(() => {
127
- reset();
128
- if (!enabled || !conversationId) return;
129
- fetchInitial();
130
- }, [conversationId, enabled, fetchInitial, reset]);
131
- useEffect(() => {
132
- if (!enabled || !conversationId) return;
133
- setIsShowFlashMessage(false);
134
- const handleNewMessages = incoming => appendIncomingMessages(incoming);
135
- OpenIMSDK.on(OpenIMEvent.OnRecvNewMessages, handleNewMessages);
136
- return () => {
137
- setIsShowFlashMessage(true);
138
- OpenIMSDK.off(OpenIMEvent.OnRecvNewMessages, handleNewMessages);
139
- };
140
- }, [appendIncomingMessages, conversationId, enabled, setIsShowFlashMessage]);
141
- return {
142
- messages,
143
- currentUserId,
144
- isLoading,
145
- isLoadingEarlier,
146
- hasMoreEarlier,
147
- isLoadingNewer,
148
- hasMoreNewer,
149
- error,
150
- onLoadEarlier,
151
- onLoadNewer,
152
- refresh: fetchInitial
153
- };
154
- }
155
- //# sourceMappingURL=useChatMessages.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["OpenIMSDK","OpenIMEvent","useCallback","useEffect","useRef","useState","ChatMessageAPI","belongsToConversation","hasNewHistoryMessages","mergeMessages","useMessageStore","useUserStore","useChatContext","allSettled","useSetIsShowFLashMessage","useChatMessages","conversationId","enabled","pageSize","messages","s","hasMoreEarlier","hasMoreNewer","setMessages","pushNewMessage","reset","applicationType","cachedUserId","user","userID","currentUserId","setCurrentUserId","isLoading","setIsLoading","isLoadingEarlier","setIsLoadingEarlier","isLoadingNewer","setIsLoadingNewer","error","setError","conversationIdRef","current","setIsShowFlashMessage","fetchInitial","historyResult","userIdResult","fetchHistoryMessages","count","getCurrentUserId","status","value","initialMessages","messageList","isEnd","markConversationAsRead","catch","undefined","console","warn","reason","localResult","searchLocalMessages","localMessages","searchResultItems","flatMap","item","log","length","err","Error","String","onLoadEarlier","history","startClientMsgID","clientMsgID","incoming","hasNew","onLoadNewer","appendIncomingMessages","total","clientMsgIDs","map","m","relevant","filter","message","forEach","msg","handleNewMessages","on","OnRecvNewMessages","off","refresh"],"sourceRoot":"../../../src","sources":["hooks/useChatMessages.ts"],"mappings":"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","ignoreList":[]}
@@ -1,21 +0,0 @@
1
- import { type MessageItem } from '@droppii/openim-rn-client-sdk';
2
- type UseChatMessagesOptions = {
3
- conversationId: string;
4
- enabled?: boolean;
5
- pageSize?: number;
6
- };
7
- export declare function useChatMessages({ conversationId, enabled, pageSize, }: UseChatMessagesOptions): {
8
- messages: MessageItem[];
9
- currentUserId: string;
10
- isLoading: boolean;
11
- isLoadingEarlier: boolean;
12
- hasMoreEarlier: boolean;
13
- isLoadingNewer: boolean;
14
- hasMoreNewer: boolean;
15
- error: Error;
16
- onLoadEarlier: () => Promise<void>;
17
- onLoadNewer: () => Promise<void>;
18
- refresh: () => Promise<void>;
19
- };
20
- export {};
21
- //# sourceMappingURL=useChatMessages.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useChatMessages.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useChatMessages.ts"],"names":[],"mappings":"AAAA,OAAkB,EAEhB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAcvC,KAAK,sBAAsB,GAAG;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAC9B,cAAc,EACd,OAAc,EACd,QAAa,GACd,EAAE,sBAAsB;;;;;;;;;;;;EA0NxB"}