@droppii-org/chat-mobile 0.2.37 → 0.2.39

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 (150) hide show
  1. package/lib/module/components/ThreadCard/ThreadCard.js +2 -1
  2. package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
  3. package/lib/module/components/messages/linkMessage/index.js +1 -10
  4. package/lib/module/components/messages/linkMessage/index.js.map +1 -1
  5. package/lib/module/components/messages/quotedMessage/index.js +177 -0
  6. package/lib/module/components/messages/quotedMessage/index.js.map +1 -0
  7. package/lib/module/context/ChatContext.js +26 -22
  8. package/lib/module/context/ChatContext.js.map +1 -1
  9. package/lib/module/context/ChatDetailContext.js +7 -4
  10. package/lib/module/context/ChatDetailContext.js.map +1 -1
  11. package/lib/module/core/useChatListener.js +15 -6
  12. package/lib/module/core/useChatListener.js.map +1 -1
  13. package/lib/module/core/useUserListener.js +12 -21
  14. package/lib/module/core/useUserListener.js.map +1 -1
  15. package/lib/module/hooks/message/useSendMessage.js +26 -4
  16. package/lib/module/hooks/message/useSendMessage.js.map +1 -1
  17. package/lib/module/hooks/useChatMessages.js.map +1 -1
  18. package/lib/module/index.js +0 -7
  19. package/lib/module/index.js.map +1 -1
  20. package/lib/module/screens/chat-detail/ChatComposer.js +2 -1
  21. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  22. package/lib/module/screens/chat-detail/ChatCurrentQuotedMessage.js +144 -0
  23. package/lib/module/screens/chat-detail/ChatCurrentQuotedMessage.js.map +1 -0
  24. package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
  25. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  26. package/lib/module/screens/chat-detail/PinnedMessageBar.js +4 -2
  27. package/lib/module/screens/chat-detail/PinnedMessageBar.js.map +1 -1
  28. package/lib/module/screens/chat-detail/PinnedMessagesSheet.js.map +1 -1
  29. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +2 -1
  30. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  31. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxMenu.js +9 -1
  32. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxMenu.js.map +1 -1
  33. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js +11 -1
  34. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js.map +1 -1
  35. package/lib/module/screens/chat-detail/messageToolbox/messageToolbox.utils.js +5 -2
  36. package/lib/module/screens/chat-detail/messageToolbox/messageToolbox.utils.js.map +1 -1
  37. package/lib/module/screens/inbox/Inbox.js +1 -5
  38. package/lib/module/screens/inbox/Inbox.js.map +1 -1
  39. package/lib/module/services/apis.js +0 -3
  40. package/lib/module/services/apis.js.map +1 -1
  41. package/lib/module/services/message.js.map +1 -1
  42. package/lib/module/store/message.js.map +1 -1
  43. package/lib/module/store/pinnedMessage.js.map +1 -1
  44. package/lib/module/store/user.js +2 -3
  45. package/lib/module/store/user.js.map +1 -1
  46. package/lib/module/translation/resources/i18n.js +5 -1
  47. package/lib/module/translation/resources/i18n.js.map +1 -1
  48. package/lib/module/types/auth.js +0 -7
  49. package/lib/module/types/auth.js.map +1 -1
  50. package/lib/module/types/chat.js +12 -0
  51. package/lib/module/types/chat.js.map +1 -1
  52. package/lib/module/utils/legendListMessage.js +1 -0
  53. package/lib/module/utils/legendListMessage.js.map +1 -1
  54. package/lib/module/utils/message.js.map +1 -1
  55. package/lib/module/utils/messageUtils.js +47 -6
  56. package/lib/module/utils/messageUtils.js.map +1 -1
  57. package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
  58. package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
  59. package/lib/typescript/src/components/messages/quotedMessage/index.d.ts +7 -0
  60. package/lib/typescript/src/components/messages/quotedMessage/index.d.ts.map +1 -0
  61. package/lib/typescript/src/components/messages/types.d.ts +2 -2
  62. package/lib/typescript/src/components/messages/types.d.ts.map +1 -1
  63. package/lib/typescript/src/context/ChatContext.d.ts.map +1 -1
  64. package/lib/typescript/src/context/ChatDetailContext.d.ts.map +1 -1
  65. package/lib/typescript/src/core/useChatListener.d.ts.map +1 -1
  66. package/lib/typescript/src/core/useUserListener.d.ts.map +1 -1
  67. package/lib/typescript/src/hooks/message/usePinMessage.d.ts +1 -1
  68. package/lib/typescript/src/hooks/message/useSendMessage.d.ts +2 -1
  69. package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
  70. package/lib/typescript/src/hooks/useChatMessages.d.ts +2 -2
  71. package/lib/typescript/src/hooks/useChatMessages.d.ts.map +1 -1
  72. package/lib/typescript/src/index.d.ts +1 -1
  73. package/lib/typescript/src/index.d.ts.map +1 -1
  74. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  75. package/lib/typescript/src/screens/chat-detail/ChatCurrentQuotedMessage.d.ts +2 -0
  76. package/lib/typescript/src/screens/chat-detail/ChatCurrentQuotedMessage.d.ts.map +1 -0
  77. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
  78. package/lib/typescript/src/screens/chat-detail/PinnedMessageBar.d.ts +2 -2
  79. package/lib/typescript/src/screens/chat-detail/PinnedMessageBar.d.ts.map +1 -1
  80. package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheet.d.ts +1 -2
  81. package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheet.d.ts.map +1 -1
  82. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +2 -3
  83. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  84. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.d.ts +6 -4
  85. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.d.ts.map +1 -1
  86. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.d.ts +4 -4
  87. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.d.ts.map +1 -1
  88. package/lib/typescript/src/screens/chat-detail/messageToolbox/messageToolbox.utils.d.ts +5 -3
  89. package/lib/typescript/src/screens/chat-detail/messageToolbox/messageToolbox.utils.d.ts.map +1 -1
  90. package/lib/typescript/src/screens/chat-detail/messageToolbox/types.d.ts +2 -2
  91. package/lib/typescript/src/screens/chat-detail/messageToolbox/types.d.ts.map +1 -1
  92. package/lib/typescript/src/screens/chat-detail/types.d.ts +5 -5
  93. package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
  94. package/lib/typescript/src/screens/inbox/Inbox.d.ts.map +1 -1
  95. package/lib/typescript/src/services/apis.d.ts +0 -1
  96. package/lib/typescript/src/services/apis.d.ts.map +1 -1
  97. package/lib/typescript/src/services/message.d.ts +1 -2
  98. package/lib/typescript/src/services/message.d.ts.map +1 -1
  99. package/lib/typescript/src/store/message.d.ts.map +1 -1
  100. package/lib/typescript/src/store/pinnedMessage.d.ts +4 -4
  101. package/lib/typescript/src/store/pinnedMessage.d.ts.map +1 -1
  102. package/lib/typescript/src/store/user.d.ts +4 -4
  103. package/lib/typescript/src/store/user.d.ts.map +1 -1
  104. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  105. package/lib/typescript/src/types/auth.d.ts +0 -5
  106. package/lib/typescript/src/types/auth.d.ts.map +1 -1
  107. package/lib/typescript/src/types/chat.d.ts +16 -36
  108. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  109. package/lib/typescript/src/utils/legendListMessage.d.ts +4 -4
  110. package/lib/typescript/src/utils/legendListMessage.d.ts.map +1 -1
  111. package/lib/typescript/src/utils/message.d.ts +4 -5
  112. package/lib/typescript/src/utils/message.d.ts.map +1 -1
  113. package/lib/typescript/src/utils/messageUtils.d.ts +16 -7
  114. package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -1
  115. package/package.json +2 -2
  116. package/src/components/ThreadCard/ThreadCard.tsx +5 -1
  117. package/src/components/messages/linkMessage/index.tsx +1 -11
  118. package/src/components/messages/quotedMessage/index.tsx +201 -0
  119. package/src/components/messages/types.ts +2 -2
  120. package/src/context/ChatContext.tsx +30 -25
  121. package/src/context/ChatDetailContext.tsx +9 -3
  122. package/src/core/useChatListener.ts +29 -7
  123. package/src/core/useUserListener.ts +9 -25
  124. package/src/hooks/message/useSendMessage.ts +25 -4
  125. package/src/hooks/useChatMessages.ts +4 -6
  126. package/src/index.tsx +5 -6
  127. package/src/screens/chat-detail/ChatComposer.tsx +2 -0
  128. package/src/screens/chat-detail/ChatCurrentQuotedMessage.tsx +153 -0
  129. package/src/screens/chat-detail/ChatDetail.tsx +3 -2
  130. package/src/screens/chat-detail/ChatListLegend.tsx +3 -3
  131. package/src/screens/chat-detail/PinnedMessageBar.tsx +52 -49
  132. package/src/screens/chat-detail/PinnedMessagesSheet.tsx +7 -8
  133. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +4 -4
  134. package/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.tsx +15 -3
  135. package/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.tsx +15 -6
  136. package/src/screens/chat-detail/messageToolbox/messageToolbox.utils.ts +21 -12
  137. package/src/screens/chat-detail/messageToolbox/types.ts +2 -2
  138. package/src/screens/chat-detail/types.ts +5 -5
  139. package/src/screens/inbox/Inbox.tsx +1 -5
  140. package/src/services/apis.ts +0 -4
  141. package/src/services/message.ts +1 -2
  142. package/src/store/message.ts +3 -3
  143. package/src/store/pinnedMessage.ts +4 -4
  144. package/src/store/user.ts +5 -5
  145. package/src/translation/resources/i18n.ts +4 -0
  146. package/src/types/auth.ts +0 -6
  147. package/src/types/chat.ts +18 -40
  148. package/src/utils/legendListMessage.ts +4 -5
  149. package/src/utils/message.ts +10 -11
  150. package/src/utils/messageUtils.ts +76 -15
@@ -1,7 +1,7 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { MediaItem } from '../../hooks/useMediaViewer';
3
- import type { DMessageItem } from '../../types/chat';
4
3
  import type { MeasuredRect } from './messageToolbox/types';
4
+ import type { MessageItem } from '@droppii/openim-rn-client-sdk';
5
5
 
6
6
  export type DChatActionIconProvider = 'MaterialCommunityIcons' | 'DroppiiNew';
7
7
 
@@ -70,9 +70,9 @@ export interface ChatComposerProps {
70
70
  }
71
71
 
72
72
  export interface ChatListProps {
73
- messages?: DMessageItem[];
73
+ messages?: MessageItem[];
74
74
  currentUserId?: string;
75
- customMessageItemFactory?: (item: DMessageItem) => ReactNode;
75
+ customMessageItemFactory?: (item: MessageItem) => ReactNode;
76
76
  onLoadEarlier?: () => void;
77
77
  isLoading?: boolean;
78
78
  isLoadingEarlier?: boolean;
@@ -82,7 +82,7 @@ export interface ChatListProps {
82
82
  hasMoreNewer?: boolean;
83
83
  onMediaPress?: (items: MediaItem[], index?: number) => void;
84
84
  onPressUrl?: (url: string) => void;
85
- onLongPress?: (message: DMessageItem, rect: MeasuredRect) => void;
85
+ onLongPress?: (message: MessageItem, rect: MeasuredRect) => void;
86
86
  }
87
87
 
88
88
  export interface ChatDetailProps extends Omit<
@@ -96,6 +96,6 @@ export interface ChatDetailProps extends Omit<
96
96
  enabled?: boolean;
97
97
  showAddMember?: boolean;
98
98
  onPressUrl?: (url: string) => void;
99
- customMessageItemFactory?: (item: DMessageItem) => ReactNode;
99
+ customMessageItemFactory?: (item: MessageItem) => ReactNode;
100
100
  pannelActions?: DChatPannelAction[];
101
101
  }
@@ -3,8 +3,6 @@ import { StyleSheet } from 'react-native';
3
3
  import { TabView } from 'react-native-tab-view';
4
4
  import { KContainer, KImage, KLabel, KColors } from '@droppii/libs';
5
5
  import { MessagesTab } from './MessagesTab';
6
- import { useUserStore } from '../../store';
7
- import { LoginStatus } from '@droppii/openim-rn-client-sdk';
8
6
 
9
7
  interface InboxProps {
10
8
  onPressThread?: (item: string) => void;
@@ -17,7 +15,6 @@ type TabRoute = { key: string; title: string };
17
15
 
18
16
  const Inbox = memo(
19
17
  ({ onPressThread, onPressSearch, onPressEdit, onPressGroup }: InboxProps) => {
20
- const connectStatus = useUserStore((state) => state.connectStatus);
21
18
  const [index, setIndex] = useState(0);
22
19
  const [routes] = useState<TabRoute[]>([
23
20
  { key: 'messages', title: 'Tin nhắn' },
@@ -25,13 +22,12 @@ const Inbox = memo(
25
22
 
26
23
  const renderScene = useCallback(
27
24
  ({ route }: { route: TabRoute }) => {
28
- if (connectStatus !== LoginStatus.Logged) return null;
29
25
  if (route.key === 'messages') {
30
26
  return <MessagesTab onPressThread={onPressThread} />;
31
27
  }
32
28
  return null;
33
29
  },
34
- [onPressThread, connectStatus]
30
+ [onPressThread]
35
31
  );
36
32
 
37
33
  const renderTabBar = useCallback(
@@ -17,8 +17,4 @@ export namespace ChatAPI {
17
17
  useConversationStore.getState().reset();
18
18
  return OpenIMSDK.logout(operationID);
19
19
  };
20
-
21
- export const getUser = async (operationID?: string | undefined) => {
22
- return OpenIMSDK.getSelfUserInfo(operationID);
23
- };
24
20
  }
@@ -3,7 +3,6 @@ import OpenIMSDK, {
3
3
  type AdvancedGetMessageResult,
4
4
  type MessageItem,
5
5
  } from '@droppii/openim-rn-client-sdk';
6
- import type { DMessageItem } from '../types/chat';
7
6
  import { useConversationStore } from '../store';
8
7
  import { getReceiverId } from '../utils/message';
9
8
 
@@ -34,7 +33,7 @@ export namespace ChatMessageAPI {
34
33
 
35
34
  export async function sendTextMessage(params: {
36
35
  text: string;
37
- }): Promise<DMessageItem> {
36
+ }): Promise<MessageItem> {
38
37
  const currentConversation = useConversationStore
39
38
  .getState()
40
39
  .getCurrentConversation();
@@ -1,7 +1,7 @@
1
1
  import { create } from 'zustand';
2
2
  import { MessageType } from '@droppii/openim-rn-client-sdk';
3
3
  import type { MessageItem } from '@droppii/openim-rn-client-sdk';
4
- import type { DMessageItem, MessageStore } from '../types/chat';
4
+ import type { MessageStore } from '../types/chat';
5
5
  import { mergeMessages } from '../utils/message';
6
6
 
7
7
  export const useMessageStore = create<MessageStore>()((set, get) => ({
@@ -15,7 +15,7 @@ export const useMessageStore = create<MessageStore>()((set, get) => ({
15
15
 
16
16
  pushNewMessage: (message: MessageItem) => {
17
17
  set((state) => ({
18
- messages: mergeMessages(state.messages, [message as DMessageItem]),
18
+ messages: mergeMessages(state.messages, [message]),
19
19
  }));
20
20
  },
21
21
 
@@ -25,7 +25,7 @@ export const useMessageStore = create<MessageStore>()((set, get) => ({
25
25
  (msg) => msg.clientMsgID === message.clientMsgID
26
26
  );
27
27
  if (idx < 0) return;
28
- tmpList[idx] = { ...tmpList[idx]!, ...message } as DMessageItem;
28
+ tmpList[idx] = { ...tmpList[idx]!, ...message };
29
29
  set({ messages: tmpList });
30
30
  },
31
31
 
@@ -1,11 +1,11 @@
1
+ import type { MessageItem } from '@droppii/openim-rn-client-sdk';
1
2
  import { create } from 'zustand';
2
- import type { DMessageItem } from '../types/chat';
3
3
 
4
4
  export interface PinnedMessageStore {
5
- messages: DMessageItem[];
5
+ messages: MessageItem[];
6
6
  totalCount: number;
7
- setMessages: (messages: DMessageItem[], totalCount: number) => void;
8
- addMessage: (message: DMessageItem) => void;
7
+ setMessages: (messages: MessageItem[], totalCount: number) => void;
8
+ addMessage: (message: MessageItem) => void;
9
9
  removeMessage: (clientMsgID: string) => void;
10
10
  reset: () => void;
11
11
  }
package/src/store/user.ts CHANGED
@@ -1,18 +1,18 @@
1
1
  import { create } from 'zustand';
2
- import { LoginStatus, type SelfUserInfo } from '@droppii/openim-rn-client-sdk';
3
- import { SyncStatus } from '../types/auth';
2
+ import { type SelfUserInfo } from '@droppii/openim-rn-client-sdk';
3
+ import { ConnectStatus, SyncStatus } from '../types/chat';
4
4
 
5
5
  export interface UserStore {
6
6
  user?: SelfUserInfo;
7
7
  setUser: (user: SelfUserInfo) => void;
8
- connectStatus: LoginStatus;
9
- updateConnectStatus: (status: LoginStatus) => void;
8
+ connectStatus: ConnectStatus;
9
+ updateConnectStatus: (status: ConnectStatus) => void;
10
10
  syncStatus: SyncStatus;
11
11
  updateSyncStatus: (status: SyncStatus) => void;
12
12
  }
13
13
 
14
14
  export const useUserStore = create<UserStore>()((set) => ({
15
- connectStatus: LoginStatus.Logout,
15
+ connectStatus: ConnectStatus.Disconnected,
16
16
  syncStatus: SyncStatus.Loading,
17
17
  setUser(user) {
18
18
  set({ user });
@@ -76,6 +76,10 @@ const i18nKey: Record<string, string> = {
76
76
  'send_order': 'Gửi đơn hàng',
77
77
  'send_product': 'Gửi sản phẩm',
78
78
  'create_appointment': 'Tạo lịch hẹn',
79
+ 'chat:reply_message': 'Trả lời',
80
+ 'chat:reply_to': 'Trả lời {{name}}',
81
+ 'yourself': 'chính mình',
82
+ 'you': 'Bạn',
79
83
  };
80
84
 
81
85
  export default {
package/src/types/auth.ts CHANGED
@@ -18,9 +18,3 @@ export type GetOpenIMTokenResponse = {
18
18
  token: string;
19
19
  expiresIn: number;
20
20
  };
21
-
22
- export enum SyncStatus {
23
- Loading = 0,
24
- Success = 1,
25
- Failed = 2,
26
- }
package/src/types/chat.ts CHANGED
@@ -37,6 +37,7 @@ export interface ChatContextType {
37
37
  onPressFlashMessage?: (message: ConversationItem) => void;
38
38
  isShowFLashMessage: boolean;
39
39
  setIsShowFLashMessage: (value: boolean) => void;
40
+ handleLoginSdk: () => void;
40
41
  }
41
42
 
42
43
  export type ChatProviderProps = PropsWithChildren<{
@@ -98,6 +99,18 @@ export interface DBotStatus {
98
99
  botSupportPlatform: unknown | null;
99
100
  }
100
101
 
102
+ export enum SyncStatus {
103
+ Loading = 0,
104
+ Success = 1,
105
+ Failed = 2,
106
+ }
107
+
108
+ export enum ConnectStatus {
109
+ Disconnected = 0,
110
+ Connected = 1,
111
+ Connecting = 2,
112
+ }
113
+
101
114
  export interface DConversationPeerUser {
102
115
  id: string;
103
116
  username?: string;
@@ -119,42 +132,6 @@ export interface DConversationQueryParams {
119
132
  pageSize: number;
120
133
  }
121
134
 
122
- export interface DMessageItem extends MessageItem {
123
- isInternal?: boolean;
124
- atUserIDList?: unknown;
125
- attachedInfo?: 'null';
126
- options?: DMessageOption;
127
- isPinned?: boolean;
128
- pinnedByUserID?: string;
129
- pinnedTime?: number;
130
- }
131
-
132
- export interface DMessageOption {
133
- conversationUpdate: boolean;
134
- offlinePush: boolean;
135
- senderConversationUpdate: boolean;
136
- unreadCount: boolean;
137
- }
138
-
139
- export interface DMessagePushInfo {
140
- title: string;
141
- desc: string;
142
- /**
143
- * @instance DMessagePushInfoEx
144
- */
145
- ex: string;
146
- signalInfo: string;
147
- iospushSound: 'default';
148
- iosbadgeCount: boolean;
149
- }
150
-
151
- export interface DMessagePushInfoEx {
152
- icon: string; // url
153
- conversationId: string;
154
- title: string;
155
- desc: string;
156
- }
157
-
158
135
  export interface IMessageItemEx {
159
136
  applicationType: DChatApplicationType;
160
137
  sessionId?: string;
@@ -168,13 +145,13 @@ export interface IMessageItemEx {
168
145
  }
169
146
 
170
147
  export interface MessageStore {
171
- messages: DMessageItem[];
148
+ messages: MessageItem[];
172
149
  hasMoreEarlier: boolean;
173
150
  hasMoreNewer: boolean;
174
- setMessages: (messages: DMessageItem[], hasMore: boolean) => void;
151
+ setMessages: (messages: MessageItem[], hasMore: boolean) => void;
175
152
  pushNewMessage: (message: MessageItem) => void;
176
153
  updateOneMessage: (
177
- message: Partial<DMessageItem> & Pick<MessageItem, 'clientMsgID'>
154
+ message: Partial<MessageItem> & Pick<MessageItem, 'clientMsgID'>
178
155
  ) => void;
179
156
  deleteOneMessage: (clientMsgID: string) => void;
180
157
  reset: () => void;
@@ -182,12 +159,13 @@ export interface MessageStore {
182
159
 
183
160
  export interface ChatDetailContextType {
184
161
  conversationFlow?: IConversationFlow;
185
- refetchConversationFlow: () => void;
186
162
  isBotConversation: boolean;
187
163
  setConverationFlowStep: (step?: IConversationFlowStep) => void;
188
164
  flowState?: DFlowState;
189
165
  runButtonContext: (stringContext: DFlowContext) => Promise<boolean>;
190
166
  conversation?: ConversationItem;
167
+ quotedMessage?: MessageItem;
168
+ setQuotedMessage: (item?: MessageItem) => void;
191
169
  }
192
170
 
193
171
  export interface ChatDetailProviderProps extends PropsWithChildren {}
@@ -1,10 +1,9 @@
1
- import { MessageType } from '@droppii/openim-rn-client-sdk';
2
- import type { DMessageItem } from '../types/chat';
1
+ import { MessageType, type MessageItem } from '@droppii/openim-rn-client-sdk';
3
2
 
4
3
  /**
5
4
  * Extract message text based on content type
6
5
  */
7
- export const getMessageText = (message: DMessageItem): string => {
6
+ export const getMessageText = (message: MessageItem): string => {
8
7
  switch (message.contentType) {
9
8
  case MessageType.TextMessage:
10
9
  return message.textElem?.content ?? message.content;
@@ -49,7 +48,7 @@ export interface PrecomputedMessageData {
49
48
  * Returns: Map of messageId -> {dayStart, messageType, createdAt}
50
49
  */
51
50
  export const precomputeLegendListData = (
52
- messages: DMessageItem[]
51
+ messages: MessageItem[]
53
52
  ): Map<string, PrecomputedMessageData> => {
54
53
  const dataMap = new Map<string, PrecomputedMessageData>();
55
54
  let lastDay: number | null = null;
@@ -81,7 +80,7 @@ export const precomputeLegendListData = (
81
80
  * Kept for backward compatibility
82
81
  */
83
82
  export const computeDayStarts = (
84
- messages: DMessageItem[]
83
+ messages: MessageItem[]
85
84
  ): Map<string, boolean> => {
86
85
  const dayStartMap = new Map<string, boolean>();
87
86
  let lastDay: number | null = null;
@@ -4,20 +4,19 @@ import {
4
4
  type ConversationItem,
5
5
  type MessageItem,
6
6
  } from '@droppii/openim-rn-client-sdk';
7
- import { type DMessageItem } from '../types/chat';
8
7
  import { getConversationID } from './conversation';
9
8
 
10
- const getMessageTime = (message: DMessageItem) =>
9
+ const getMessageTime = (message: MessageItem) =>
11
10
  message.sendTime || message.createTime || 0;
12
11
 
13
- const getMessageKey = (message: DMessageItem) =>
12
+ const getMessageKey = (message: MessageItem) =>
14
13
  message.clientMsgID || message.serverMsgID;
15
14
 
16
15
  export const mergeMessages = (
17
- current: DMessageItem[],
18
- incoming: DMessageItem[]
19
- ): DMessageItem[] => {
20
- const map = new Map<string, DMessageItem>();
16
+ current: MessageItem[],
17
+ incoming: MessageItem[]
18
+ ): MessageItem[] => {
19
+ const map = new Map<string, MessageItem>();
21
20
 
22
21
  for (const message of [...current, ...incoming]) {
23
22
  const key = getMessageKey(message);
@@ -54,7 +53,7 @@ export type HistoryPaginationAnchor = {
54
53
 
55
54
  export const resolveHistoryLastMinSeq = (
56
55
  history: { lastMinSeq?: number },
57
- fallbackMessage?: DMessageItem
56
+ fallbackMessage?: MessageItem
58
57
  ): number => {
59
58
  if (history.lastMinSeq != null) {
60
59
  return history.lastMinSeq;
@@ -64,7 +63,7 @@ export const resolveHistoryLastMinSeq = (
64
63
  };
65
64
 
66
65
  export const getHistoryPaginationAnchor = (
67
- messages: DMessageItem[]
66
+ messages: MessageItem[]
68
67
  ): HistoryPaginationAnchor | null => {
69
68
  if (!messages.length) {
70
69
  return null;
@@ -86,8 +85,8 @@ export const getHistoryPaginationAnchor = (
86
85
  };
87
86
 
88
87
  export const hasNewHistoryMessages = (
89
- current: DMessageItem[],
90
- incoming: DMessageItem[]
88
+ current: MessageItem[],
89
+ incoming: MessageItem[]
91
90
  ): boolean => {
92
91
  const currentKeys = new Set(
93
92
  current.map((message) => getMessageKey(message)).filter(Boolean)
@@ -6,17 +6,18 @@ import {
6
6
  MessageType,
7
7
  PeerType,
8
8
  type ConversationItem,
9
+ type MessageItem,
9
10
  } from '@droppii/openim-rn-client-sdk';
10
- import { type DMessageItem } from '../types/chat';
11
- import type { IUrlMetadata } from '../types/common';
12
11
  import { formatDuration } from './dateTimeUtils';
13
12
  import { getFileIcon, getMimeType } from './imageUtils';
14
13
  import { trans } from '../translation';
14
+ import type { IUrlMetadata } from '../types/common';
15
+ import type { TextProps } from 'react-native';
15
16
 
16
- export const isMessageRevoked = (message: DMessageItem): boolean =>
17
+ export const isMessageRevoked = (message: MessageItem): boolean =>
17
18
  message.contentType === MessageType.RevokeMessage;
18
19
 
19
- export const extractTextContent = (message: DMessageItem): string => {
20
+ export const extractTextContent = (message: MessageItem): string => {
20
21
  if (message.textElem?.content) return message.textElem.content;
21
22
  try {
22
23
  const parsed = JSON.parse(message.content) as { content?: string };
@@ -26,7 +27,8 @@ export const extractTextContent = (message: DMessageItem): string => {
26
27
  }
27
28
  };
28
29
 
29
- export const getMessagePreview = (message: DMessageItem): string => {
30
+ export const getMessagePreview = (message?: MessageItem): string => {
31
+ if (!message) return '';
30
32
  // Handle standard message types
31
33
  switch (message.contentType) {
32
34
  case MessageType.TextMessage:
@@ -45,14 +47,13 @@ export const getMessagePreview = (message: DMessageItem): string => {
45
47
  return '[Video]';
46
48
  }
47
49
 
48
- case MessageType.FileMessage:
49
- try {
50
- const fileData = JSON.parse(message.content);
51
- const fileName = fileData.fileName || fileData.name || 'File';
50
+ case MessageType.FileMessage: {
51
+ const fileName = message?.fileElem?.fileName;
52
+ if (fileName) {
52
53
  return `[File] ${fileName}`;
53
- } catch {
54
- return '[File]';
55
54
  }
55
+ return '[File]';
56
+ }
56
57
 
57
58
  case MessageType.MergeMessage:
58
59
  // Show image count for merged messages containing images
@@ -78,9 +79,11 @@ export const getMessagePreview = (message: DMessageItem): string => {
78
79
  return urlText ? urlText : '';
79
80
 
80
81
  case MessageType.AtTextMessage:
81
- case MessageType.QuoteMessage:
82
82
  return extractTextContent(message);
83
83
 
84
+ case MessageType.QuoteMessage:
85
+ return message?.quoteElem?.text || '';
86
+
84
87
  case MessageType.RevokeMessage:
85
88
  return trans('msg_type_revoke');
86
89
 
@@ -94,6 +97,27 @@ export const getMessagePreview = (message: DMessageItem): string => {
94
97
  }
95
98
  };
96
99
 
100
+ export const getMessagePreviewTextProps = (
101
+ message?: MessageItem
102
+ ): TextProps => {
103
+ if (!message) return {};
104
+ switch (message.contentType) {
105
+ case MessageType.FileMessage:
106
+ return {
107
+ ellipsizeMode: 'middle',
108
+ };
109
+ default:
110
+ return {};
111
+ }
112
+ };
113
+
114
+ export const getMessagePreviewParts = (
115
+ message?: MessageItem
116
+ ): { text: string; textProps: TextProps } => ({
117
+ text: getMessagePreview(message),
118
+ textProps: getMessagePreviewTextProps(message),
119
+ });
120
+
97
121
  export type PinnedMessageMediaType = 'image' | 'video' | 'file' | 'text';
98
122
 
99
123
  export interface PinnedMessagePreview {
@@ -110,7 +134,7 @@ const getImageUrl = (pictureElem: any): string | undefined =>
110
134
 
111
135
  // Link messages carry their rich-preview metadata (title/description/image)
112
136
  // as a JSON string in `ex`, set by useSendMessage's IMessageItemEx payload.
113
- const getUrlMetadata = (message: DMessageItem): IUrlMetadata | undefined => {
137
+ const getUrlMetadata = (message: MessageItem): IUrlMetadata | undefined => {
114
138
  if (!message.ex) return undefined;
115
139
  try {
116
140
  const parsed = JSON.parse(message.ex) as { urlMetadata?: IUrlMetadata };
@@ -121,7 +145,7 @@ const getUrlMetadata = (message: DMessageItem): IUrlMetadata | undefined => {
121
145
  };
122
146
 
123
147
  export const getPinnedMessagePreview = (
124
- message: DMessageItem
148
+ message: MessageItem
125
149
  ): PinnedMessagePreview => {
126
150
  switch (message.contentType) {
127
151
  case MessageType.PictureMessage: {
@@ -183,7 +207,7 @@ export const getPinnedMessagePreview = (
183
207
  };
184
208
 
185
209
  export const getLastMessageText = (
186
- message: DMessageItem | undefined,
210
+ message: MessageItem | undefined,
187
211
  currentUserId?: string,
188
212
  conversation?: ConversationItem
189
213
  ): string => {
@@ -205,3 +229,40 @@ export const getLastMessageText = (
205
229
  ? trans('chat:revoked_by_sender', { sender })
206
230
  : `${sender}: ${preview}`;
207
231
  };
232
+
233
+ export const getReplySenderName = (
234
+ message?: MessageItem,
235
+ currentUserId?: string,
236
+ conversation?: ConversationItem,
237
+ isSent?: boolean
238
+ ): string => {
239
+ if (!message) return '';
240
+ if (currentUserId && message.sendID === currentUserId)
241
+ return trans(isSent ? 'you' : 'yourself');
242
+ return conversation?.peerType === PeerType.Bot
243
+ ? conversation?.showName || ''
244
+ : message?.senderNickname || '';
245
+ };
246
+
247
+ export const parseUrlMetadata = (ex?: string): IUrlMetadata | undefined => {
248
+ if (!ex) return undefined;
249
+ try {
250
+ const parsed = JSON.parse(ex) as any;
251
+ // Handle nested urlMetadata structure
252
+ return parsed?.urlMetadata || undefined;
253
+ } catch {
254
+ return undefined;
255
+ }
256
+ };
257
+
258
+ export const truncateMiddle = (name: string, maxLength: number): string => {
259
+ const dotIndex = name.lastIndexOf('.');
260
+ const baseName = dotIndex !== -1 ? name.slice(0, dotIndex) : name;
261
+ const ext = dotIndex !== -1 ? name.slice(dotIndex) : '';
262
+
263
+ if (baseName.length <= maxLength) return name;
264
+
265
+ const headLen = Math.ceil((maxLength - 3) / 2);
266
+ const tailLen = Math.floor((maxLength - 3) / 2);
267
+ return `${baseName.slice(0, headLen)}...${tailLen > 0 ? baseName.slice(-tailLen) : ''}${ext}`;
268
+ };