@droppii-org/chat-mobile 0.2.28 → 0.2.30

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 (182) hide show
  1. package/lib/module/components/ThreadCard/MuteThread.js +86 -0
  2. package/lib/module/components/ThreadCard/MuteThread.js.map +1 -0
  3. package/lib/module/components/ThreadCard/ThreadCard.js +93 -73
  4. package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
  5. package/lib/module/components/flows/inputButtons/index.js +6 -3
  6. package/lib/module/components/flows/inputButtons/index.js.map +1 -1
  7. package/lib/module/config/api-endpoints.js +2 -1
  8. package/lib/module/config/api-endpoints.js.map +1 -1
  9. package/lib/module/config/uploadLimits.js +1 -1
  10. package/lib/module/context/ChatDetailContext.js +35 -2
  11. package/lib/module/context/ChatDetailContext.js.map +1 -1
  12. package/lib/module/context/index.js +1 -0
  13. package/lib/module/context/index.js.map +1 -1
  14. package/lib/module/hooks/conversation/useGetConversationDetail.js +58 -0
  15. package/lib/module/hooks/conversation/useGetConversationDetail.js.map +1 -0
  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/flows/useGetConversationFlowMainMenu.js +17 -0
  19. package/lib/module/hooks/flows/useGetConversationFlowMainMenu.js.map +1 -0
  20. package/lib/module/hooks/message/useSendMessage.js +32 -7
  21. package/lib/module/hooks/message/useSendMessage.js.map +1 -1
  22. package/lib/module/hooks/query-keys.js +4 -1
  23. package/lib/module/hooks/query-keys.js.map +1 -1
  24. package/lib/module/hooks/useChatCompose.js +0 -1
  25. package/lib/module/hooks/useChatCompose.js.map +1 -1
  26. package/lib/module/hooks/useMuteConversation.js +34 -0
  27. package/lib/module/hooks/useMuteConversation.js.map +1 -0
  28. package/lib/module/index.js +4 -2
  29. package/lib/module/index.js.map +1 -1
  30. package/lib/module/screens/chat-detail/ChatAttachmentPanel.js +4 -14
  31. package/lib/module/screens/chat-detail/ChatAttachmentPanel.js.map +1 -1
  32. package/lib/module/screens/chat-detail/ChatComposer.js +26 -15
  33. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  34. package/lib/module/screens/chat-detail/ChatDetail.js +58 -71
  35. package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
  36. package/lib/module/screens/chat-detail/ChatDetailHeader.js +7 -10
  37. package/lib/module/screens/chat-detail/ChatDetailHeader.js.map +1 -1
  38. package/lib/module/screens/chat-detail/ChatListLegend.js +1 -1
  39. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  40. package/lib/module/screens/chat-detail/ChatLoadEarlier.js.map +1 -1
  41. package/lib/module/screens/chat-detail/ChatQuickActions.js +2 -1
  42. package/lib/module/screens/chat-detail/ChatQuickActions.js.map +1 -1
  43. package/lib/module/screens/chat-detail/constants.js +30 -24
  44. package/lib/module/screens/chat-detail/constants.js.map +1 -1
  45. package/lib/module/screens/chat-detail/index.js +2 -2
  46. package/lib/module/screens/chat-detail/index.js.map +1 -1
  47. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxMenu.js +3 -4
  48. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxMenu.js.map +1 -1
  49. package/lib/module/screens/chat-detail/messageToolbox/messageToolbox.utils.js +5 -3
  50. package/lib/module/screens/chat-detail/messageToolbox/messageToolbox.utils.js.map +1 -1
  51. package/lib/module/screens/chat-detail/types.js +15 -1
  52. package/lib/module/screens/chat-detail/types.js.map +1 -1
  53. package/lib/module/services/attachmentHandlers/imageAttachmentHandler.js +2 -2
  54. package/lib/module/services/attachmentHandlers/imageAttachmentHandler.js.map +1 -1
  55. package/lib/module/services/endpoints.js +3 -1
  56. package/lib/module/services/endpoints.js.map +1 -1
  57. package/lib/module/translation/resources/i18n.js +15 -1
  58. package/lib/module/translation/resources/i18n.js.map +1 -1
  59. package/lib/module/types/chat.js +9 -0
  60. package/lib/module/types/chat.js.map +1 -1
  61. package/lib/module/types/flows.js +5 -0
  62. package/lib/module/types/flows.js.map +1 -1
  63. package/lib/module/utils/device.js +1 -1
  64. package/lib/module/utils/device.js.map +1 -1
  65. package/lib/module/utils/flows.js +5 -0
  66. package/lib/module/utils/flows.js.map +1 -1
  67. package/lib/module/utils/imageUtils.js +0 -3
  68. package/lib/module/utils/imageUtils.js.map +1 -1
  69. package/lib/module/utils/messageUtils.js +5 -19
  70. package/lib/module/utils/messageUtils.js.map +1 -1
  71. package/lib/typescript/src/components/ThreadCard/MuteThread.d.ts +10 -0
  72. package/lib/typescript/src/components/ThreadCard/MuteThread.d.ts.map +1 -0
  73. package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
  74. package/lib/typescript/src/components/flows/inputButtons/index.d.ts.map +1 -1
  75. package/lib/typescript/src/config/api-endpoints.d.ts +1 -0
  76. package/lib/typescript/src/config/api-endpoints.d.ts.map +1 -1
  77. package/lib/typescript/src/context/ChatDetailContext.d.ts +1 -1
  78. package/lib/typescript/src/context/ChatDetailContext.d.ts.map +1 -1
  79. package/lib/typescript/src/context/index.d.ts +1 -0
  80. package/lib/typescript/src/context/index.d.ts.map +1 -1
  81. package/lib/typescript/src/hooks/conversation/useGetConversationDetail.d.ts +17 -0
  82. package/lib/typescript/src/hooks/conversation/useGetConversationDetail.d.ts.map +1 -0
  83. package/lib/typescript/src/hooks/flows/useGetConversationFlowMainMenu.d.ts +3 -0
  84. package/lib/typescript/src/hooks/flows/useGetConversationFlowMainMenu.d.ts.map +1 -0
  85. package/lib/typescript/src/hooks/message/useSendMessage.d.ts +5 -4
  86. package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
  87. package/lib/typescript/src/hooks/query-keys.d.ts +3 -0
  88. package/lib/typescript/src/hooks/query-keys.d.ts.map +1 -1
  89. package/lib/typescript/src/hooks/useMuteConversation.d.ts +6 -0
  90. package/lib/typescript/src/hooks/useMuteConversation.d.ts.map +1 -0
  91. package/lib/typescript/src/index.d.ts +6 -4
  92. package/lib/typescript/src/index.d.ts.map +1 -1
  93. package/lib/typescript/src/screens/chat-detail/ChatAttachmentPanel.d.ts +2 -2
  94. package/lib/typescript/src/screens/chat-detail/ChatAttachmentPanel.d.ts.map +1 -1
  95. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts +3 -1
  96. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  97. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts +1 -1
  98. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
  99. package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts +1 -1
  100. package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts.map +1 -1
  101. package/lib/typescript/src/screens/chat-detail/ChatLoadEarlier.d.ts +3 -2
  102. package/lib/typescript/src/screens/chat-detail/ChatLoadEarlier.d.ts.map +1 -1
  103. package/lib/typescript/src/screens/chat-detail/ChatQuickActions.d.ts +1 -1
  104. package/lib/typescript/src/screens/chat-detail/ChatQuickActions.d.ts.map +1 -1
  105. package/lib/typescript/src/screens/chat-detail/constants.d.ts +3 -3
  106. package/lib/typescript/src/screens/chat-detail/constants.d.ts.map +1 -1
  107. package/lib/typescript/src/screens/chat-detail/index.d.ts +3 -3
  108. package/lib/typescript/src/screens/chat-detail/index.d.ts.map +1 -1
  109. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.d.ts +1 -1
  110. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.d.ts.map +1 -1
  111. package/lib/typescript/src/screens/chat-detail/messageToolbox/messageToolbox.utils.d.ts +0 -2
  112. package/lib/typescript/src/screens/chat-detail/messageToolbox/messageToolbox.utils.d.ts.map +1 -1
  113. package/lib/typescript/src/screens/chat-detail/types.d.ts +28 -19
  114. package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
  115. package/lib/typescript/src/services/endpoints.d.ts +2 -0
  116. package/lib/typescript/src/services/endpoints.d.ts.map +1 -1
  117. package/lib/typescript/src/store/conversation.d.ts +1 -1
  118. package/lib/typescript/src/store/conversation.d.ts.map +1 -1
  119. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  120. package/lib/typescript/src/types/chat.d.ts +26 -2
  121. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  122. package/lib/typescript/src/types/flows.d.ts +3 -0
  123. package/lib/typescript/src/types/flows.d.ts.map +1 -1
  124. package/lib/typescript/src/utils/flows.d.ts +2 -0
  125. package/lib/typescript/src/utils/flows.d.ts.map +1 -1
  126. package/lib/typescript/src/utils/imageUtils.d.ts +0 -1
  127. package/lib/typescript/src/utils/imageUtils.d.ts.map +1 -1
  128. package/lib/typescript/src/utils/messageUtils.d.ts +1 -1
  129. package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -1
  130. package/package.json +3 -5
  131. package/src/components/ThreadCard/MuteThread.tsx +100 -0
  132. package/src/components/ThreadCard/ThreadCard.tsx +104 -71
  133. package/src/components/flows/inputButtons/index.tsx +11 -3
  134. package/src/config/api-endpoints.ts +2 -0
  135. package/src/config/uploadLimits.ts +1 -1
  136. package/src/context/ChatDetailContext.tsx +57 -4
  137. package/src/context/index.ts +1 -0
  138. package/src/hooks/conversation/useGetConversationDetail.ts +78 -0
  139. package/src/hooks/flows/useFlow.ts +1 -1
  140. package/src/hooks/flows/useGetConversationFlowMainMenu.ts +19 -0
  141. package/src/hooks/message/useSendMessage.ts +43 -14
  142. package/src/hooks/query-keys.ts +6 -0
  143. package/src/hooks/useChatCompose.ts +1 -1
  144. package/src/hooks/useMuteConversation.ts +44 -0
  145. package/src/index.tsx +15 -6
  146. package/src/screens/chat-detail/ChatAttachmentPanel.tsx +8 -25
  147. package/src/screens/chat-detail/ChatComposer.tsx +26 -21
  148. package/src/screens/chat-detail/ChatDetail.tsx +61 -77
  149. package/src/screens/chat-detail/ChatDetailHeader.tsx +7 -18
  150. package/src/screens/chat-detail/ChatListLegend.tsx +1 -1
  151. package/src/screens/chat-detail/ChatLoadEarlier.tsx +1 -2
  152. package/src/screens/chat-detail/ChatQuickActions.tsx +6 -2
  153. package/src/screens/chat-detail/constants.ts +33 -27
  154. package/src/screens/chat-detail/index.ts +5 -8
  155. package/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.tsx +2 -2
  156. package/src/screens/chat-detail/messageToolbox/messageToolbox.utils.ts +4 -4
  157. package/src/screens/chat-detail/types.ts +30 -28
  158. package/src/services/attachmentHandlers/imageAttachmentHandler.ts +2 -2
  159. package/src/services/endpoints.ts +4 -0
  160. package/src/store/conversation.ts +1 -1
  161. package/src/translation/resources/i18n.ts +15 -0
  162. package/src/types/chat.ts +31 -1
  163. package/src/types/flows.ts +4 -0
  164. package/src/utils/device.ts +1 -1
  165. package/src/utils/flows.ts +7 -0
  166. package/src/utils/imageUtils.ts +0 -4
  167. package/src/utils/messageUtils.ts +7 -22
  168. package/lib/module/screens/chat-detail/ChatDay.js +0 -65
  169. package/lib/module/screens/chat-detail/ChatDay.js.map +0 -1
  170. package/lib/module/types/message.js +0 -17
  171. package/lib/module/types/message.js.map +0 -1
  172. package/lib/module/utils/resolveMessageType.js +0 -47
  173. package/lib/module/utils/resolveMessageType.js.map +0 -1
  174. package/lib/typescript/src/screens/chat-detail/ChatDay.d.ts +0 -3
  175. package/lib/typescript/src/screens/chat-detail/ChatDay.d.ts.map +0 -1
  176. package/lib/typescript/src/types/message.d.ts +0 -16
  177. package/lib/typescript/src/types/message.d.ts.map +0 -1
  178. package/lib/typescript/src/utils/resolveMessageType.d.ts +0 -4
  179. package/lib/typescript/src/utils/resolveMessageType.d.ts.map +0 -1
  180. package/src/screens/chat-detail/ChatDay.tsx +0 -73
  181. package/src/types/message.ts +0 -18
  182. package/src/utils/resolveMessageType.ts +0 -51
@@ -0,0 +1,44 @@
1
+ import { useCallback } from 'react';
2
+ import OpenIMSDK, {
3
+ MessageReceiveOptType,
4
+ } from '@droppii/openim-rn-client-sdk';
5
+ import type { ConversationItem } from '@droppii/openim-rn-client-sdk';
6
+ import { useConversationStore } from '../store';
7
+
8
+ export function useMuteConversation() {
9
+ const muteConversation = useCallback(
10
+ async (conversation?: ConversationItem) => {
11
+ if (conversation == null) return;
12
+
13
+ await OpenIMSDK.setConversationRecvMessageOpt({
14
+ conversationID: conversation.conversationID,
15
+ opt: MessageReceiveOptType.NotNotify,
16
+ });
17
+ useConversationStore
18
+ .getState()
19
+ .updateConversations([
20
+ { ...conversation, recvMsgOpt: MessageReceiveOptType.NotNotify },
21
+ ]);
22
+ },
23
+ []
24
+ );
25
+
26
+ const unmuteConversation = useCallback(
27
+ async (conversation?: ConversationItem) => {
28
+ if (conversation == null) return;
29
+
30
+ await OpenIMSDK.setConversationRecvMessageOpt({
31
+ conversationID: conversation.conversationID,
32
+ opt: MessageReceiveOptType.Normal,
33
+ });
34
+ useConversationStore
35
+ .getState()
36
+ .updateConversations([
37
+ { ...conversation, recvMsgOpt: MessageReceiveOptType.Normal },
38
+ ]);
39
+ },
40
+ []
41
+ );
42
+
43
+ return { muteConversation, unmuteConversation };
44
+ }
package/src/index.tsx CHANGED
@@ -14,6 +14,7 @@ export * from './store';
14
14
  export * from './context';
15
15
  export * from './hooks/useConversationList';
16
16
  export * from './hooks/useChatMessages';
17
+ export * from './hooks/message/useSendMessage';
17
18
  export { useImageAttachment } from './hooks/useImageAttachment';
18
19
  export { useMediaViewer } from './hooks/useMediaViewer';
19
20
  export type { MediaItem } from './hooks/useMediaViewer';
@@ -34,24 +35,32 @@ export {
34
35
  ChatComposer,
35
36
  ChatQuickActions,
36
37
  ChatAttachmentPanel,
37
- DEFAULT_Chat_QUICK_ACTIONS,
38
- DEFAULT_ATTACHMENT_ACTIONS,
38
+ DEFAULT_QUICK_ACTIONS,
39
+ DEFAULT_PANNEL_ACTIONS,
40
+ DChatPannelActionItemType,
41
+ DChatQuickActionItemType,
39
42
  } from './screens/chat-detail';
40
43
  export type {
41
44
  DChatActionItem,
42
45
  DChatActionIconProvider,
43
46
  DChatQuickAction,
44
- DChatAttachmentAction,
47
+ DChatPannelAction,
45
48
  ChatDetailProps,
46
49
  ChatDetailHeaderProps,
47
50
  ChatListProps,
48
51
  ChatComposerProps,
49
52
  ChatQuickActionsProps,
50
53
  ChatQuickActionsRenderParams,
51
- ChatAttachmentPanelProps,
54
+ ChatPanelProps,
52
55
  } from './screens/chat-detail';
53
56
 
54
- export type { PeerType } from '@droppii/openim-rn-client-sdk';
55
- export { LoginStatus } from '@droppii/openim-rn-client-sdk';
57
+ export { LoginStatus, MessageType } from '@droppii/openim-rn-client-sdk';
58
+ export type {
59
+ PeerType,
60
+ ConversationItem,
61
+ MessageItem,
62
+ } from '@droppii/openim-rn-client-sdk';
56
63
 
57
64
  export { registerUIUtils, UIUtils } from './utils/UIUtils';
65
+
66
+ export { DFlowContext } from './types/flows';
@@ -8,8 +8,7 @@ import {
8
8
  KSpacingValue,
9
9
  } from '@droppii/libs';
10
10
  import { ATTACHMENT_PANEL_COLUMNS } from './constants';
11
- import { useChatActionPress } from './useChatActionPress';
12
- import type { DChatAttachmentAction, ChatAttachmentPanelProps } from './types';
11
+ import type { DChatPannelAction, ChatPanelProps } from './types';
13
12
 
14
13
  const AttachmentActionItem = memo(
15
14
  ({
@@ -17,9 +16,9 @@ const AttachmentActionItem = memo(
17
16
  itemWidth,
18
17
  onPress,
19
18
  }: {
20
- action: DChatAttachmentAction;
19
+ action: DChatPannelAction;
21
20
  itemWidth: `${number}%`;
22
- onPress: (action: DChatAttachmentAction) => void;
21
+ onPress: (action: DChatPannelAction) => void;
23
22
  }) => {
24
23
  const handlePress = useCallback(() => {
25
24
  onPress(action);
@@ -61,42 +60,26 @@ const AttachmentActionItem = memo(
61
60
  AttachmentActionItem.displayName = 'AttachmentActionItem';
62
61
 
63
62
  export const ChatAttachmentPanel = memo(
64
- ({
65
- actions,
66
- columns = ATTACHMENT_PANEL_COLUMNS,
67
- onActionPress,
68
- renderAction,
69
- }: ChatAttachmentPanelProps) => {
70
- const handleActionPress = useChatActionPress(onActionPress);
71
-
63
+ ({ actions, columns = ATTACHMENT_PANEL_COLUMNS }: ChatPanelProps) => {
72
64
  const itemWidth = useMemo(
73
65
  () => `${100 / columns}%` as `${number}%`,
74
66
  [columns]
75
67
  );
76
68
 
77
- const renderItem = useCallback<ListRenderItem<DChatAttachmentAction>>(
69
+ const renderItem = useCallback<ListRenderItem<DChatPannelAction>>(
78
70
  ({ item }) => {
79
- const onPress = () => handleActionPress(item);
80
-
81
- if (renderAction) {
82
- return <>{renderAction(item, onPress)}</>;
83
- }
84
-
85
71
  return (
86
72
  <AttachmentActionItem
87
73
  action={item}
88
74
  itemWidth={itemWidth}
89
- onPress={handleActionPress}
75
+ onPress={() => item?.onPress?.()}
90
76
  />
91
77
  );
92
78
  },
93
- [handleActionPress, itemWidth, renderAction]
79
+ [itemWidth]
94
80
  );
95
81
 
96
- const keyExtractor = useCallback(
97
- (item: DChatAttachmentAction) => item.id,
98
- []
99
- );
82
+ const keyExtractor = useCallback((item: DChatPannelAction) => item.id, []);
100
83
 
101
84
  if (!actions?.length) {
102
85
  return null;
@@ -18,11 +18,11 @@ import { ChatMessageInput } from './components/ChatMessageInput';
18
18
  import { AttachmentPreview } from '../../components/AttachmentPreview';
19
19
 
20
20
  import {
21
- DEFAULT_ATTACHMENT_ACTIONS,
22
- DEFAULT_Chat_QUICK_ACTIONS,
21
+ DEFAULT_QUICK_ACTIONS,
23
22
  getAttachmentPanelHeight,
23
+ DEFAULT_PANNEL_ACTIONS,
24
24
  } from './constants';
25
- import type { DChatAttachmentAction } from './types';
25
+ import { DChatPannelActionItemType, type DChatPannelAction } from './types';
26
26
  import { useChatComposerState } from './hooks/useChatComposerState';
27
27
  import { useChatComposerAnimation } from './hooks/useChatComposerAnimation';
28
28
  import { useChatDetailContext } from '../../context/ChatDetailContext';
@@ -35,10 +35,11 @@ import { useChatCompose } from '../../hooks/useChatCompose';
35
35
 
36
36
  interface ChatComposerInternalProps {
37
37
  isEmptyMessage?: boolean;
38
+ pannelActions?: DChatPannelAction[];
38
39
  }
39
40
 
40
41
  export const ChatComposer = memo(
41
- ({ isEmptyMessage = false }: ChatComposerInternalProps) => {
42
+ ({ isEmptyMessage = false, pannelActions }: ChatComposerInternalProps) => {
42
43
  const insets = useSafeAreaInsets();
43
44
 
44
45
  const { isBotConversation, conversationFlow } = useChatDetailContext();
@@ -57,7 +58,7 @@ export const ChatComposer = memo(
57
58
  } = useChatComposerState(compose.text);
58
59
 
59
60
  const panelHeight = useMemo(
60
- () => getAttachmentPanelHeight(DEFAULT_ATTACHMENT_ACTIONS.length),
61
+ () => getAttachmentPanelHeight(DEFAULT_PANNEL_ACTIONS.length),
61
62
  []
62
63
  );
63
64
 
@@ -132,18 +133,25 @@ export const ChatComposer = memo(
132
133
  })
133
134
  );
134
135
 
135
- const handleAttachmentAction = useCallback(
136
- async (action: DChatAttachmentAction) => {
137
- if (action.id === 'gallery') {
138
- debouncedImagePickerRef.current();
139
- } else if (action.id === 'file') {
140
- debouncedFilePickerRef.current();
141
- } else {
142
- console.log('[ChatComposer] attachment action:', action.id);
136
+ const resolvedPannelActons = useMemo(() => {
137
+ return (pannelActions || DEFAULT_PANNEL_ACTIONS)?.map((p) => {
138
+ let onPress;
139
+ switch (p.id) {
140
+ case DChatPannelActionItemType.Gallery:
141
+ onPress = debouncedImagePickerRef.current;
142
+ break;
143
+ case DChatPannelActionItemType.Documents:
144
+ onPress = debouncedFilePickerRef.current;
145
+ break;
146
+ default:
147
+ break;
143
148
  }
144
- },
145
- []
146
- );
149
+ return {
150
+ ...p,
151
+ onPress: p.onPress || onPress,
152
+ };
153
+ });
154
+ }, [pannelActions]);
147
155
 
148
156
  const inputRowStyle = useMemo(
149
157
  () => ({ paddingBottom: isAttachmentOpen ? 8 : insets.bottom + 12 }),
@@ -186,7 +194,7 @@ export const ChatComposer = memo(
186
194
  <KContainer.View background={'rgba(131, 137, 157, 0.05)'}>
187
195
  <ChatQuickActions
188
196
  visible
189
- actions={DEFAULT_Chat_QUICK_ACTIONS}
197
+ actions={DEFAULT_QUICK_ACTIONS}
190
198
  onActionPress={(action) =>
191
199
  console.log('[ChatComposer] quick action:', action.id)
192
200
  }
@@ -272,10 +280,7 @@ export const ChatComposer = memo(
272
280
  style={[styles.accessorySlot, accessorySlotStyle]}
273
281
  pointerEvents={isAttachmentOpen ? 'auto' : 'none'}
274
282
  >
275
- <ChatAttachmentPanel
276
- actions={DEFAULT_ATTACHMENT_ACTIONS}
277
- onActionPress={handleAttachmentAction}
278
- />
283
+ <ChatAttachmentPanel actions={resolvedPannelActons} />
279
284
  </Reanimated.View>
280
285
  </KContainer.View>
281
286
  );
@@ -14,30 +14,22 @@ import { useConversation, useConversationStore } from '../../store';
14
14
  import ChatDetailHeader from './ChatDetailHeader';
15
15
  import { ChatListLegend } from './ChatListLegend';
16
16
  import { ChatComposer } from './ChatComposer';
17
- import {
18
- getConversationAvatarUri,
19
- getConversationSubtitle,
20
- getConversationTitle,
21
- shouldShowAddMember,
22
- } from './conversationHeader.utils';
17
+ import { shouldShowAddMember } from './conversationHeader.utils';
23
18
  import type { ChatDetailProps } from './types';
24
- import { ChatDetailProvider } from '../../context/ChatDetailContext';
25
19
  import { normalizeUrl } from '../../utils/url';
26
- // import { ChatMessageAPI } from '../../services/message';
27
20
  import { MessageToolboxOverlay } from './messageToolbox/MessageToolboxOverlay';
28
21
  import type { MeasuredRect, MessageToolboxRef } from './messageToolbox/types';
29
22
  import type { DMessageItem } from '../../types/chat';
23
+ import { useGetConversationDetail } from '../../hooks/conversation/useGetConversationDetail';
30
24
 
31
25
  const ChatDetail = memo(
32
26
  ({
33
- conversationId,
27
+ targetConversationId = '',
28
+ targetUserId = '',
29
+ targetGroupId = '',
30
+ targetBotId = '',
34
31
  enabled = true,
35
- title,
36
- subtitle,
37
- avatarUri,
38
- avatarFullName,
39
32
  showAddMember,
40
- getSubtitle,
41
33
  onBack,
42
34
  onPressSearch,
43
35
  onPressAddMember,
@@ -45,10 +37,20 @@ const ChatDetail = memo(
45
37
  onPressAvatar,
46
38
  onPressUrl,
47
39
  customMessageItemFactory,
40
+ pannelActions,
48
41
  }: ChatDetailProps) => {
49
42
  const navigation = useNavigation();
50
43
  const mediaViewerRef = useRef<MediaViewerModalHandle>(null);
51
44
  const messageToolboxRef = useRef<MessageToolboxRef>(null);
45
+
46
+ const { conversationId, isLoading: isLoadingConversation } =
47
+ useGetConversationDetail({
48
+ targetConversationId,
49
+ targetUserId,
50
+ targetGroupId,
51
+ targetBotId,
52
+ });
53
+
52
54
  const conversation = useConversation(conversationId);
53
55
 
54
56
  const handleBackDefault = useCallback(() => {
@@ -75,31 +77,16 @@ const ChatDetail = memo(
75
77
  } = useChatMessages({ conversationId, enabled });
76
78
 
77
79
  useEffect(() => {
78
- useConversationStore.getState().setCurrentConversation(conversationId);
80
+ if (conversationId) {
81
+ useConversationStore.getState().setCurrentConversation(conversationId);
82
+ }
83
+ return () => {
84
+ useConversationStore.getState().setCurrentConversation(undefined);
85
+ };
79
86
  }, [conversationId]);
80
87
 
81
- // useEffect(() => {
82
- // if (!conversationId) return;
83
- // ChatMessageAPI.searchLocalMessages(conversationId, { count: 20 })
84
- // .then((result) => {
85
- // console.log('[TEST searchLocalMessages] success:', result);
86
- // })
87
- // .catch((err) => {
88
- // console.log('[TEST searchLocalMessages] error:', err);
89
- // });
90
- // }, [conversationId]);
91
-
92
- const resolvedTitle = title ?? getConversationTitle(conversation);
93
- const resolvedAvatarUri =
94
- avatarUri ?? getConversationAvatarUri(conversation);
95
- const resolvedAvatarFullName = avatarFullName ?? resolvedTitle;
96
88
  const resolvedShowAddMember =
97
89
  showAddMember ?? shouldShowAddMember(conversation);
98
- const resolvedSubtitle = useMemo(() => {
99
- if (subtitle !== undefined) return subtitle;
100
- if (getSubtitle && conversation) return getSubtitle(conversation);
101
- return getConversationSubtitle(conversation);
102
- }, [conversation, getSubtitle, subtitle]);
103
90
 
104
91
  const insets = useSafeAreaInsets();
105
92
 
@@ -123,51 +110,48 @@ const ChatDetail = memo(
123
110
  );
124
111
 
125
112
  return (
126
- <ChatDetailProvider>
127
- <KContainer.Page flex edges={['bottom']}>
128
- <ChatDetailHeader
129
- conversationId={conversationId}
130
- title={resolvedTitle}
131
- subtitle={resolvedSubtitle}
132
- avatarUri={resolvedAvatarUri}
133
- avatarFullName={resolvedAvatarFullName}
134
- showAddMember={resolvedShowAddMember}
135
- onBack={onBack ?? handleBackDefault}
136
- onPressSearch={onPressSearch}
137
- onPressAddMember={onPressAddMember}
138
- onPressMenu={onPressMenu}
139
- onPressAvatar={onPressAvatar}
140
- />
141
-
142
- <KeyboardAvoidingView
143
- style={styles.keyboardAvoiding}
144
- behavior="padding"
145
- keyboardVerticalOffset={keyboardVerticalOffset}
146
- >
147
- <ChatListLegend
148
- messages={messages}
149
- currentUserId={currentUserId}
150
- customMessageItemFactory={customMessageItemFactory}
151
- onLoadEarlier={onLoadEarlier}
152
- isLoading={isLoading}
153
- isLoadingEarlier={isLoadingEarlier}
154
- hasMoreEarlier={hasMoreEarlier}
155
- onMediaPress={handleMediaPress}
156
- onPressUrl={handlePressUrl}
157
- onLongPress={handleMessageLongPress}
158
- />
159
-
160
- <ChatComposer isEmptyMessage={messages?.length === 0} />
161
- </KeyboardAvoidingView>
162
-
163
- <MediaViewerModal ref={mediaViewerRef} />
164
- <MessageToolboxOverlay
165
- ref={messageToolboxRef}
113
+ <KContainer.Page flex edges={['bottom']}>
114
+ <ChatDetailHeader
115
+ conversationId={conversationId}
116
+ showAddMember={resolvedShowAddMember}
117
+ onBack={onBack ?? handleBackDefault}
118
+ onPressSearch={onPressSearch}
119
+ onPressAddMember={onPressAddMember}
120
+ onPressMenu={onPressMenu}
121
+ onPressAvatar={onPressAvatar}
122
+ />
123
+
124
+ <KeyboardAvoidingView
125
+ style={styles.keyboardAvoiding}
126
+ behavior="padding"
127
+ keyboardVerticalOffset={keyboardVerticalOffset}
128
+ >
129
+ <ChatListLegend
130
+ messages={messages}
166
131
  currentUserId={currentUserId}
167
132
  customMessageItemFactory={customMessageItemFactory}
133
+ onLoadEarlier={onLoadEarlier}
134
+ isLoading={isLoading || isLoadingConversation}
135
+ isLoadingEarlier={isLoadingEarlier}
136
+ hasMoreEarlier={hasMoreEarlier}
137
+ onMediaPress={handleMediaPress}
138
+ onPressUrl={handlePressUrl}
139
+ onLongPress={handleMessageLongPress}
140
+ />
141
+
142
+ <ChatComposer
143
+ isEmptyMessage={messages?.length === 0}
144
+ pannelActions={pannelActions}
168
145
  />
169
- </KContainer.Page>
170
- </ChatDetailProvider>
146
+ </KeyboardAvoidingView>
147
+
148
+ <MediaViewerModal ref={mediaViewerRef} />
149
+ <MessageToolboxOverlay
150
+ ref={messageToolboxRef}
151
+ currentUserId={currentUserId}
152
+ customMessageItemFactory={customMessageItemFactory}
153
+ />
154
+ </KContainer.Page>
171
155
  );
172
156
  }
173
157
  );
@@ -10,13 +10,10 @@ import { AvatarSection } from '../../components/ThreadCard/AvatarSection';
10
10
  import { NamePrefixIcon } from '../../components/ThreadCard/NamePrefixIcon';
11
11
  import type { ChatDetailHeaderProps } from './types';
12
12
  import { useConversation } from '../../store';
13
+ import { getConversationSubtitle } from './conversationHeader.utils';
13
14
 
14
15
  const ChatDetailHeader = memo(
15
16
  ({
16
- title,
17
- subtitle,
18
- avatarUri,
19
- avatarFullName,
20
17
  showAddMember = false,
21
18
  conversationId,
22
19
  onBack,
@@ -79,8 +76,8 @@ const ChatDetailHeader = memo(
79
76
  activeOpacity={0.7}
80
77
  >
81
78
  <AvatarSection
82
- avatar={avatarUri ?? null}
83
- fullName={avatarFullName ?? title}
79
+ avatar={conversation?.faceURL ?? null}
80
+ fullName={conversation?.showName || ''}
84
81
  peerType={conversation?.peerType}
85
82
  />
86
83
 
@@ -93,31 +90,23 @@ const ChatDetailHeader = memo(
93
90
  numberOfLines={1}
94
91
  flex
95
92
  >
96
- {title}
93
+ {conversation?.showName || ''}
97
94
  </KLabel.Text>
98
95
  </KContainer.View>
99
- {!!subtitle && (
96
+ {!!conversation && (
100
97
  <KLabel.Text
101
98
  typo="TextSmNormal"
102
99
  color={KColors.palette.gray.w500}
103
100
  numberOfLines={1}
104
101
  >
105
- {subtitle}
102
+ {getConversationSubtitle(conversation)}
106
103
  </KLabel.Text>
107
104
  )}
108
105
  </KContainer.View>
109
106
  </KContainer.Touchable>
110
107
  </KContainer.View>
111
108
  ),
112
- [
113
- avatarFullName,
114
- avatarUri,
115
- onBack,
116
- onPressAvatar,
117
- subtitle,
118
- title,
119
- conversation?.peerType,
120
- ]
109
+ [onBack, onPressAvatar, conversation]
121
110
  );
122
111
 
123
112
  return (
@@ -374,7 +374,7 @@ export const ChatListLegend = memo(
374
374
  renderItem={renderItem}
375
375
  estimatedItemSize={avgItemHeightRef.current}
376
376
  keyExtractor={(item) => String(item.clientMsgID || item.serverMsgID)}
377
- recycleItems={true}
377
+ recycleItems={false}
378
378
  extraData={`${conversationFlow?.flowCurrentStep?.id ?? ''}-${lastMessageId ?? ''}`}
379
379
  alignItemsAtEnd
380
380
  maintainVisibleContentPosition={maintainVisiblePositionConfig}
@@ -1,10 +1,9 @@
1
1
  import { memo } from 'react';
2
2
  import { ActivityIndicator } from 'react-native';
3
3
  import { KContainer, KColors } from '@droppii/libs';
4
- import type { LoadEarlierMessagesProps } from 'react-native-gifted-chat';
5
4
 
6
5
  export const ChatLoadEarlier = memo(
7
- ({ isLoading = false }: LoadEarlierMessagesProps) => {
6
+ ({ isLoading = false }: { isLoading: boolean }) => {
8
7
  if (!isLoading) {
9
8
  return null;
10
9
  }
@@ -8,7 +8,11 @@ import {
8
8
  KSpacingValue,
9
9
  } from '@droppii/libs';
10
10
  import { useChatActionPress } from './useChatActionPress';
11
- import type { DChatQuickAction, ChatQuickActionsProps } from './types';
11
+ import {
12
+ type DChatQuickAction,
13
+ type ChatQuickActionsProps,
14
+ DChatQuickActionItemType,
15
+ } from './types';
12
16
  import { useResetFlow } from '../../hooks/flows/useFlow';
13
17
 
14
18
  const QuickActionItem = memo(
@@ -76,7 +80,7 @@ export const ChatQuickActions = memo(
76
80
  ({ item }) => {
77
81
  const onPress = () => {
78
82
  handleActionPress(item);
79
- if (item.id === 'restart') {
83
+ if (item.id === DChatQuickActionItemType.Restart) {
80
84
  resetFlow?.();
81
85
  }
82
86
  };
@@ -1,5 +1,11 @@
1
1
  import { KColors } from '@droppii/libs';
2
- import type { DChatQuickAction, DChatAttachmentAction } from './types';
2
+ import {
3
+ type DChatQuickAction,
4
+ type DChatPannelAction,
5
+ DChatQuickActionItemType,
6
+ DChatPannelActionItemType,
7
+ } from './types';
8
+ import { trans } from '../../translation';
3
9
  import { opacityToSolid } from '../../utils/ui';
4
10
 
5
11
  export const CHAT_BUBBLE_COLORS = {
@@ -10,19 +16,19 @@ export const CHAT_BUBBLE_COLORS = {
10
16
  dayLabel: KColors.gray.light,
11
17
  } as const;
12
18
 
13
- export const DEFAULT_Chat_QUICK_ACTIONS: DChatQuickAction[] = [
19
+ export const DEFAULT_QUICK_ACTIONS: DChatQuickAction[] = [
14
20
  {
15
- id: 'restart',
21
+ id: DChatQuickActionItemType.Restart,
16
22
  label: 'Bắt đầu lại',
17
23
  iconName: 'refresh',
18
24
  },
19
25
  {
20
- id: 'send-order',
26
+ id: DChatQuickActionItemType.SendOrder,
21
27
  label: 'Gửi đơn hàng',
22
28
  iconName: 'file-document-outline',
23
29
  },
24
30
  {
25
- id: 'scam-warning',
31
+ id: DChatQuickActionItemType.ScamWarning,
26
32
  label: 'Cảnh báo lừa đảo/g...',
27
33
  iconName: 'alert-outline',
28
34
  },
@@ -43,35 +49,35 @@ export const getAttachmentPanelHeight = (
43
49
  /** @deprecated use getAttachmentPanelHeight */
44
50
  export const DEFAULT_ATTACHMENT_PANEL_HEIGHT = getAttachmentPanelHeight(6);
45
51
 
46
- export const DEFAULT_ATTACHMENT_ACTIONS: DChatAttachmentAction[] = [
52
+ export const DEFAULT_PANNEL_ACTIONS: DChatPannelAction[] = [
47
53
  {
48
- id: 'gallery',
49
- label: 'Ảnh/Video',
54
+ id: DChatPannelActionItemType.Gallery,
55
+ label: trans('gallery'),
50
56
  iconName: 'image-02-o',
51
57
  },
52
58
  {
53
- id: 'camera',
54
- label: 'Chụp ảnh',
59
+ id: DChatPannelActionItemType.Camera,
60
+ label: trans('camera'),
55
61
  iconName: 'camera-o',
56
62
  },
57
63
  {
58
- id: 'file',
59
- label: 'Tài liệu',
64
+ id: DChatPannelActionItemType.Documents,
65
+ label: trans('documents'),
60
66
  iconName: 'paperclip-o',
61
67
  },
62
- {
63
- id: 'order',
64
- label: 'Gửi đơn hàng',
65
- iconName: 'receipt-o',
66
- },
67
- {
68
- id: 'product',
69
- label: 'Gửi sản phẩm',
70
- iconName: 'shopping-basket-o',
71
- },
72
- {
73
- id: 'calendar',
74
- label: 'Tạo lịch hẹn',
75
- iconName: 'calendar-active-o',
76
- },
68
+ // {
69
+ // id: DChatPannelActionItemType.SendOrder,
70
+ // label: trans('send_order'),
71
+ // iconName: 'receipt-o',
72
+ // },
73
+ // {
74
+ // id: DChatPannelActionItemType.SendProduct,
75
+ // label: trans('send_product'),
76
+ // iconName: 'shopping-basket-o',
77
+ // },
78
+ // {
79
+ // id: DChatPannelActionItemType.CreateAppointment,
80
+ // label: trans('create_appointment'),
81
+ // iconName: 'calendar-active-o',
82
+ // },
77
83
  ];
@@ -4,8 +4,8 @@ export { ChatComposer } from './ChatComposer';
4
4
  export { ChatQuickActions } from './ChatQuickActions';
5
5
  export { ChatAttachmentPanel } from './ChatAttachmentPanel';
6
6
  export {
7
- DEFAULT_Chat_QUICK_ACTIONS,
8
- DEFAULT_ATTACHMENT_ACTIONS,
7
+ DEFAULT_QUICK_ACTIONS,
8
+ DEFAULT_PANNEL_ACTIONS,
9
9
  DEFAULT_ATTACHMENT_PANEL_HEIGHT,
10
10
  } from './constants';
11
11
  export {
@@ -18,17 +18,14 @@ export type {
18
18
  DChatActionItem,
19
19
  DChatActionIconProvider,
20
20
  DChatQuickAction,
21
- DChatAttachmentAction,
21
+ DChatPannelAction,
22
22
  ChatDetailProps,
23
23
  ChatDetailHeaderProps,
24
24
  ChatListProps,
25
25
  ChatComposerProps,
26
26
  ChatQuickActionsProps,
27
27
  ChatQuickActionsRenderParams,
28
- ChatAttachmentPanelProps,
28
+ ChatPanelProps,
29
29
  } from './types';
30
30
 
31
- export {
32
- DChatMessageType,
33
- CUSTOM_MESSAGE_DATA_TYPE,
34
- } from '../../types/message';
31
+ export { DChatPannelActionItemType, DChatQuickActionItemType } from './types';