@droppii-org/chat-mobile 0.2.63 → 0.2.65

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 (124) hide show
  1. package/lib/module/components/flows/inputButtons/index.js +11 -6
  2. package/lib/module/components/flows/inputButtons/index.js.map +1 -1
  3. package/lib/module/components/messages/linkMessage/index.js +4 -2
  4. package/lib/module/components/messages/linkMessage/index.js.map +1 -1
  5. package/lib/module/components/messages/quotedMessage/index.js +3 -2
  6. package/lib/module/components/messages/quotedMessage/index.js.map +1 -1
  7. package/lib/module/components/messages/styles.js +6 -1
  8. package/lib/module/components/messages/styles.js.map +1 -1
  9. package/lib/module/components/messages/textMessage/index.js +3 -2
  10. package/lib/module/components/messages/textMessage/index.js.map +1 -1
  11. package/lib/module/components/messages/types.js.map +1 -1
  12. package/lib/module/context/ChatDetailContext.js +29 -6
  13. package/lib/module/context/ChatDetailContext.js.map +1 -1
  14. package/lib/module/core/useChatListener.js +21 -10
  15. package/lib/module/core/useChatListener.js.map +1 -1
  16. package/lib/module/hooks/flows/useFlow.js +1 -1
  17. package/lib/module/hooks/flows/useFlow.js.map +1 -1
  18. package/lib/module/hooks/message/useSearchMessage.js +39 -14
  19. package/lib/module/hooks/message/useSearchMessage.js.map +1 -1
  20. package/lib/module/hooks/message/useSendMessage.js +13 -3
  21. package/lib/module/hooks/message/useSendMessage.js.map +1 -1
  22. package/lib/module/screens/SearchConversation/SearchAllResult.js +25 -10
  23. package/lib/module/screens/SearchConversation/SearchAllResult.js.map +1 -1
  24. package/lib/module/screens/SearchConversation/SearchEmpty.js +22 -3
  25. package/lib/module/screens/SearchConversation/SearchEmpty.js.map +1 -1
  26. package/lib/module/screens/SearchConversation/SearchMessagesResult.js +23 -7
  27. package/lib/module/screens/SearchConversation/SearchMessagesResult.js.map +1 -1
  28. package/lib/module/screens/SearchConversation/SearchResultItem.js +53 -12
  29. package/lib/module/screens/SearchConversation/SearchResultItem.js.map +1 -1
  30. package/lib/module/screens/SearchMessage/SearchMessageResult.js +24 -7
  31. package/lib/module/screens/SearchMessage/SearchMessageResult.js.map +1 -1
  32. package/lib/module/screens/SearchMessage/SearchResultItem.js +31 -3
  33. package/lib/module/screens/SearchMessage/SearchResultItem.js.map +1 -1
  34. package/lib/module/screens/chat-detail/ChatComposer.js +12 -1
  35. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  36. package/lib/module/screens/chat-detail/ChatListLegend.js +26 -17
  37. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  38. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +4 -2
  39. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  40. package/lib/module/store/message.js +3 -0
  41. package/lib/module/store/message.js.map +1 -1
  42. package/lib/module/translation/resources/i18n.js +7 -2
  43. package/lib/module/translation/resources/i18n.js.map +1 -1
  44. package/lib/module/types/chat.js.map +1 -1
  45. package/lib/module/types/events.js +2 -0
  46. package/lib/module/types/events.js.map +1 -1
  47. package/lib/module/utils/flows.js +4 -4
  48. package/lib/module/utils/flows.js.map +1 -1
  49. package/lib/module/utils/highlightSearch.js +38 -0
  50. package/lib/module/utils/highlightSearch.js.map +1 -0
  51. package/lib/module/utils/messageUtils.js +5 -1
  52. package/lib/module/utils/messageUtils.js.map +1 -1
  53. package/lib/typescript/src/components/flows/inputButtons/index.d.ts +1 -1
  54. package/lib/typescript/src/components/flows/inputButtons/index.d.ts.map +1 -1
  55. package/lib/typescript/src/components/messages/linkMessage/index.d.ts +1 -1
  56. package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
  57. package/lib/typescript/src/components/messages/quotedMessage/index.d.ts.map +1 -1
  58. package/lib/typescript/src/components/messages/styles.d.ts +5 -0
  59. package/lib/typescript/src/components/messages/styles.d.ts.map +1 -1
  60. package/lib/typescript/src/components/messages/textMessage/index.d.ts +1 -1
  61. package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -1
  62. package/lib/typescript/src/components/messages/types.d.ts +1 -0
  63. package/lib/typescript/src/components/messages/types.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/hooks/flows/useFlow.d.ts.map +1 -1
  67. package/lib/typescript/src/hooks/message/useSearchMessage.d.ts.map +1 -1
  68. package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
  69. package/lib/typescript/src/screens/SearchConversation/SearchAllResult.d.ts.map +1 -1
  70. package/lib/typescript/src/screens/SearchConversation/SearchEmpty.d.ts +7 -1
  71. package/lib/typescript/src/screens/SearchConversation/SearchEmpty.d.ts.map +1 -1
  72. package/lib/typescript/src/screens/SearchConversation/SearchMessagesResult.d.ts.map +1 -1
  73. package/lib/typescript/src/screens/SearchConversation/SearchResultItem.d.ts +1 -0
  74. package/lib/typescript/src/screens/SearchConversation/SearchResultItem.d.ts.map +1 -1
  75. package/lib/typescript/src/screens/SearchMessage/SearchMessageResult.d.ts.map +1 -1
  76. package/lib/typescript/src/screens/SearchMessage/SearchResultItem.d.ts +1 -0
  77. package/lib/typescript/src/screens/SearchMessage/SearchResultItem.d.ts.map +1 -1
  78. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  79. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
  80. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +2 -1
  81. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  82. package/lib/typescript/src/store/message.d.ts.map +1 -1
  83. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  84. package/lib/typescript/src/types/chat.d.ts +3 -2
  85. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  86. package/lib/typescript/src/types/events.d.ts +10 -1
  87. package/lib/typescript/src/types/events.d.ts.map +1 -1
  88. package/lib/typescript/src/types/flows.d.ts +4 -0
  89. package/lib/typescript/src/types/flows.d.ts.map +1 -1
  90. package/lib/typescript/src/utils/flows.d.ts +1 -1
  91. package/lib/typescript/src/utils/flows.d.ts.map +1 -1
  92. package/lib/typescript/src/utils/highlightSearch.d.ts +7 -0
  93. package/lib/typescript/src/utils/highlightSearch.d.ts.map +1 -0
  94. package/lib/typescript/src/utils/messageUtils.d.ts +1 -0
  95. package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -1
  96. package/package.json +2 -2
  97. package/src/components/flows/inputButtons/index.tsx +20 -12
  98. package/src/components/messages/linkMessage/index.tsx +3 -0
  99. package/src/components/messages/quotedMessage/index.tsx +2 -1
  100. package/src/components/messages/styles.ts +6 -1
  101. package/src/components/messages/textMessage/index.tsx +7 -1
  102. package/src/components/messages/types.ts +1 -0
  103. package/src/context/ChatDetailContext.tsx +57 -11
  104. package/src/core/useChatListener.ts +53 -17
  105. package/src/hooks/flows/useFlow.ts +5 -1
  106. package/src/hooks/message/useSearchMessage.ts +46 -15
  107. package/src/hooks/message/useSendMessage.ts +21 -2
  108. package/src/screens/SearchConversation/SearchAllResult.tsx +24 -10
  109. package/src/screens/SearchConversation/SearchEmpty.tsx +38 -14
  110. package/src/screens/SearchConversation/SearchMessagesResult.tsx +39 -18
  111. package/src/screens/SearchConversation/SearchResultItem.tsx +72 -13
  112. package/src/screens/SearchMessage/SearchMessageResult.tsx +47 -20
  113. package/src/screens/SearchMessage/SearchResultItem.tsx +37 -5
  114. package/src/screens/chat-detail/ChatComposer.tsx +17 -1
  115. package/src/screens/chat-detail/ChatListLegend.tsx +48 -21
  116. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +3 -0
  117. package/src/store/message.ts +2 -0
  118. package/src/translation/resources/i18n.ts +7 -2
  119. package/src/types/chat.ts +7 -1
  120. package/src/types/events.ts +12 -0
  121. package/src/types/flows.ts +4 -0
  122. package/src/utils/flows.ts +5 -6
  123. package/src/utils/highlightSearch.ts +48 -0
  124. package/src/utils/messageUtils.ts +16 -7
@@ -29,10 +29,13 @@ import { LegendChatMessage } from './legend/LegendChatMessage';
29
29
  import { LegendChatDay } from './legend/LegendChatDay';
30
30
  import { LegendChatLoadEarlier } from './legend/LegendChatLoadEarlier';
31
31
  import { useChatDetailContext } from '../../context/ChatDetailContext';
32
- import { getFlowInputButtonsNode } from '../../utils/flows';
32
+ import { getFlowInputButtonsNodes } from '../../utils/flows';
33
33
  import { InputButtonFlow } from '../../components/flows/inputButtons';
34
34
  import { useResetFlow, useRunFlow } from '../../hooks/flows/useFlow';
35
- import type { IRunConversationFlowPayload } from '../../types/flows';
35
+ import type {
36
+ GroupChild,
37
+ IRunConversationFlowPayload,
38
+ } from '../../types/flows';
36
39
  import { useSendMessage } from '../../hooks/message/useSendMessage';
37
40
  import { ChatEvent, type ScrollToMessagePayload } from '../../types/events';
38
41
  import { useMessageStore } from '../../store/message';
@@ -110,6 +113,10 @@ export const ChatListLegend = memo(
110
113
  const scrollDebounceRef = useRef<NodeJS.Timeout | undefined>(undefined);
111
114
  const rowRefsMap = useRef<Map<string, View | null>>(new Map());
112
115
  const [showBadge, setShowBadge] = useState(false);
116
+ const [highlightedId, setHighlightedId] = useState<string | null>(null);
117
+ const highlightTimerRef = useRef<ReturnType<typeof setTimeout> | null>(
118
+ null
119
+ );
113
120
 
114
121
  const { applicationType } = useChatContext();
115
122
  const searchMessages = useMessageStore((s) => s.searchMessages);
@@ -143,9 +150,9 @@ export const ChatListLegend = memo(
143
150
 
144
151
  const message = item as MessageItem;
145
152
  const isOutgoing = message.sendID === currentUserId;
146
- const isLastIncoming =
147
- !isOutgoing &&
153
+ const isLastMessage =
148
154
  (message.clientMsgID || message.serverMsgID) === lastMessageId;
155
+ const isLastIncoming = !isOutgoing && isLastMessage;
149
156
  const messageId =
150
157
  message.clientMsgID ||
151
158
  message.serverMsgID ||
@@ -158,9 +165,13 @@ export const ChatListLegend = memo(
158
165
 
159
166
  const { dayStart, createdAt } = messageData;
160
167
 
161
- let flowInputButtonsNode = null;
162
- if (isLastIncoming && isBotConversation) {
163
- flowInputButtonsNode = getFlowInputButtonsNode(
168
+ let flowInputButtonsNodes: GroupChild<'input-buttons'>[] = [];
169
+ if (
170
+ ((isLastMessage && conversationFlow?.havingBotMessage === false) ||
171
+ isLastIncoming) &&
172
+ isBotConversation
173
+ ) {
174
+ flowInputButtonsNodes = getFlowInputButtonsNodes(
164
175
  conversationFlow?.flowCurrentStep
165
176
  );
166
177
  }
@@ -193,15 +204,16 @@ export const ChatListLegend = memo(
193
204
  : undefined
194
205
  }
195
206
  customMessageItemFactory={customMessageItemFactory}
207
+ isHighlighted={highlightedId === messageId}
196
208
  />
197
- {!!flowInputButtonsNode && (
198
- <InputButtonFlow
199
- nodeData={flowInputButtonsNode}
200
- onResetFlow={onResetFlow}
201
- onRunFlow={onRunFlow}
202
- />
203
- )}
204
209
  </KContainer.View>
210
+ {flowInputButtonsNodes && flowInputButtonsNodes.length > 0 && (
211
+ <InputButtonFlow
212
+ nodeData={flowInputButtonsNodes}
213
+ onResetFlow={onResetFlow}
214
+ onRunFlow={onRunFlow}
215
+ />
216
+ )}
205
217
  </>
206
218
  );
207
219
  } catch (error) {
@@ -229,7 +241,9 @@ export const ChatListLegend = memo(
229
241
  onResetFlow,
230
242
  onRunFlow,
231
243
  conversationFlow?.flowCurrentStep,
244
+ conversationFlow?.havingBotMessage,
232
245
  retryMessage,
246
+ highlightedId,
233
247
  ]
234
248
  );
235
249
 
@@ -320,10 +334,13 @@ export const ChatListLegend = memo(
320
334
 
321
335
  const isOutgoing = message.sendID === currentUserId;
322
336
  const isLastIncoming = !isOutgoing && messageId === lastMessageId;
337
+ const flowInputButtonsNodes = getFlowInputButtonsNodes(
338
+ conversationFlow?.flowCurrentStep
339
+ );
323
340
  if (
324
341
  isLastIncoming &&
325
342
  isBotConversation &&
326
- getFlowInputButtonsNode(conversationFlow?.flowCurrentStep)
343
+ flowInputButtonsNodes.length > 0
327
344
  ) {
328
345
  return undefined;
329
346
  }
@@ -427,11 +444,21 @@ export const ChatListLegend = memo(
427
444
 
428
445
  if (index >= 0) {
429
446
  try {
430
- listRef.current?.scrollToIndex({
431
- index,
432
- animated: true,
433
- viewPosition: 0.5,
434
- });
447
+ listRef.current
448
+ ?.scrollToIndex({
449
+ index,
450
+ animated: true,
451
+ viewPosition: 0.5,
452
+ })
453
+ .finally(() => {
454
+ if (highlightTimerRef.current)
455
+ clearTimeout(highlightTimerRef.current);
456
+ setHighlightedId(clientMessageId);
457
+ highlightTimerRef.current = setTimeout(
458
+ () => setHighlightedId(null),
459
+ 5000
460
+ );
461
+ });
435
462
  } catch {
436
463
  // scrollToIndex throws if item not rendered yet — force refetch messages
437
464
  searchMessages({
@@ -487,7 +514,7 @@ export const ChatListLegend = memo(
487
514
  getFixedItemSize={getFixedItemSize}
488
515
  keyExtractor={(item) => String(item.clientMsgID || item.serverMsgID)}
489
516
  recycleItems={false}
490
- extraData={`${conversationFlow?.flowCurrentStep?.id ?? ''}-${lastMessageId ?? ''}`}
517
+ extraData={`${conversationFlow?.flowCurrentStep?.id ?? ''}-${lastMessageId ?? ''}-${highlightedId ?? ''}`}
491
518
  alignItemsAtEnd
492
519
  maintainVisibleContentPosition={maintainVisiblePositionConfig}
493
520
  maintainScrollAtEnd={true}
@@ -35,6 +35,7 @@ interface LegendChatMessageProps {
35
35
  onPress?: (message: MessageItem) => void;
36
36
  onLongPress?: () => void;
37
37
  customMessageItemFactory?: (m: MessageItem) => ReactNode;
38
+ isHighlighted?: boolean;
38
39
  }
39
40
 
40
41
  const messageComponentMap: Partial<
@@ -69,6 +70,7 @@ export const LegendChatMessage = memo(
69
70
  onPress,
70
71
  onLongPress,
71
72
  customMessageItemFactory,
73
+ isHighlighted,
72
74
  }: LegendChatMessageProps) => {
73
75
  const handlePress = useCallback(() => {
74
76
  onPress?.(message);
@@ -107,6 +109,7 @@ export const LegendChatMessage = memo(
107
109
  createdAtTime={createdAtTime}
108
110
  onMediaPress={hasMediaPress ? onMediaPress : undefined}
109
111
  onPressUrl={hasUrlPress ? onPressUrl : undefined}
112
+ isHighlighted={isHighlighted}
110
113
  />
111
114
  </LongPressWrapper>
112
115
 
@@ -224,6 +224,8 @@ export const markMessageRevoked = (clientMsgID: string) => {
224
224
  .getState()
225
225
  .updateOneMessage({ clientMsgID, contentType: MessageType.RevokeMessage });
226
226
 
227
+ DeviceEventEmitter.emit(ChatEvent.MessageRevoked, { clientMsgID });
228
+
227
229
  revokeQuotedReferences(clientMsgID);
228
230
  };
229
231
 
@@ -122,9 +122,14 @@ const i18nKey: Record<string, string> = {
122
122
  'all': 'Tất cả',
123
123
  'contacts': 'Liên hệ',
124
124
  'messages': 'Tin nhắn',
125
- 'search:empty_description':
126
- 'Không tìm thấy kết quả nào\nHãy thử lại với cách viết hoặc kết hợp cụm từ khác phù hợp hơn.',
125
+ 'search:empty_description': 'Không tìm thấy kết quả nào',
126
+ 'search:empty_hint':
127
+ 'Bạn có thể tìm kiếm theo liên hệ hoặc nội dung tin nhắn',
128
+ 'search_message:empty_hint': 'Bạn có thể tìm kiếm theo nội dung tin nhắn',
129
+ 'search_conversation:empty_hint': 'Bạn có thể tìm kiếm theo liên hệ',
127
130
  'view_all': 'Xem tất cả',
131
+ 'search_message:revoked_message': 'Tin nhắn đã được thu hồi',
132
+ 'chat:no_send_permission': 'Bạn không có quyền gửi tin nhắn',
128
133
  };
129
134
 
130
135
  export default {
package/src/types/chat.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import {
2
+ GroupPermission,
2
3
  MessageType,
3
4
  type ConversationItem,
4
5
  type MessageItem,
@@ -205,13 +206,18 @@ export interface MessageStore {
205
206
  export interface ChatDetailContextType {
206
207
  conversationFlow?: IConversationFlow;
207
208
  isBotConversation: boolean;
208
- setConverationFlowStep: (step?: IConversationFlowStep) => void;
209
+ setConverationFlowStep: (
210
+ step?: IConversationFlowStep,
211
+ isEnd?: boolean,
212
+ havingBotMessage?: boolean
213
+ ) => void;
209
214
  flowState?: DFlowState;
210
215
  runButtonContext: (stringContext: DFlowContext) => Promise<boolean>;
211
216
  conversation?: ConversationItem;
212
217
  quotedMessage?: MessageItem;
213
218
  setQuotedMessage: (item?: MessageItem) => void;
214
219
  conversationFlowMainMenu?: InputButtonItem[];
220
+ groupPermissions: GroupPermission[];
215
221
  }
216
222
 
217
223
  export interface ChatDetailProviderProps extends PropsWithChildren {}
@@ -1,8 +1,20 @@
1
+ import type { GroupPermission } from '@droppii/openim-rn-client-sdk';
2
+
1
3
  export enum ChatEvent {
2
4
  ScrollToMessage = 'chat:scroll_to_message',
3
5
  ScrollToBottom = 'chat:scroll_to_bottom',
6
+ MessageRevoked = 'chat:message_revoked',
7
+ GroupPermissionUpdated = 'chat:group_permission_updated',
4
8
  }
5
9
 
6
10
  export interface ScrollToMessagePayload {
7
11
  clientMessageId: string;
8
12
  }
13
+
14
+ export interface MessageRevokedPayload {
15
+ clientMsgID: string;
16
+ }
17
+
18
+ export interface GroupPermissionUpdatedPayload {
19
+ permissions: GroupPermission[];
20
+ }
@@ -91,10 +91,14 @@ export interface IConversationFlow {
91
91
  chatType: PeerType;
92
92
  applicationType: DChatApplicationType;
93
93
  flowCurrentStep: IConversationFlowStep | null;
94
+ havingBotMessage: boolean;
95
+ flowIsEnd: boolean;
94
96
  }
95
97
 
96
98
  export interface IRunConversationFlowResponse {
97
99
  flowNextStep: IConversationFlowStep | null;
100
+ isEnd: boolean;
101
+ havingBotMessage: boolean;
98
102
  }
99
103
 
100
104
  export interface IRunConversationFlowPayload {
@@ -4,15 +4,14 @@ import {
4
4
  type IConversationFlowStep,
5
5
  } from '../types/flows';
6
6
 
7
- export const getFlowInputButtonsNode = (
7
+ export const getFlowInputButtonsNodes = (
8
8
  step?: IConversationFlowStep | null
9
9
  ) => {
10
- if (!step) return null;
10
+ if (!step) return [];
11
11
  const childrenNode = step?.data?.children || [];
12
- const inputButtonsNode = childrenNode?.find(
13
- (f) => f.type === NodeTypes.InputButtons
14
- ) as GroupChild<'input-buttons'>;
15
- return inputButtonsNode;
12
+ const inputButtonsNodes =
13
+ childrenNode?.filter?.((f) => f.type === NodeTypes.InputButtons) || [];
14
+ return inputButtonsNodes as GroupChild<'input-buttons'>[];
16
15
  };
17
16
 
18
17
  export const DEFAULT_BUTTON_ID = 'default-item-button';
@@ -0,0 +1,48 @@
1
+ export interface HighlightResult {
2
+ before: string;
3
+ match: string;
4
+ after: string;
5
+ }
6
+
7
+ export const highlightSearch = (
8
+ text: string,
9
+ keyword: string,
10
+ maxLength = 30
11
+ ): HighlightResult | null => {
12
+ if (!keyword) return null;
13
+
14
+ const lowerText = text.toLowerCase();
15
+ const lowerKeyword = keyword.toLowerCase();
16
+ const index = lowerText.indexOf(lowerKeyword);
17
+
18
+ if (index === -1) return null;
19
+
20
+ const before = text.slice(0, index);
21
+ const match = text.slice(index, index + keyword.length);
22
+ const after = text.slice(index + keyword.length);
23
+
24
+ if (keyword.length >= maxLength) {
25
+ return { before: '', match: match.slice(0, maxLength), after: '' };
26
+ }
27
+
28
+ const remain = maxLength - match.length;
29
+ let left = Math.floor(remain / 2);
30
+ let right = remain - left;
31
+
32
+ if (before.length < left) {
33
+ right += left - before.length;
34
+ left = before.length;
35
+ }
36
+
37
+ if (after.length < right) {
38
+ left += right - after.length;
39
+ right = after.length;
40
+ }
41
+
42
+ const displayedBefore =
43
+ before.length > left ? '…' + before.slice(before.length - left) : before;
44
+ const displayedAfter =
45
+ after.length > right ? after.slice(0, right) + '…' : after;
46
+
47
+ return { before: displayedBefore, match, after: displayedAfter };
48
+ };
@@ -216,6 +216,21 @@ export const getPinnedMessagePreview = (
216
216
  }
217
217
  };
218
218
 
219
+ export const getSenderName = (
220
+ message: MessageItem,
221
+ currentUserId?: string,
222
+ conversation?: ConversationItem
223
+ ): string => {
224
+ const sender =
225
+ currentUserId && message.sendID === currentUserId
226
+ ? 'Bạn'
227
+ : message?.senderNickname ||
228
+ (conversation?.peerType === PeerType.Bot
229
+ ? conversation?.showName || ''
230
+ : undefined);
231
+ return sender || '';
232
+ };
233
+
219
234
  export interface GetLastMessageTextParams {
220
235
  message: MessageItem | undefined;
221
236
  currentUserId?: string;
@@ -233,13 +248,7 @@ export const getLastMessageText = ({
233
248
  const preview = getMessagePreview(message);
234
249
  if (!preview) return '';
235
250
 
236
- const sender =
237
- currentUserId && message.sendID === currentUserId
238
- ? 'Bạn'
239
- : message.senderNickname ||
240
- (conversation?.peerType === PeerType.Bot
241
- ? conversation?.showName || ''
242
- : undefined);
251
+ const sender = getSenderName(message, currentUserId, conversation);
243
252
 
244
253
  if (!sender) return preview;
245
254