@droppii-org/chat-mobile 0.2.80 → 0.2.82

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 (228) hide show
  1. package/lib/module/components/ThreadCard/MentionBadge.js +24 -0
  2. package/lib/module/components/ThreadCard/MentionBadge.js.map +1 -0
  3. package/lib/module/components/ThreadCard/ThreadCard.js +5 -1
  4. package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
  5. package/lib/module/components/messages/linkMessage/LinkPreviewCard.js +67 -0
  6. package/lib/module/components/messages/linkMessage/LinkPreviewCard.js.map +1 -0
  7. package/lib/module/components/messages/linkMessage/index.js +21 -68
  8. package/lib/module/components/messages/linkMessage/index.js.map +1 -1
  9. package/lib/module/components/messages/quotedMessage/QuotedMessagePreviewStrip.js +152 -0
  10. package/lib/module/components/messages/quotedMessage/QuotedMessagePreviewStrip.js.map +1 -0
  11. package/lib/module/components/messages/textMessage/index.js +102 -8
  12. package/lib/module/components/messages/textMessage/index.js.map +1 -1
  13. package/lib/module/config/api-endpoints.js +2 -1
  14. package/lib/module/config/api-endpoints.js.map +1 -1
  15. package/lib/module/core/useChatListener.js +1 -1
  16. package/lib/module/core/useChatListener.js.map +1 -1
  17. package/lib/module/hooks/contacts/useSearchContacts.js +50 -0
  18. package/lib/module/hooks/contacts/useSearchContacts.js.map +1 -0
  19. package/lib/module/hooks/message/useSendMessage.js +64 -3
  20. package/lib/module/hooks/message/useSendMessage.js.map +1 -1
  21. package/lib/module/hooks/query-keys.js +8 -0
  22. package/lib/module/hooks/query-keys.js.map +1 -1
  23. package/lib/module/hooks/useChatCompose.js +3 -2
  24. package/lib/module/hooks/useChatCompose.js.map +1 -1
  25. package/lib/module/screens/SearchConversation/ContactResultItem.js +119 -0
  26. package/lib/module/screens/SearchConversation/ContactResultItem.js.map +1 -0
  27. package/lib/module/screens/SearchConversation/SearchAllResult.js +26 -20
  28. package/lib/module/screens/SearchConversation/SearchAllResult.js.map +1 -1
  29. package/lib/module/screens/SearchConversation/SearchCommunityResult.js +79 -0
  30. package/lib/module/screens/SearchConversation/SearchCommunityResult.js.map +1 -0
  31. package/lib/module/screens/SearchConversation/SearchContactsResult.js +117 -0
  32. package/lib/module/screens/SearchConversation/SearchContactsResult.js.map +1 -0
  33. package/lib/module/screens/SearchConversation/SearchEmpty.js +2 -0
  34. package/lib/module/screens/SearchConversation/SearchEmpty.js.map +1 -1
  35. package/lib/module/screens/SearchConversation/SearchMessagesResult.js +1 -8
  36. package/lib/module/screens/SearchConversation/SearchMessagesResult.js.map +1 -1
  37. package/lib/module/screens/SearchConversation/SearchResultItem.js +2 -0
  38. package/lib/module/screens/SearchConversation/SearchResultItem.js.map +1 -1
  39. package/lib/module/screens/SearchConversation/TabResult.js +24 -7
  40. package/lib/module/screens/SearchConversation/TabResult.js.map +1 -1
  41. package/lib/module/screens/SearchConversation/index.js +6 -2
  42. package/lib/module/screens/SearchConversation/index.js.map +1 -1
  43. package/lib/module/screens/SearchConversation/types.js +1 -0
  44. package/lib/module/screens/SearchConversation/types.js.map +1 -1
  45. package/lib/module/screens/chat-detail/ChatComposer.js +170 -48
  46. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  47. package/lib/module/screens/chat-detail/ChatListLegend.js +1 -0
  48. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  49. package/lib/module/screens/chat-detail/components/ChatMessageInput.js +23 -2
  50. package/lib/module/screens/chat-detail/components/ChatMessageInput.js.map +1 -1
  51. package/lib/module/screens/chat-detail/components/MentionHighlightAdapter.js +51 -0
  52. package/lib/module/screens/chat-detail/components/MentionHighlightAdapter.js.map +1 -0
  53. package/lib/module/screens/chat-detail/components/MentionSuggestionItem.js +49 -0
  54. package/lib/module/screens/chat-detail/components/MentionSuggestionItem.js.map +1 -0
  55. package/lib/module/screens/chat-detail/components/MentionSuggestionList.js +114 -0
  56. package/lib/module/screens/chat-detail/components/MentionSuggestionList.js.map +1 -0
  57. package/lib/module/screens/chat-detail/hooks/useChatComposerState.js +8 -0
  58. package/lib/module/screens/chat-detail/hooks/useChatComposerState.js.map +1 -1
  59. package/lib/module/screens/chat-detail/hooks/useMentionComposer.js +251 -0
  60. package/lib/module/screens/chat-detail/hooks/useMentionComposer.js.map +1 -0
  61. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +5 -1
  62. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  63. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js +11 -1
  64. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js.map +1 -1
  65. package/lib/module/services/endpoints.js +2 -1
  66. package/lib/module/services/endpoints.js.map +1 -1
  67. package/lib/module/services/mentionSearch.js +49 -0
  68. package/lib/module/services/mentionSearch.js.map +1 -0
  69. package/lib/module/services/message.js +6 -1
  70. package/lib/module/services/message.js.map +1 -1
  71. package/lib/module/translation/resources/i18n.js +11 -0
  72. package/lib/module/translation/resources/i18n.js.map +1 -1
  73. package/lib/module/types/chat.js +8 -0
  74. package/lib/module/types/chat.js.map +1 -1
  75. package/lib/module/types/mention.js +2 -0
  76. package/lib/module/types/mention.js.map +1 -0
  77. package/lib/module/utils/dateTimeUtils.js +10 -0
  78. package/lib/module/utils/dateTimeUtils.js.map +1 -1
  79. package/lib/module/utils/highlightSearch.js +6 -2
  80. package/lib/module/utils/highlightSearch.js.map +1 -1
  81. package/lib/module/utils/mentionSerializer.js +113 -0
  82. package/lib/module/utils/mentionSerializer.js.map +1 -0
  83. package/lib/module/utils/mentions/index.js +7 -0
  84. package/lib/module/utils/mentions/index.js.map +1 -0
  85. package/lib/module/utils/mentions/mentionDetector.js +49 -0
  86. package/lib/module/utils/mentions/mentionDetector.js.map +1 -0
  87. package/lib/module/utils/mentions/mentionDiff.js +66 -0
  88. package/lib/module/utils/mentions/mentionDiff.js.map +1 -0
  89. package/lib/module/utils/mentions/mentionRange.js +188 -0
  90. package/lib/module/utils/mentions/mentionRange.js.map +1 -0
  91. package/lib/module/utils/mentions/mentionTokenize.js +50 -0
  92. package/lib/module/utils/mentions/mentionTokenize.js.map +1 -0
  93. package/lib/module/utils/messageUtils.js +16 -3
  94. package/lib/module/utils/messageUtils.js.map +1 -1
  95. package/lib/module/utils/url.js +33 -0
  96. package/lib/module/utils/url.js.map +1 -1
  97. package/lib/typescript/src/components/ThreadCard/MentionBadge.d.ts +7 -0
  98. package/lib/typescript/src/components/ThreadCard/MentionBadge.d.ts.map +1 -0
  99. package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
  100. package/lib/typescript/src/components/messages/linkMessage/LinkPreviewCard.d.ts +16 -0
  101. package/lib/typescript/src/components/messages/linkMessage/LinkPreviewCard.d.ts.map +1 -0
  102. package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
  103. package/lib/typescript/src/components/messages/quotedMessage/QuotedMessagePreviewStrip.d.ts +13 -0
  104. package/lib/typescript/src/components/messages/quotedMessage/QuotedMessagePreviewStrip.d.ts.map +1 -0
  105. package/lib/typescript/src/components/messages/textMessage/index.d.ts +3 -1
  106. package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -1
  107. package/lib/typescript/src/config/api-endpoints.d.ts +1 -0
  108. package/lib/typescript/src/config/api-endpoints.d.ts.map +1 -1
  109. package/lib/typescript/src/hooks/contacts/useSearchContacts.d.ts +221 -0
  110. package/lib/typescript/src/hooks/contacts/useSearchContacts.d.ts.map +1 -0
  111. package/lib/typescript/src/hooks/message/useSendMessage.d.ts +5 -2
  112. package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
  113. package/lib/typescript/src/hooks/query-keys.d.ts +8 -0
  114. package/lib/typescript/src/hooks/query-keys.d.ts.map +1 -1
  115. package/lib/typescript/src/hooks/useChatCompose.d.ts +2 -1
  116. package/lib/typescript/src/hooks/useChatCompose.d.ts.map +1 -1
  117. package/lib/typescript/src/screens/SearchConversation/ContactResultItem.d.ts +9 -0
  118. package/lib/typescript/src/screens/SearchConversation/ContactResultItem.d.ts.map +1 -0
  119. package/lib/typescript/src/screens/SearchConversation/SearchAllResult.d.ts +3 -2
  120. package/lib/typescript/src/screens/SearchConversation/SearchAllResult.d.ts.map +1 -1
  121. package/lib/typescript/src/screens/SearchConversation/SearchCommunityResult.d.ts +7 -0
  122. package/lib/typescript/src/screens/SearchConversation/SearchCommunityResult.d.ts.map +1 -0
  123. package/lib/typescript/src/screens/SearchConversation/SearchContactsResult.d.ts +8 -0
  124. package/lib/typescript/src/screens/SearchConversation/SearchContactsResult.d.ts.map +1 -0
  125. package/lib/typescript/src/screens/SearchConversation/SearchEmpty.d.ts.map +1 -1
  126. package/lib/typescript/src/screens/SearchConversation/SearchMessagesResult.d.ts.map +1 -1
  127. package/lib/typescript/src/screens/SearchConversation/SearchResultItem.d.ts.map +1 -1
  128. package/lib/typescript/src/screens/SearchConversation/TabResult.d.ts +4 -2
  129. package/lib/typescript/src/screens/SearchConversation/TabResult.d.ts.map +1 -1
  130. package/lib/typescript/src/screens/SearchConversation/index.d.ts +4 -2
  131. package/lib/typescript/src/screens/SearchConversation/index.d.ts.map +1 -1
  132. package/lib/typescript/src/screens/SearchConversation/types.d.ts +2 -1
  133. package/lib/typescript/src/screens/SearchConversation/types.d.ts.map +1 -1
  134. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  135. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
  136. package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts +10 -2
  137. package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts.map +1 -1
  138. package/lib/typescript/src/screens/chat-detail/components/MentionHighlightAdapter.d.ts +29 -0
  139. package/lib/typescript/src/screens/chat-detail/components/MentionHighlightAdapter.d.ts.map +1 -0
  140. package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionItem.d.ts +8 -0
  141. package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionItem.d.ts.map +1 -0
  142. package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionList.d.ts +12 -0
  143. package/lib/typescript/src/screens/chat-detail/components/MentionSuggestionList.d.ts.map +1 -0
  144. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts +1 -1
  145. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts.map +1 -1
  146. package/lib/typescript/src/screens/chat-detail/hooks/useMentionComposer.d.ts +48 -0
  147. package/lib/typescript/src/screens/chat-detail/hooks/useMentionComposer.d.ts.map +1 -0
  148. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  149. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts.map +1 -1
  150. package/lib/typescript/src/services/endpoints.d.ts +1 -0
  151. package/lib/typescript/src/services/endpoints.d.ts.map +1 -1
  152. package/lib/typescript/src/services/mentionSearch.d.ts +15 -0
  153. package/lib/typescript/src/services/mentionSearch.d.ts.map +1 -0
  154. package/lib/typescript/src/services/message.d.ts +1 -1
  155. package/lib/typescript/src/services/message.d.ts.map +1 -1
  156. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  157. package/lib/typescript/src/types/chat.d.ts +50 -0
  158. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  159. package/lib/typescript/src/types/mention.d.ts +65 -0
  160. package/lib/typescript/src/types/mention.d.ts.map +1 -0
  161. package/lib/typescript/src/utils/dateTimeUtils.d.ts +2 -0
  162. package/lib/typescript/src/utils/dateTimeUtils.d.ts.map +1 -1
  163. package/lib/typescript/src/utils/highlightSearch.d.ts.map +1 -1
  164. package/lib/typescript/src/utils/mentionSerializer.d.ts +78 -0
  165. package/lib/typescript/src/utils/mentionSerializer.d.ts.map +1 -0
  166. package/lib/typescript/src/utils/mentions/index.d.ts +5 -0
  167. package/lib/typescript/src/utils/mentions/index.d.ts.map +1 -0
  168. package/lib/typescript/src/utils/mentions/mentionDetector.d.ts +18 -0
  169. package/lib/typescript/src/utils/mentions/mentionDetector.d.ts.map +1 -0
  170. package/lib/typescript/src/utils/mentions/mentionDiff.d.ts +20 -0
  171. package/lib/typescript/src/utils/mentions/mentionDiff.d.ts.map +1 -0
  172. package/lib/typescript/src/utils/mentions/mentionRange.d.ts +86 -0
  173. package/lib/typescript/src/utils/mentions/mentionRange.d.ts.map +1 -0
  174. package/lib/typescript/src/utils/mentions/mentionTokenize.d.ts +29 -0
  175. package/lib/typescript/src/utils/mentions/mentionTokenize.d.ts.map +1 -0
  176. package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -1
  177. package/lib/typescript/src/utils/url.d.ts +12 -0
  178. package/lib/typescript/src/utils/url.d.ts.map +1 -1
  179. package/package.json +3 -1
  180. package/src/build-ignore.d.ts +2 -0
  181. package/src/components/ThreadCard/MentionBadge.tsx +28 -0
  182. package/src/components/ThreadCard/ThreadCard.tsx +3 -0
  183. package/src/components/messages/linkMessage/LinkPreviewCard.tsx +92 -0
  184. package/src/components/messages/linkMessage/index.tsx +25 -89
  185. package/src/components/messages/quotedMessage/QuotedMessagePreviewStrip.tsx +168 -0
  186. package/src/components/messages/textMessage/index.tsx +124 -4
  187. package/src/config/api-endpoints.ts +2 -0
  188. package/src/core/useChatListener.ts +1 -1
  189. package/src/hooks/contacts/useSearchContacts.ts +66 -0
  190. package/src/hooks/message/useSendMessage.ts +60 -1
  191. package/src/hooks/query-keys.ts +12 -0
  192. package/src/hooks/useChatCompose.ts +115 -107
  193. package/src/screens/SearchConversation/ContactResultItem.tsx +128 -0
  194. package/src/screens/SearchConversation/SearchAllResult.tsx +38 -24
  195. package/src/screens/SearchConversation/SearchCommunityResult.tsx +96 -0
  196. package/src/screens/SearchConversation/SearchContactsResult.tsx +155 -0
  197. package/src/screens/SearchConversation/SearchEmpty.tsx +2 -0
  198. package/src/screens/SearchConversation/SearchMessagesResult.tsx +1 -6
  199. package/src/screens/SearchConversation/SearchResultItem.tsx +6 -1
  200. package/src/screens/SearchConversation/TabResult.tsx +40 -5
  201. package/src/screens/SearchConversation/index.tsx +10 -2
  202. package/src/screens/SearchConversation/types.tsx +1 -0
  203. package/src/screens/chat-detail/ChatComposer.tsx +201 -67
  204. package/src/screens/chat-detail/ChatListLegend.tsx +1 -0
  205. package/src/screens/chat-detail/components/ChatMessageInput.tsx +35 -2
  206. package/src/screens/chat-detail/components/MentionHighlightAdapter.tsx +57 -0
  207. package/src/screens/chat-detail/components/MentionSuggestionItem.tsx +53 -0
  208. package/src/screens/chat-detail/components/MentionSuggestionList.tsx +133 -0
  209. package/src/screens/chat-detail/hooks/useChatComposerState.ts +7 -1
  210. package/src/screens/chat-detail/hooks/useMentionComposer.ts +344 -0
  211. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +7 -1
  212. package/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.tsx +22 -4
  213. package/src/services/endpoints.ts +1 -0
  214. package/src/services/mentionSearch.ts +57 -0
  215. package/src/services/message.ts +9 -1
  216. package/src/translation/resources/i18n.ts +12 -0
  217. package/src/types/chat.ts +52 -0
  218. package/src/types/mention.ts +70 -0
  219. package/src/utils/dateTimeUtils.ts +15 -0
  220. package/src/utils/highlightSearch.ts +12 -2
  221. package/src/utils/mentionSerializer.ts +155 -0
  222. package/src/utils/mentions/index.ts +16 -0
  223. package/src/utils/mentions/mentionDetector.ts +58 -0
  224. package/src/utils/mentions/mentionDiff.ts +95 -0
  225. package/src/utils/mentions/mentionRange.ts +207 -0
  226. package/src/utils/mentions/mentionTokenize.ts +53 -0
  227. package/src/utils/messageUtils.ts +21 -10
  228. package/src/utils/url.ts +30 -0
@@ -10,41 +10,56 @@ import {
10
10
  import { memo, useCallback, useMemo } from 'react';
11
11
  import { useChatContext } from '../../context';
12
12
  import { useSearchMessage } from '../../hooks/message/useSearchMessage';
13
+ import { useSearchContacts } from '../../hooks/contacts/useSearchContacts';
13
14
  import { SearchConversationTabResultType } from './types';
14
- import type { ISearchMessageItem } from '../../types/chat';
15
+ import type { IContactSearchItem, ISearchMessageItem } from '../../types/chat';
15
16
  import { trans } from '../../translation';
16
17
  import { ActivityIndicator, FlatList, StyleSheet } from 'react-native';
17
18
  import { SearchEmpty } from './SearchEmpty';
18
19
  import SearchResultItem from './SearchResultItem';
20
+ import ContactResultItem from './ContactResultItem';
19
21
 
20
22
  interface SearchAllResultProps {
21
23
  searchTerm: string;
22
24
  handleChangeTab: (key: SearchConversationTabResultType) => void;
23
25
  onPressItem?: (item: ISearchMessageItem) => void;
26
+ onPressSearchContact?: (item: IContactSearchItem) => void;
24
27
  }
25
28
 
26
29
  interface ISearchAllResultItem {
27
30
  type: SearchConversationTabResultType;
28
- data: ISearchMessageItem[];
31
+ data: (ISearchMessageItem | IContactSearchItem)[];
29
32
  title: string;
30
33
  }
31
34
 
32
35
  const PAGE_SIZE = 5;
33
36
 
34
37
  const SearchAllResult = memo(
35
- ({ searchTerm, handleChangeTab, onPressItem }: SearchAllResultProps) => {
38
+ ({
39
+ searchTerm,
40
+ handleChangeTab,
41
+ onPressItem,
42
+ onPressSearchContact,
43
+ }: SearchAllResultProps) => {
36
44
  const { applicationType } = useChatContext();
37
- const { dataFlatten: messagesData, isFetching } = useSearchMessage({
38
- query: searchTerm,
39
- applicationType,
40
- pageSize: PAGE_SIZE,
41
- });
45
+ const { dataFlatten: messagesData, isFetching: isFetchingMessages } =
46
+ useSearchMessage({
47
+ query: searchTerm,
48
+ applicationType,
49
+ pageSize: PAGE_SIZE,
50
+ });
51
+ const { dataFlatten: contactsData, isFetching: isFetchingContacts } =
52
+ useSearchContacts({
53
+ query: searchTerm,
54
+ applicationType,
55
+ });
56
+ const isFetching = isFetchingMessages || isFetchingContacts;
42
57
 
43
58
  const data: ISearchAllResultItem[] = useMemo(() => {
44
59
  const mData = [
45
60
  {
46
61
  type: SearchConversationTabResultType.Conversations,
47
- data: [],
62
+ data: contactsData,
48
63
  title: trans('contacts'),
49
64
  },
50
65
  {
@@ -54,7 +69,7 @@ const SearchAllResult = memo(
54
69
  },
55
70
  ]?.filter((item) => item.data.length > 0);
56
71
  return mData;
57
- }, [messagesData]);
72
+ }, [messagesData, contactsData]);
58
73
 
59
74
  const onChangeTab = useCallback(
60
75
  (key: SearchConversationTabResultType) => {
@@ -80,21 +95,24 @@ const SearchAllResult = memo(
80
95
  </KLabel.Text>
81
96
  <KImage.VectorIcons name="angle-right-o" size={20} />
82
97
  </KContainer.Touchable>
83
- {item?.data?.map((childItem) => {
84
- return (
85
- <KContainer.View
86
- style={styles.childItemContainer}
87
- key={`${item.type}-${childItem?.conversation?.conversationID}-${childItem?.chatLog?.clientMsgID}`}
88
- >
98
+ {item.type === SearchConversationTabResultType.Conversations
99
+ ? (item.data as IContactSearchItem[]).map((childItem) => (
100
+ <ContactResultItem
101
+ key={`${item.type}-${childItem?.id}`}
102
+ item={childItem}
103
+ onPressSearchContact={onPressSearchContact}
104
+ searchTerm={searchTerm}
105
+ />
106
+ ))
107
+ : (item.data as ISearchMessageItem[]).map((childItem) => (
89
108
  <SearchResultItem
109
+ key={`${item.type}-${childItem?.conversation?.conversationID}-${childItem?.chatLog?.clientMsgID}`}
90
110
  item={childItem}
91
111
  tabResultType={item.type}
92
112
  onPressItem={onPressItem}
93
113
  searchTerm={searchTerm}
94
114
  />
95
- </KContainer.View>
96
- );
97
- })}
115
+ ))}
98
116
  <KButton.Link
99
117
  label={trans('view_all')}
100
118
  icon={{
@@ -108,7 +126,7 @@ const SearchAllResult = memo(
108
126
  </KContainer.View>
109
127
  );
110
128
  },
111
- [onChangeTab, onPressItem, searchTerm]
129
+ [onChangeTab, onPressItem, onPressSearchContact, searchTerm]
112
130
  );
113
131
 
114
132
  const keyExtractor = useCallback((item: ISearchAllResultItem) => {
@@ -158,10 +176,6 @@ const styles = StyleSheet.create({
158
176
  borderBottomWidth: 1,
159
177
  borderBottomColor: KColors.border.light,
160
178
  },
161
- childItemContainer: {
162
- borderBottomWidth: 1,
163
- borderBottomColor: KColors.border.light,
164
- },
165
179
  viewAllButton: {
166
180
  height: 40,
167
181
  },
@@ -0,0 +1,96 @@
1
+ import { KColors, KContainer, KSpacingValue } from '@droppii/libs';
2
+ import { memo, useCallback, useMemo } from 'react';
3
+ import { ActivityIndicator, FlatList, StyleSheet } from 'react-native';
4
+ import isEmpty from 'lodash/isEmpty';
5
+ import type { SearchPublicGroupInfo } from '@droppii/openim-rn-client-sdk';
6
+ import { useFetchPublicGroup } from '../../hooks/groups/useFetchPublicGroup';
7
+ import { GroupItem } from '../../components/GroupItem';
8
+ import { SearchEmpty } from './SearchEmpty';
9
+ import { SearchConversationTabResultType } from './types';
10
+
11
+ interface ISearchCommunityResultProps {
12
+ searchTerm: string;
13
+ onPressGroup?: (groupId: string) => void;
14
+ }
15
+
16
+ const keyExtractor = (item: SearchPublicGroupInfo) => item.groupID;
17
+
18
+ const SearchCommunityResult = memo(
19
+ ({ searchTerm, onPressGroup }: ISearchCommunityResultProps) => {
20
+ const hasKeyword = !isEmpty(searchTerm?.trim());
21
+
22
+ const {
23
+ dataFlatten,
24
+ hasNextPage,
25
+ fetchNextPage,
26
+ isFetchingNextPage,
27
+ isFetching,
28
+ isRefetching,
29
+ refetch,
30
+ } = useFetchPublicGroup(searchTerm);
31
+
32
+ const data = useMemo(
33
+ () => (hasKeyword ? dataFlatten : []),
34
+ [hasKeyword, dataFlatten]
35
+ );
36
+
37
+ const renderItem = useCallback(
38
+ ({ item }: { item: SearchPublicGroupInfo }) => (
39
+ <GroupItem item={item} onPress={onPressGroup} />
40
+ ),
41
+ [onPressGroup]
42
+ );
43
+
44
+ const onEndReached = useCallback(() => {
45
+ if (hasKeyword && hasNextPage && !isFetchingNextPage) {
46
+ fetchNextPage();
47
+ }
48
+ }, [hasKeyword, hasNextPage, isFetchingNextPage, fetchNextPage]);
49
+
50
+ if (!hasKeyword) {
51
+ return (
52
+ <KContainer.View flex>
53
+ <SearchEmpty
54
+ searchTerm={searchTerm}
55
+ searchType={SearchConversationTabResultType.Community}
56
+ />
57
+ </KContainer.View>
58
+ );
59
+ }
60
+
61
+ return (
62
+ <KContainer.View flex>
63
+ {isFetching && !isFetchingNextPage && !isRefetching ? (
64
+ <KContainer.View flex center>
65
+ <ActivityIndicator color={KColors.primary.normal} size={'small'} />
66
+ </KContainer.View>
67
+ ) : (
68
+ <FlatList
69
+ data={data}
70
+ renderItem={renderItem}
71
+ keyExtractor={keyExtractor}
72
+ contentContainerStyle={styles.container}
73
+ showsVerticalScrollIndicator={false}
74
+ onEndReached={onEndReached}
75
+ ListEmptyComponent={
76
+ <SearchEmpty
77
+ searchTerm={searchTerm}
78
+ searchType={SearchConversationTabResultType.Community}
79
+ />
80
+ }
81
+ refreshing={isFetching}
82
+ onRefresh={refetch}
83
+ />
84
+ )}
85
+ </KContainer.View>
86
+ );
87
+ }
88
+ );
89
+
90
+ export default SearchCommunityResult;
91
+
92
+ const styles = StyleSheet.create({
93
+ container: {
94
+ paddingHorizontal: KSpacingValue['0.75rem'],
95
+ },
96
+ });
@@ -0,0 +1,155 @@
1
+ import {
2
+ KColors,
3
+ KContainer,
4
+ KSpacingValue,
5
+ KTagsChoiceSlideBar,
6
+ type KTagsChoiceSlideBarItemProps,
7
+ } from '@droppii/libs';
8
+ import { memo, useCallback, useMemo, useState } from 'react';
9
+ import { ActivityIndicator, FlatList, StyleSheet } from 'react-native';
10
+ import { useChatContext } from '../../context';
11
+ import { useSearchContacts } from '../../hooks/contacts/useSearchContacts';
12
+ import { ContactCategory, type IContactSearchItem } from '../../types/chat';
13
+ import { trans } from '../../translation';
14
+ import { SearchEmpty } from './SearchEmpty';
15
+ import ContactResultItem from './ContactResultItem';
16
+ import { SearchConversationTabResultType } from './types';
17
+
18
+ interface ISearchContactsResultProps {
19
+ searchTerm: string;
20
+ onPressSearchContact?: (item: IContactSearchItem) => void;
21
+ }
22
+
23
+ const FILTER_ITEMS: KTagsChoiceSlideBarItemProps[] = [
24
+ {
25
+ id: ContactCategory.Customer,
26
+ label: trans('contact_type:customer'),
27
+ allowDeselect: true,
28
+ },
29
+ {
30
+ id: ContactCategory.Pdp,
31
+ label: trans('contact_type:pdp'),
32
+ allowDeselect: true,
33
+ },
34
+ {
35
+ id: ContactCategory.Group,
36
+ label: trans('contact_type:group'),
37
+ allowDeselect: true,
38
+ },
39
+ {
40
+ id: ContactCategory.Seller,
41
+ label: trans('contact_type:seller'),
42
+ allowDeselect: true,
43
+ },
44
+ ];
45
+
46
+ const SearchContactsResult = memo(
47
+ ({ searchTerm, onPressSearchContact }: ISearchContactsResultProps) => {
48
+ const { applicationType } = useChatContext();
49
+ const [contactType, setContactType] = useState<
50
+ ContactCategory | undefined
51
+ >();
52
+
53
+ const {
54
+ dataFlatten,
55
+ hasNextPage,
56
+ fetchNextPage,
57
+ isFetchingNextPage,
58
+ isFetching,
59
+ isRefetching,
60
+ refetch,
61
+ } = useSearchContacts({
62
+ query: searchTerm,
63
+ applicationType,
64
+ type: contactType,
65
+ });
66
+
67
+ const onFilterChanged = useCallback(
68
+ (item?: KTagsChoiceSlideBarItemProps) => {
69
+ setContactType(item?.id as ContactCategory | undefined);
70
+ },
71
+ []
72
+ );
73
+
74
+ const renderItem = useCallback(
75
+ ({ item }: { item: IContactSearchItem }) => {
76
+ return (
77
+ <ContactResultItem
78
+ item={item}
79
+ onPressSearchContact={onPressSearchContact}
80
+ searchTerm={searchTerm}
81
+ />
82
+ );
83
+ },
84
+ [onPressSearchContact, searchTerm]
85
+ );
86
+
87
+ const keyExtractor = useCallback(
88
+ (item: IContactSearchItem) => item?.id,
89
+ []
90
+ );
91
+
92
+ const onEndReached = useCallback(() => {
93
+ if (hasNextPage && !isFetchingNextPage) {
94
+ fetchNextPage();
95
+ }
96
+ }, [hasNextPage, isFetchingNextPage, fetchNextPage]);
97
+
98
+ const ListHeaderComponent = useMemo(
99
+ () => (
100
+ <KContainer.View style={styles.filterContainer}>
101
+ <KTagsChoiceSlideBar
102
+ items={FILTER_ITEMS}
103
+ onChanged={onFilterChanged}
104
+ containerStyle={styles.filterContentContainer}
105
+ type="outline"
106
+ />
107
+ </KContainer.View>
108
+ ),
109
+ [onFilterChanged]
110
+ );
111
+
112
+ return (
113
+ <KContainer.View flex>
114
+ {ListHeaderComponent}
115
+ {isFetching && !isFetchingNextPage && !isRefetching ? (
116
+ <KContainer.View flex center>
117
+ <ActivityIndicator color={KColors.primary.normal} size={'small'} />
118
+ </KContainer.View>
119
+ ) : (
120
+ <FlatList
121
+ data={dataFlatten}
122
+ renderItem={renderItem}
123
+ keyExtractor={keyExtractor}
124
+ contentContainerStyle={styles.container}
125
+ showsVerticalScrollIndicator={false}
126
+ onEndReached={onEndReached}
127
+ ListEmptyComponent={
128
+ <SearchEmpty
129
+ searchTerm={searchTerm}
130
+ searchType={SearchConversationTabResultType.Conversations}
131
+ />
132
+ }
133
+ refreshing={isFetching}
134
+ onRefresh={refetch}
135
+ />
136
+ )}
137
+ </KContainer.View>
138
+ );
139
+ }
140
+ );
141
+
142
+ export default SearchContactsResult;
143
+
144
+ const styles = StyleSheet.create({
145
+ container: {
146
+ paddingHorizontal: KSpacingValue['0.75rem'],
147
+ },
148
+ filterContainer: {
149
+ borderBottomWidth: 1,
150
+ borderBottomColor: KColors.border.light,
151
+ },
152
+ filterContentContainer: {
153
+ padding: 12,
154
+ },
155
+ });
@@ -22,6 +22,8 @@ export const SearchEmpty = memo(
22
22
  return 'search_message:empty_hint';
23
23
  case SearchConversationTabResultType.Conversations:
24
24
  return 'search_conversation:empty_hint';
25
+ case SearchConversationTabResultType.Community:
26
+ return 'search_community:empty_hint';
25
27
  default:
26
28
  return 'search:empty_hint';
27
29
  }
@@ -1,4 +1,4 @@
1
- import { KColors, KContainer, KDivider, KSpacingValue } from '@droppii/libs';
1
+ import { KColors, KContainer, KSpacingValue } from '@droppii/libs';
2
2
  import { memo, useCallback } from 'react';
3
3
  import { useSearchMessage } from '../../hooks/message/useSearchMessage';
4
4
  import { useChatContext } from '../../context';
@@ -52,10 +52,6 @@ const SearchMessagesResult = memo(
52
52
  }
53
53
  }, [hasNextPage, isFetchingNextPage, fetchNextPage]);
54
54
 
55
- const ItemSeparatorComponent = useCallback(() => {
56
- return <KDivider size={'hairline'} vertical={false} />;
57
- }, []);
58
-
59
55
  return (
60
56
  <KContainer.View flex>
61
57
  {isFetching && !isFetchingNextPage && !isRefetching ? (
@@ -70,7 +66,6 @@ const SearchMessagesResult = memo(
70
66
  contentContainerStyle={styles.container}
71
67
  showsVerticalScrollIndicator={false}
72
68
  onEndReached={onEndReached}
73
- ItemSeparatorComponent={ItemSeparatorComponent}
74
69
  ListEmptyComponent={
75
70
  <SearchEmpty
76
71
  searchTerm={searchTerm}
@@ -68,7 +68,12 @@ const SearchResultItem = memo((props: ISearchResultItemProps) => {
68
68
  }, [onPressItem, item?.conversation, item?.chatLog]);
69
69
 
70
70
  return (
71
- <KContainer.Touchable style={styles.container} onPress={handlePressItem}>
71
+ <KContainer.Touchable
72
+ style={styles.container}
73
+ onPress={handlePressItem}
74
+ brBW={1}
75
+ brBC={KColors.border.light}
76
+ >
72
77
  <KContainer.View style={styles.leftContainer}>
73
78
  <AvatarSection
74
79
  avatar={item?.conversation?.faceURL ?? null}
@@ -12,19 +12,30 @@ import { SearchConversationTabResultType } from './types';
12
12
  import { trans } from '../../translation';
13
13
  import SearchMessagesResult from './SearchMessagesResult';
14
14
  import SearchAllResult from './SearchAllResult';
15
- import type { ISearchMessageItem } from '../../types/chat';
15
+ import SearchContactsResult from './SearchContactsResult';
16
+ import SearchCommunityResult from './SearchCommunityResult';
17
+ import type { IContactSearchItem, ISearchMessageItem } from '../../types/chat';
16
18
 
17
19
  type TabRoute = { key: string; title: string };
18
20
 
19
21
  interface ISearchConversationTabResultProps {
20
22
  searchTerm: string;
21
23
  onPressItem?: (item: ISearchMessageItem) => void;
24
+ onPressSearchContact?: (item: IContactSearchItem) => void;
25
+ onPressGroup?: (groupId: string) => void;
22
26
  }
23
27
 
24
28
  const TabRoutes: TabRoute[] = [
25
29
  { key: SearchConversationTabResultType.All, title: trans('all') },
26
- // { key: SearchConversationTabResultType.Conversations, title: trans('contacts') },
30
+ {
31
+ key: SearchConversationTabResultType.Conversations,
32
+ title: trans('contacts'),
33
+ },
27
34
  { key: SearchConversationTabResultType.Messages, title: trans('messages') },
35
+ {
36
+ key: SearchConversationTabResultType.Community,
37
+ title: trans('community'),
38
+ },
28
39
  ];
29
40
 
30
41
  interface CustomTabBarProps {
@@ -58,7 +69,12 @@ const CustomTabBar = memo(({ routes, index, onPress }: CustomTabBarProps) => (
58
69
  ));
59
70
 
60
71
  const SearchConversationTabResult = memo(
61
- ({ searchTerm, onPressItem }: ISearchConversationTabResultProps) => {
72
+ ({
73
+ searchTerm,
74
+ onPressItem,
75
+ onPressSearchContact,
76
+ onPressGroup,
77
+ }: ISearchConversationTabResultProps) => {
62
78
  const [index, setIndex] = useState(0);
63
79
  const [routes] = useState<TabRoute[]>(TabRoutes);
64
80
 
@@ -78,10 +94,16 @@ const SearchConversationTabResult = memo(
78
94
  searchTerm={searchTerm}
79
95
  handleChangeTab={handleChangeTab}
80
96
  onPressItem={onPressItem}
97
+ onPressSearchContact={onPressSearchContact}
81
98
  />
82
99
  );
83
100
  case SearchConversationTabResultType.Conversations:
84
- return null;
101
+ return (
102
+ <SearchContactsResult
103
+ searchTerm={searchTerm}
104
+ onPressSearchContact={onPressSearchContact}
105
+ />
106
+ );
85
107
  case SearchConversationTabResultType.Messages:
86
108
  return (
87
109
  <SearchMessagesResult
@@ -89,11 +111,24 @@ const SearchConversationTabResult = memo(
89
111
  onPressItem={onPressItem}
90
112
  />
91
113
  );
114
+ case SearchConversationTabResultType.Community:
115
+ return (
116
+ <SearchCommunityResult
117
+ searchTerm={searchTerm}
118
+ onPressGroup={onPressGroup}
119
+ />
120
+ );
92
121
  default:
93
122
  return null;
94
123
  }
95
124
  },
96
- [searchTerm, handleChangeTab, onPressItem]
125
+ [
126
+ searchTerm,
127
+ handleChangeTab,
128
+ onPressItem,
129
+ onPressSearchContact,
130
+ onPressGroup,
131
+ ]
97
132
  );
98
133
 
99
134
  const renderTabBar = useCallback(
@@ -5,13 +5,19 @@ import { trans } from '../../translation';
5
5
  import debounce from 'lodash/debounce';
6
6
  import type { TextInput } from 'react-native';
7
7
  import SearchConversationTabResult from './TabResult';
8
- import type { ISearchMessageItem } from '../../types/chat';
8
+ import type { IContactSearchItem, ISearchMessageItem } from '../../types/chat';
9
9
 
10
10
  interface SearchConversationScreenProps {
11
11
  onPressItem?: (item: ISearchMessageItem) => void;
12
+ onPressSearchContact?: (item: IContactSearchItem) => void;
13
+ onPressGroup?: (groupId: string) => void;
12
14
  }
13
15
  const SearchConversationScreen = memo(
14
- ({ onPressItem }: SearchConversationScreenProps) => {
16
+ ({
17
+ onPressItem,
18
+ onPressSearchContact,
19
+ onPressGroup,
20
+ }: SearchConversationScreenProps) => {
15
21
  const nav = useNavigation();
16
22
  const [inputValue, setInputValue] = useState('');
17
23
  const [searchTerm, setSearchTerm] = useState('');
@@ -62,6 +68,8 @@ const SearchConversationScreen = memo(
62
68
  <SearchConversationTabResult
63
69
  searchTerm={searchTerm}
64
70
  onPressItem={onPressItem}
71
+ onPressSearchContact={onPressSearchContact}
72
+ onPressGroup={onPressGroup}
65
73
  />
66
74
  </KContainer.Page>
67
75
  );
@@ -2,4 +2,5 @@ export enum SearchConversationTabResultType {
2
2
  All = 'all',
3
3
  Conversations = 'conversations',
4
4
  Messages = 'messages',
5
+ Community = 'community',
5
6
  }