react-native-chatbot-ai 0.1.19 → 0.1.22

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 (263) hide show
  1. package/lib/module/components/Drawer/DeleteSessionPopup.js +113 -0
  2. package/lib/module/components/Drawer/DeleteSessionPopup.js.map +1 -0
  3. package/lib/module/components/Drawer/DrawerContent.js +21 -8
  4. package/lib/module/components/Drawer/DrawerContent.js.map +1 -1
  5. package/lib/module/components/Drawer/RenameSessionPopup.js +121 -0
  6. package/lib/module/components/Drawer/RenameSessionPopup.js.map +1 -0
  7. package/lib/module/components/Drawer/SearchInput.js +10 -3
  8. package/lib/module/components/Drawer/SearchInput.js.map +1 -1
  9. package/lib/module/components/Drawer/SessionItem.js +36 -20
  10. package/lib/module/components/Drawer/SessionItem.js.map +1 -1
  11. package/lib/module/components/Drawer/SessionList.js +2 -5
  12. package/lib/module/components/Drawer/SessionList.js.map +1 -1
  13. package/lib/module/components/Drawer/SessionOptionsBottomSheet.js +129 -0
  14. package/lib/module/components/Drawer/SessionOptionsBottomSheet.js.map +1 -0
  15. package/lib/module/components/Drawer/ShareSessionPopup.js +132 -0
  16. package/lib/module/components/Drawer/ShareSessionPopup.js.map +1 -0
  17. package/lib/module/components/chat/ChatEmpty.js +15 -4
  18. package/lib/module/components/chat/ChatEmpty.js.map +1 -1
  19. package/lib/module/components/chat/ChatHeader.js +10 -4
  20. package/lib/module/components/chat/ChatHeader.js.map +1 -1
  21. package/lib/module/components/chat/ChatMessageList.js +75 -24
  22. package/lib/module/components/chat/ChatMessageList.js.map +1 -1
  23. package/lib/module/components/chat/SuggestionItem.js +2 -1
  24. package/lib/module/components/chat/SuggestionItem.js.map +1 -1
  25. package/lib/module/components/chat/footer/index.js +77 -15
  26. package/lib/module/components/chat/footer/index.js.map +1 -1
  27. package/lib/module/components/chat/footer/item/UploadImageItem.js +21 -1
  28. package/lib/module/components/chat/footer/item/UploadImageItem.js.map +1 -1
  29. package/lib/module/components/chat/index.js +7 -6
  30. package/lib/module/components/chat/index.js.map +1 -1
  31. package/lib/module/components/chat/item/ChatAIAnswerMessageItem.js +36 -5
  32. package/lib/module/components/chat/item/ChatAIAnswerMessageItem.js.map +1 -1
  33. package/lib/module/components/chat/item/DeeplinkItem.js +30 -2
  34. package/lib/module/components/chat/item/DeeplinkItem.js.map +1 -1
  35. package/lib/module/components/chat/item/MessageActionsBar.js +243 -0
  36. package/lib/module/components/chat/item/MessageActionsBar.js.map +1 -0
  37. package/lib/module/components/chat/item/actions/ActionButton.js +56 -0
  38. package/lib/module/components/chat/item/actions/ActionButton.js.map +1 -0
  39. package/lib/module/components/portal/BottomSheet.js +245 -0
  40. package/lib/module/components/portal/BottomSheet.js.map +1 -0
  41. package/lib/module/components/portal/Popup.js +278 -0
  42. package/lib/module/components/portal/Popup.js.map +1 -0
  43. package/lib/module/components/portal/index.js +11 -5
  44. package/lib/module/components/portal/index.js.map +1 -1
  45. package/lib/module/components/product/CardHorizontal.js +44 -7
  46. package/lib/module/components/product/CardHorizontal.js.map +1 -1
  47. package/lib/module/constants/events.js +33 -0
  48. package/lib/module/constants/events.js.map +1 -1
  49. package/lib/module/constants/index.js +5 -1
  50. package/lib/module/constants/index.js.map +1 -1
  51. package/lib/module/constants/query.js +5 -1
  52. package/lib/module/constants/query.js.map +1 -1
  53. package/lib/module/context/ChatContext.js +9 -3
  54. package/lib/module/context/ChatContext.js.map +1 -1
  55. package/lib/module/hooks/message/useSendMessage.js +21 -3
  56. package/lib/module/hooks/message/useSendMessage.js.map +1 -1
  57. package/lib/module/hooks/message/useStreamMessage.js +10 -3
  58. package/lib/module/hooks/message/useStreamMessage.js.map +1 -1
  59. package/lib/module/hooks/messageActions/index.js +13 -0
  60. package/lib/module/hooks/messageActions/index.js.map +1 -0
  61. package/lib/module/hooks/messageActions/useAudioPlayer.js +269 -0
  62. package/lib/module/hooks/messageActions/useAudioPlayer.js.map +1 -0
  63. package/lib/module/hooks/messageActions/useCopyToClipboard.js +38 -0
  64. package/lib/module/hooks/messageActions/useCopyToClipboard.js.map +1 -0
  65. package/lib/module/hooks/messageActions/useFeedback.js +93 -0
  66. package/lib/module/hooks/messageActions/useFeedback.js.map +1 -0
  67. package/lib/module/hooks/messageActions/useSendFeedback.js +24 -0
  68. package/lib/module/hooks/messageActions/useSendFeedback.js.map +1 -0
  69. package/lib/module/hooks/messageActions/useShareMessage.js +128 -0
  70. package/lib/module/hooks/messageActions/useShareMessage.js.map +1 -0
  71. package/lib/module/hooks/session/useDeleteSession.js +23 -0
  72. package/lib/module/hooks/session/useDeleteSession.js.map +1 -0
  73. package/lib/module/hooks/session/useRenameSession.js +28 -0
  74. package/lib/module/hooks/session/useRenameSession.js.map +1 -0
  75. package/lib/module/hooks/session/useSearchSessions.js +5 -1
  76. package/lib/module/hooks/session/useSearchSessions.js.map +1 -1
  77. package/lib/module/hooks/session/useShareSession.js +16 -0
  78. package/lib/module/hooks/session/useShareSession.js.map +1 -0
  79. package/lib/module/hooks/upload/useImageUpload.js +2 -1
  80. package/lib/module/hooks/upload/useImageUpload.js.map +1 -1
  81. package/lib/module/services/endpoints.js +6 -1
  82. package/lib/module/services/endpoints.js.map +1 -1
  83. package/lib/module/services/index.js +1 -0
  84. package/lib/module/services/index.js.map +1 -1
  85. package/lib/module/services/playbackService.js +22 -0
  86. package/lib/module/services/playbackService.js.map +1 -0
  87. package/lib/module/store/audioPlayer.js +75 -0
  88. package/lib/module/store/audioPlayer.js.map +1 -0
  89. package/lib/module/store/messageActions.js +160 -0
  90. package/lib/module/store/messageActions.js.map +1 -0
  91. package/lib/module/store/session.js +6 -3
  92. package/lib/module/store/session.js.map +1 -1
  93. package/lib/module/translation/index.js +21 -25
  94. package/lib/module/translation/index.js.map +1 -1
  95. package/lib/module/translation/resources/i18n.js +39 -0
  96. package/lib/module/translation/resources/i18n.js.map +1 -0
  97. package/lib/module/types/chat.js +12 -1
  98. package/lib/module/types/chat.js.map +1 -1
  99. package/lib/module/types/index.js +1 -0
  100. package/lib/module/types/index.js.map +1 -1
  101. package/lib/module/types/messageActions.js +56 -0
  102. package/lib/module/types/messageActions.js.map +1 -0
  103. package/lib/module/utils/textCleaner.js +67 -0
  104. package/lib/module/utils/textCleaner.js.map +1 -0
  105. package/lib/module/utils/ui.js +27 -1
  106. package/lib/module/utils/ui.js.map +1 -1
  107. package/lib/typescript/src/components/Drawer/DeleteSessionPopup.d.ts +3 -0
  108. package/lib/typescript/src/components/Drawer/DeleteSessionPopup.d.ts.map +1 -0
  109. package/lib/typescript/src/components/Drawer/DrawerContent.d.ts.map +1 -1
  110. package/lib/typescript/src/components/Drawer/RenameSessionPopup.d.ts +3 -0
  111. package/lib/typescript/src/components/Drawer/RenameSessionPopup.d.ts.map +1 -0
  112. package/lib/typescript/src/components/Drawer/SearchInput.d.ts.map +1 -1
  113. package/lib/typescript/src/components/Drawer/SessionItem.d.ts.map +1 -1
  114. package/lib/typescript/src/components/Drawer/SessionList.d.ts.map +1 -1
  115. package/lib/typescript/src/components/Drawer/SessionOptionsBottomSheet.d.ts +3 -0
  116. package/lib/typescript/src/components/Drawer/SessionOptionsBottomSheet.d.ts.map +1 -0
  117. package/lib/typescript/src/components/Drawer/ShareSessionPopup.d.ts +3 -0
  118. package/lib/typescript/src/components/Drawer/ShareSessionPopup.d.ts.map +1 -0
  119. package/lib/typescript/src/components/chat/ChatEmpty.d.ts.map +1 -1
  120. package/lib/typescript/src/components/chat/ChatHeader.d.ts.map +1 -1
  121. package/lib/typescript/src/components/chat/ChatMessageList.d.ts.map +1 -1
  122. package/lib/typescript/src/components/chat/SuggestionItem.d.ts +3 -2
  123. package/lib/typescript/src/components/chat/SuggestionItem.d.ts.map +1 -1
  124. package/lib/typescript/src/components/chat/footer/index.d.ts.map +1 -1
  125. package/lib/typescript/src/components/chat/footer/item/UploadImageItem.d.ts.map +1 -1
  126. package/lib/typescript/src/components/chat/index.d.ts.map +1 -1
  127. package/lib/typescript/src/components/chat/item/ChatAIAnswerMessageItem.d.ts.map +1 -1
  128. package/lib/typescript/src/components/chat/item/DeeplinkItem.d.ts +2 -1
  129. package/lib/typescript/src/components/chat/item/DeeplinkItem.d.ts.map +1 -1
  130. package/lib/typescript/src/components/chat/item/MessageActionsBar.d.ts +16 -0
  131. package/lib/typescript/src/components/chat/item/MessageActionsBar.d.ts.map +1 -0
  132. package/lib/typescript/src/components/chat/item/actions/ActionButton.d.ts +19 -0
  133. package/lib/typescript/src/components/chat/item/actions/ActionButton.d.ts.map +1 -0
  134. package/lib/typescript/src/components/portal/BottomSheet.d.ts +8 -0
  135. package/lib/typescript/src/components/portal/BottomSheet.d.ts.map +1 -0
  136. package/lib/typescript/src/components/portal/Popup.d.ts +4 -0
  137. package/lib/typescript/src/components/portal/Popup.d.ts.map +1 -0
  138. package/lib/typescript/src/components/portal/index.d.ts.map +1 -1
  139. package/lib/typescript/src/components/product/CardHorizontal.d.ts +3 -2
  140. package/lib/typescript/src/components/product/CardHorizontal.d.ts.map +1 -1
  141. package/lib/typescript/src/constants/events.d.ts +33 -0
  142. package/lib/typescript/src/constants/events.d.ts.map +1 -1
  143. package/lib/typescript/src/constants/index.d.ts +5 -1
  144. package/lib/typescript/src/constants/index.d.ts.map +1 -1
  145. package/lib/typescript/src/constants/query.d.ts +4 -0
  146. package/lib/typescript/src/constants/query.d.ts.map +1 -1
  147. package/lib/typescript/src/context/ChatContext.d.ts.map +1 -1
  148. package/lib/typescript/src/hooks/message/useSendMessage.d.ts +2 -2
  149. package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
  150. package/lib/typescript/src/hooks/message/useStreamMessage.d.ts.map +1 -1
  151. package/lib/typescript/src/hooks/messageActions/index.d.ts +10 -0
  152. package/lib/typescript/src/hooks/messageActions/index.d.ts.map +1 -0
  153. package/lib/typescript/src/hooks/messageActions/useAudioPlayer.d.ts +14 -0
  154. package/lib/typescript/src/hooks/messageActions/useAudioPlayer.d.ts.map +1 -0
  155. package/lib/typescript/src/hooks/messageActions/useCopyToClipboard.d.ts +9 -0
  156. package/lib/typescript/src/hooks/messageActions/useCopyToClipboard.d.ts.map +1 -0
  157. package/lib/typescript/src/hooks/messageActions/useFeedback.d.ts +18 -0
  158. package/lib/typescript/src/hooks/messageActions/useFeedback.d.ts.map +1 -0
  159. package/lib/typescript/src/hooks/messageActions/useSendFeedback.d.ts +6 -0
  160. package/lib/typescript/src/hooks/messageActions/useSendFeedback.d.ts.map +1 -0
  161. package/lib/typescript/src/hooks/messageActions/useShareMessage.d.ts +12 -0
  162. package/lib/typescript/src/hooks/messageActions/useShareMessage.d.ts.map +1 -0
  163. package/lib/typescript/src/hooks/session/useDeleteSession.d.ts +2 -0
  164. package/lib/typescript/src/hooks/session/useDeleteSession.d.ts.map +1 -0
  165. package/lib/typescript/src/hooks/session/useRenameSession.d.ts +2 -0
  166. package/lib/typescript/src/hooks/session/useRenameSession.d.ts.map +1 -0
  167. package/lib/typescript/src/hooks/session/useSearchSessions.d.ts +1 -1
  168. package/lib/typescript/src/hooks/session/useSearchSessions.d.ts.map +1 -1
  169. package/lib/typescript/src/hooks/session/useShareSession.d.ts +2 -0
  170. package/lib/typescript/src/hooks/session/useShareSession.d.ts.map +1 -0
  171. package/lib/typescript/src/hooks/upload/useImageUpload.d.ts +1 -1
  172. package/lib/typescript/src/hooks/upload/useImageUpload.d.ts.map +1 -1
  173. package/lib/typescript/src/services/endpoints.d.ts +5 -0
  174. package/lib/typescript/src/services/endpoints.d.ts.map +1 -1
  175. package/lib/typescript/src/services/index.d.ts +1 -0
  176. package/lib/typescript/src/services/index.d.ts.map +1 -1
  177. package/lib/typescript/src/services/playbackService.d.ts +2 -0
  178. package/lib/typescript/src/services/playbackService.d.ts.map +1 -0
  179. package/lib/typescript/src/store/audioPlayer.d.ts +27 -0
  180. package/lib/typescript/src/store/audioPlayer.d.ts.map +1 -0
  181. package/lib/typescript/src/store/messageActions.d.ts +9 -0
  182. package/lib/typescript/src/store/messageActions.d.ts.map +1 -0
  183. package/lib/typescript/src/store/session.d.ts.map +1 -1
  184. package/lib/typescript/src/translation/index.d.ts +3 -4
  185. package/lib/typescript/src/translation/index.d.ts.map +1 -1
  186. package/lib/typescript/src/translation/resources/i18n.d.ts +5 -0
  187. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -0
  188. package/lib/typescript/src/types/chat.d.ts +16 -1
  189. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  190. package/lib/typescript/src/types/dto.d.ts +11 -0
  191. package/lib/typescript/src/types/dto.d.ts.map +1 -1
  192. package/lib/typescript/src/types/index.d.ts +1 -0
  193. package/lib/typescript/src/types/index.d.ts.map +1 -1
  194. package/lib/typescript/src/types/messageActions.d.ts +85 -0
  195. package/lib/typescript/src/types/messageActions.d.ts.map +1 -0
  196. package/lib/typescript/src/types/ui.d.ts +16 -1
  197. package/lib/typescript/src/types/ui.d.ts.map +1 -1
  198. package/lib/typescript/src/utils/textCleaner.d.ts +30 -0
  199. package/lib/typescript/src/utils/textCleaner.d.ts.map +1 -0
  200. package/lib/typescript/src/utils/ui.d.ts +12 -1
  201. package/lib/typescript/src/utils/ui.d.ts.map +1 -1
  202. package/package.json +6 -6
  203. package/src/components/Drawer/DeleteSessionPopup.tsx +121 -0
  204. package/src/components/Drawer/DrawerContent.tsx +23 -7
  205. package/src/components/Drawer/RenameSessionPopup.tsx +145 -0
  206. package/src/components/Drawer/SearchInput.tsx +11 -2
  207. package/src/components/Drawer/SessionItem.tsx +22 -8
  208. package/src/components/Drawer/SessionList.tsx +0 -2
  209. package/src/components/Drawer/SessionOptionsBottomSheet.tsx +138 -0
  210. package/src/components/Drawer/ShareSessionPopup.tsx +145 -0
  211. package/src/components/chat/ChatEmpty.tsx +15 -5
  212. package/src/components/chat/ChatHeader.tsx +9 -4
  213. package/src/components/chat/ChatMessageList.tsx +78 -18
  214. package/src/components/chat/SuggestionItem.tsx +4 -3
  215. package/src/components/chat/footer/index.tsx +95 -14
  216. package/src/components/chat/footer/item/UploadImageItem.tsx +21 -1
  217. package/src/components/chat/index.tsx +8 -11
  218. package/src/components/chat/item/ChatAIAnswerMessageItem.tsx +55 -6
  219. package/src/components/chat/item/DeeplinkItem.tsx +30 -2
  220. package/src/components/chat/item/MessageActionsBar.tsx +326 -0
  221. package/src/components/chat/item/actions/ActionButton.tsx +65 -0
  222. package/src/components/portal/BottomSheet.tsx +307 -0
  223. package/src/components/portal/Popup.tsx +345 -0
  224. package/src/components/portal/index.tsx +5 -1
  225. package/src/components/product/CardHorizontal.tsx +45 -10
  226. package/src/constants/events.ts +34 -0
  227. package/src/constants/index.ts +6 -1
  228. package/src/constants/query.ts +4 -0
  229. package/src/context/ChatContext.tsx +6 -0
  230. package/src/hooks/message/useSendMessage.ts +47 -4
  231. package/src/hooks/message/useStreamMessage.ts +15 -4
  232. package/src/hooks/messageActions/index.ts +10 -0
  233. package/src/hooks/messageActions/useAudioPlayer.ts +346 -0
  234. package/src/hooks/messageActions/useCopyToClipboard.ts +38 -0
  235. package/src/hooks/messageActions/useFeedback.ts +114 -0
  236. package/src/hooks/messageActions/useSendFeedback.ts +31 -0
  237. package/src/hooks/messageActions/useShareMessage.ts +146 -0
  238. package/src/hooks/session/useDeleteSession.ts +25 -0
  239. package/src/hooks/session/useRenameSession.ts +37 -0
  240. package/src/hooks/session/useSearchSessions.ts +6 -1
  241. package/src/hooks/session/useShareSession.ts +22 -0
  242. package/src/hooks/upload/useImageUpload.ts +6 -2
  243. package/src/ignore.d.ts +20 -1
  244. package/src/services/endpoints.ts +10 -0
  245. package/src/services/index.ts +1 -0
  246. package/src/services/playbackService.ts +22 -0
  247. package/src/store/audioPlayer.ts +112 -0
  248. package/src/store/messageActions.ts +161 -0
  249. package/src/store/session.ts +4 -2
  250. package/src/translation/index.ts +27 -19
  251. package/src/translation/resources/i18n.ts +45 -0
  252. package/src/types/chat.ts +21 -1
  253. package/src/types/dto.ts +14 -0
  254. package/src/types/index.ts +1 -0
  255. package/src/types/messageActions.ts +131 -0
  256. package/src/types/ui.ts +19 -1
  257. package/src/utils/textCleaner.ts +65 -0
  258. package/src/utils/ui.tsx +29 -2
  259. package/lib/module/translation/resources/vi.js +0 -12
  260. package/lib/module/translation/resources/vi.js.map +0 -1
  261. package/lib/typescript/src/translation/resources/vi.d.ts +0 -11
  262. package/lib/typescript/src/translation/resources/vi.d.ts.map +0 -1
  263. package/src/translation/resources/vi.ts +0 -10
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Text Cleaning Utilities
3
+ * Utilities for cleaning markdown, truncating text, and validating content
4
+ */
5
+ /**
6
+ * Remove markdown formatting from text for cleaner copy/share
7
+ * @param text - Text with markdown formatting
8
+ * @returns Clean text without markdown
9
+ */
10
+ export declare const cleanMarkdown: (text: string) => string;
11
+ /**
12
+ * Truncate text to specified length with suffix
13
+ * @param text - Text to truncate
14
+ * @param maxLength - Maximum length
15
+ * @param suffix - Suffix to add (default: '...')
16
+ * @returns Truncated text
17
+ */
18
+ export declare const truncateText: (text: string, maxLength: number, suffix?: string) => string;
19
+ /**
20
+ * Validate text content
21
+ * @param text - Text to validate
22
+ * @param minLength - Minimum length (default: 1)
23
+ * @param maxLength - Maximum length (default: 100000)
24
+ * @returns Validation result with error message if invalid
25
+ */
26
+ export declare const validateContent: (text: string, minLength?: number, maxLength?: number) => {
27
+ valid: boolean;
28
+ error?: string;
29
+ };
30
+ //# sourceMappingURL=textCleaner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textCleaner.d.ts","sourceRoot":"","sources":["../../../../src/utils/textCleaner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,MAW5C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,WAAW,MAAM,EACjB,eAAc,KACb,MAGF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,kBAAa,EACb,kBAAkB,KACjB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAclC,CAAC"}
@@ -1,4 +1,5 @@
1
- import { StyleProp, ViewStyle } from 'react-native';
1
+ import type { KPopupProps, KToastBarProps } from '@droppii/libs';
2
+ import { KBottomSheetPropsEnhance } from '../types';
2
3
  declare class UIUtils {
3
4
  toast: {
4
5
  open: (params: KToastBarProps & {
@@ -6,6 +7,16 @@ declare class UIUtils {
6
7
  }) => void;
7
8
  dismiss: () => void;
8
9
  showError: (error: any, withToast?: boolean) => any;
10
+ showSuccess: (message: string) => void;
11
+ };
12
+ bottomSheet: {
13
+ open: (params: KBottomSheetPropsEnhance) => void;
14
+ dismiss: () => void;
15
+ };
16
+ popup: {
17
+ open: (params: KPopupProps) => void;
18
+ dismiss: () => void;
19
+ dismissAll: () => void;
9
20
  };
10
21
  }
11
22
  declare const _default: UIUtils;
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../../src/utils/ui.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKpD,cAAM,OAAO;IACX,KAAK;uBAGO,cAAc,GAAG;YAAE,qBAAqB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;SAAE;;2BAOxD,GAAG;MAWtB;CACH;;AAED,wBAA6B"}
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../../src/utils/ui.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAEpD,cAAM,OAAO;IACX,KAAK;uBAGO,cAAc,GAAG;YAAE,qBAAqB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;SAAE;;2BAOxD,GAAG;+BAWC,MAAM;MAO7B;IACF,WAAW;uBACM,wBAAwB;;MAMvC;IACF,KAAK;uBACY,WAAW;;;MAS1B;CACH;;AAED,wBAA6B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-chatbot-ai",
3
- "version": "0.1.19",
3
+ "version": "0.1.22",
4
4
  "description": "React Native library for Chatbot AI",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -80,11 +80,9 @@
80
80
  "eslint": "^9.35.0",
81
81
  "eslint-config-prettier": "^10.1.8",
82
82
  "eslint-plugin-prettier": "^5.5.4",
83
- "i18next": "^25.6.1",
84
83
  "jest": "^29.7.0",
85
84
  "lodash": "^4.17.21",
86
85
  "prettier": "^3.6.2",
87
- "react-i18next": "^16.2.4",
88
86
  "react-native-builder-bob": "^0.40.13",
89
87
  "react-native-file-viewer": "^2.1.5",
90
88
  "react-native-image-crop-picker": "^0.51.1",
@@ -98,13 +96,14 @@
98
96
  "@droppii/libs": "*",
99
97
  "@react-native-documents/picker": "*",
100
98
  "@tanstack/react-query": "*",
101
- "i18next": "*",
102
99
  "react": "*",
103
- "react-i18next": "*",
104
100
  "react-native": "*",
105
101
  "react-native-blob-util": "*",
106
102
  "react-native-file-viewer": "*",
107
- "react-native-popup-menu": "*"
103
+ "react-native-keyboard-controller": "*",
104
+ "react-native-popup-menu": "*",
105
+ "react-native-share": "*",
106
+ "react-native-track-player": "*"
108
107
  },
109
108
  "workspaces": [
110
109
  "example"
@@ -173,6 +172,7 @@
173
172
  },
174
173
  "dependencies": {
175
174
  "@babel/runtime": "^7.28.4",
175
+ "@react-native-clipboard/clipboard": "^1.16.0",
176
176
  "axios": "^1.12.2",
177
177
  "dayjs": "^1.11.18",
178
178
  "lodash": "^4.17.21",
@@ -0,0 +1,121 @@
1
+ import { useCallback } from 'react';
2
+ import { StyleSheet } from 'react-native';
3
+ import { KContainer, KLabel, KColors, KSpacingValue } from '@droppii/libs';
4
+ import { useDeleteSession } from '../../hooks/session/useDeleteSession';
5
+ import UIUtils from '../../utils/ui';
6
+ import { trans } from '../../translation';
7
+ import { SessionSearchItem } from '../../types/dto';
8
+ import useSessionStore from '../../store/session';
9
+ import { SessionLogType } from '../../types';
10
+ import { GAEvents } from '../../constants/events';
11
+
12
+ const truncateText = (text: string, maxLength: number) => {
13
+ if (text.length <= maxLength) return text;
14
+ return text.substring(0, maxLength) + '…';
15
+ };
16
+
17
+ interface DeleteContentProps {
18
+ session: SessionSearchItem;
19
+ onConfirmRef: React.RefObject<(() => Promise<void>) | null>;
20
+ }
21
+
22
+ const DeleteContent = ({ session, onConfirmRef }: DeleteContentProps) => {
23
+ const { mutateAsync: deleteSession } = useDeleteSession();
24
+ const currentSessionId = useSessionStore((state) => state.sessionId);
25
+ const setSessionId = useSessionStore((state) => state.setSessionId);
26
+
27
+ // Expose handleConfirm via ref
28
+ onConfirmRef.current = useCallback(async () => {
29
+ try {
30
+ await deleteSession(session.id);
31
+
32
+ // If the deleted session is the current active session, clear it
33
+ if (currentSessionId === session.id) {
34
+ setSessionId(undefined, SessionLogType.newChatBtn);
35
+ }
36
+
37
+ UIUtils.toast.showSuccess(trans('chatbot:delete_session_success'));
38
+ UIUtils.popup.dismiss();
39
+ } catch (err) {
40
+ UIUtils.toast.showError(err);
41
+ }
42
+ }, [session.id, currentSessionId, deleteSession, setSessionId]);
43
+
44
+ const truncatedName = truncateText(session.title, 50);
45
+ const descriptionTemplate = trans('chatbot:delete_session_description');
46
+ const parts = descriptionTemplate.split('{sessionName}');
47
+
48
+ return (
49
+ // @ts-ignore
50
+ <KContainer.View style={styles.container}>
51
+ {/* @ts-ignore */}
52
+ <KLabel.Text typo="TextMdNormal" color={KColors.gray.dark}>
53
+ {parts[0]}
54
+ {/* @ts-ignore */}
55
+ <KLabel.Text typo="TextMdBold" color={KColors.gray.dark}>
56
+ {truncatedName}
57
+ </KLabel.Text>
58
+ {parts[1]}
59
+ </KLabel.Text>
60
+ </KContainer.View>
61
+ );
62
+ };
63
+
64
+ export const openDeleteSessionPopup = (
65
+ session: SessionSearchItem,
66
+ logGA?: (event: string, params?: any) => void
67
+ ) => {
68
+ const onConfirmRef = { current: null } as React.RefObject<
69
+ (() => Promise<void>) | null
70
+ >;
71
+
72
+ UIUtils.popup.open({
73
+ header: {
74
+ title: {
75
+ text: trans('chatbot:delete_session_title'),
76
+ },
77
+ showCloseButton: false,
78
+ },
79
+ body: {
80
+ scrollable: false,
81
+ renderContent: () => (
82
+ <DeleteContent session={session} onConfirmRef={onConfirmRef} />
83
+ ),
84
+ },
85
+ actions: {
86
+ type: 'horizontal-button',
87
+ buttons: [
88
+ {
89
+ kind: 'light',
90
+ label: trans('chatbot:delete_session_cancel'),
91
+ weight: 'medium',
92
+ onPress: () => {
93
+ UIUtils.popup.dismiss();
94
+ logGA?.(GAEvents.deleteChatModalDeleteBtnTap, {
95
+ conversation_id: session.id,
96
+ button: 'cancel',
97
+ });
98
+ },
99
+ },
100
+ {
101
+ kind: 'danger',
102
+ label: trans('chatbot:delete_session_confirm'),
103
+ weight: 'medium',
104
+ onPress: () => {
105
+ onConfirmRef.current?.();
106
+ logGA?.(GAEvents.deleteChatModalDeleteBtnTap, {
107
+ conversation_id: session.id,
108
+ button: 'delete',
109
+ });
110
+ },
111
+ },
112
+ ],
113
+ },
114
+ });
115
+ };
116
+
117
+ const styles = StyleSheet.create({
118
+ container: {
119
+ padding: KSpacingValue['1rem'],
120
+ },
121
+ });
@@ -1,6 +1,6 @@
1
1
  import { useCallback, useMemo, useState, useEffect, useRef } from 'react';
2
- import { StyleSheet } from 'react-native';
3
- import { KContainer } from '@droppii/libs';
2
+ import { StyleSheet, Platform } from 'react-native';
3
+ import { KContainer, KSpacingValue } from '@droppii/libs';
4
4
  import debounce from 'lodash/debounce';
5
5
  import useSessionStore from '../../store/session';
6
6
  import { useChatContext } from '../../context/ChatContext';
@@ -9,11 +9,13 @@ import { SessionSearchItem } from '../../types/dto';
9
9
  import NewChatButton from './NewChatButton';
10
10
  import SearchInput from './SearchInput';
11
11
  import SessionList from './SessionList';
12
+ import { SessionLogType } from '../../types';
13
+ import { GAEvents } from '../../constants/events';
12
14
 
13
15
  const DrawerContent = () => {
14
16
  const setSessionId = useSessionStore((state) => state.setSessionId);
15
17
  const sessionId = useSessionStore((state) => state.sessionId);
16
- const { closeDrawer } = useChatContext();
18
+ const { closeDrawer, logGA } = useChatContext();
17
19
  const [searchQuery, setSearchQuery] = useState('');
18
20
  const [debouncedSearchTerm, setDebouncedSearchTerm] = useState('');
19
21
  const debounceRef = useRef(
@@ -30,6 +32,16 @@ const DrawerContent = () => {
30
32
  };
31
33
  }, [searchQuery]);
32
34
 
35
+ const onSearchCallback = useCallback(
36
+ (isSuccess?: boolean) => {
37
+ logGA(GAEvents.sidebarSearchConversationSend, {
38
+ content: debouncedSearchTerm,
39
+ search_result: isSuccess ? 'yes' : null,
40
+ });
41
+ },
42
+ [logGA, debouncedSearchTerm]
43
+ );
44
+
33
45
  const {
34
46
  data,
35
47
  isLoading,
@@ -38,7 +50,7 @@ const DrawerContent = () => {
38
50
  fetchNextPage,
39
51
  hasNextPage,
40
52
  isFetchingNextPage,
41
- } = useSearchSessions(true, debouncedSearchTerm);
53
+ } = useSearchSessions(true, debouncedSearchTerm, onSearchCallback);
42
54
 
43
55
  const sessions = useMemo(() => {
44
56
  return (data?.pages.flatMap(
@@ -47,13 +59,16 @@ const DrawerContent = () => {
47
59
  }, [data]);
48
60
 
49
61
  const onPressNewSession = useCallback(() => {
50
- setSessionId(undefined);
62
+ setSessionId(undefined, SessionLogType.newChatBtn);
51
63
  closeDrawer();
52
- }, [setSessionId, closeDrawer]);
64
+ logGA(GAEvents.newChatCreateBtnTap, {
65
+ button_type: 'sidebar',
66
+ });
67
+ }, [setSessionId, closeDrawer, logGA]);
53
68
 
54
69
  const onPressSession = useCallback(
55
70
  (item: SessionSearchItem) => {
56
- setSessionId(item.id);
71
+ setSessionId(item.id, SessionLogType.oldChat);
57
72
  closeDrawer();
58
73
  },
59
74
  [setSessionId, closeDrawer]
@@ -88,6 +103,7 @@ const styles = StyleSheet.create({
88
103
  drawerContainer: {
89
104
  flex: 1,
90
105
  backgroundColor: 'white',
106
+ paddingTop: Platform.OS === 'android' ? KSpacingValue['2rem'] : 0,
91
107
  },
92
108
  });
93
109
 
@@ -0,0 +1,145 @@
1
+ import { useState, useCallback } from 'react';
2
+ import { useRenameSession } from '../../hooks/session/useRenameSession';
3
+ import UIUtils from '../../utils/ui';
4
+ import { trans } from '../../translation';
5
+ import { SessionSearchItem } from '../../types/dto';
6
+ import { StyleSheet, Keyboard } from 'react-native';
7
+ import {
8
+ KButton,
9
+ KColors,
10
+ KContainer,
11
+ KInput,
12
+ KLabel,
13
+ KSpacingValue,
14
+ } from '@droppii/libs';
15
+ import { useChatContext } from '../../context/ChatContext';
16
+
17
+ const MAX_LENGTH = 250;
18
+ const MIN_LENGTH = 1;
19
+
20
+ interface RenameSessionPopupProps {
21
+ session: SessionSearchItem;
22
+ }
23
+
24
+ const RenameSessionPopup = ({ session }: RenameSessionPopupProps) => {
25
+ const [value, setValue] = useState(session.title);
26
+ const [confirmDisabled, setConfirmDisabled] = useState(true);
27
+ const { mutateAsync: renameSession } = useRenameSession();
28
+ const { openDrawer } = useChatContext();
29
+
30
+ const onChangeText = useCallback(
31
+ (text: string) => {
32
+ const newText = text.slice(0, MAX_LENGTH);
33
+ setValue(newText);
34
+
35
+ const disabled =
36
+ newText.trim().length < MIN_LENGTH ||
37
+ newText.length > MAX_LENGTH ||
38
+ newText.trim() === session.title.trim();
39
+
40
+ setConfirmDisabled(disabled);
41
+ },
42
+ [session.title]
43
+ );
44
+
45
+ const onClear = useCallback(() => {
46
+ setValue('');
47
+ setConfirmDisabled(true);
48
+ }, []);
49
+
50
+ const handleConfirm = useCallback(async () => {
51
+ const trimmed = value.trim();
52
+ if (
53
+ confirmDisabled ||
54
+ !trimmed ||
55
+ trimmed.length < MIN_LENGTH ||
56
+ trimmed.length > MAX_LENGTH ||
57
+ trimmed === session.title.trim()
58
+ ) {
59
+ return;
60
+ }
61
+
62
+ try {
63
+ await renameSession({
64
+ sessionId: session.id,
65
+ title: trimmed,
66
+ });
67
+ Keyboard.dismiss();
68
+ UIUtils.toast.showSuccess(trans('chatbot:rename_session_success'));
69
+ UIUtils.popup.dismiss();
70
+ setTimeout(() => {
71
+ openDrawer();
72
+ }, 500);
73
+ } catch (err) {
74
+ UIUtils.toast.showError(err);
75
+ }
76
+ }, [confirmDisabled, value, session, renameSession, openDrawer]);
77
+
78
+ return (
79
+ <KContainer.View>
80
+ <KContainer.View style={[styles.searchInputWrapper]}>
81
+ <KInput.TextBox
82
+ placeholder={trans('chatbot:rename_session_placeholder')}
83
+ value={value}
84
+ onChangeText={onChangeText}
85
+ onClear={onClear}
86
+ border="entire"
87
+ radius="borderless"
88
+ withBorder
89
+ height={160}
90
+ maxLength={MAX_LENGTH}
91
+ paddingV="0.5rem"
92
+ multiline
93
+ textAlignVertical="top"
94
+ />
95
+ <KLabel.Text color={KColors.gray.light}>
96
+ {value.trim().length === 0
97
+ ? `Tối đa ${MAX_LENGTH} ký tự`
98
+ : `Còn ${MAX_LENGTH - value.length}/${MAX_LENGTH} ký tự`}
99
+ </KLabel.Text>
100
+ </KContainer.View>
101
+
102
+ <KContainer.View style={styles.divider} />
103
+ <KContainer.View style={styles.buttonConfirm}>
104
+ <KButton.Solid
105
+ label={trans('rename_session_confirm')}
106
+ stretch
107
+ size="lg"
108
+ marginT="1rem"
109
+ disabled={confirmDisabled}
110
+ onPress={handleConfirm}
111
+ />
112
+ </KContainer.View>
113
+ </KContainer.View>
114
+ );
115
+ };
116
+
117
+ export const openRenameSessionPopup = (session: SessionSearchItem) => {
118
+ UIUtils.popup.open({
119
+ header: {
120
+ title: { text: trans('chatbot:rename_session_title') },
121
+ showCloseButton: true,
122
+ alignment: 'left',
123
+ },
124
+ body: {
125
+ scrollable: false,
126
+ renderContent: () => <RenameSessionPopup session={session} />,
127
+ },
128
+ });
129
+ };
130
+
131
+ const styles = StyleSheet.create({
132
+ searchInputWrapper: {
133
+ marginHorizontal: KSpacingValue['1rem'],
134
+ marginBottom: KSpacingValue['0.75rem'],
135
+ paddingTop: KSpacingValue['0.25rem'],
136
+ },
137
+ divider: {
138
+ height: 1,
139
+ backgroundColor: KColors.border.light,
140
+ },
141
+ buttonConfirm: {
142
+ padding: KSpacingValue['1rem'],
143
+ paddingTop: 0,
144
+ },
145
+ });
@@ -1,6 +1,8 @@
1
- import { memo } from 'react';
1
+ import { useCallback, memo } from 'react';
2
2
  import { StyleSheet } from 'react-native';
3
3
  import { KContainer, KInput, KColors, KSpacingValue } from '@droppii/libs';
4
+ import { useChatContext } from '../../context/ChatContext';
5
+ import { GAEvents } from '../../constants/events';
4
6
 
5
7
  interface SearchInputProps {
6
8
  value: string;
@@ -8,10 +10,16 @@ interface SearchInputProps {
8
10
  }
9
11
 
10
12
  const SearchInput = memo<SearchInputProps>(({ value, onChangeText }) => {
13
+ const logGA = useChatContext().logGA;
14
+
15
+ const onFocus = useCallback(() => {
16
+ logGA(GAEvents.sidebarSearchConversationTap);
17
+ }, [logGA]);
18
+
11
19
  return (
12
20
  <KContainer.View style={styles.searchInputWrapper}>
13
21
  <KInput.TextBox
14
- placeholder={'Tìm kiếm đoạn chát'}
22
+ placeholder={'Tìm kiếm đoạn chat'}
15
23
  value={value}
16
24
  onChangeText={onChangeText}
17
25
  searchIconLeftColor={KColors.gray.normal}
@@ -20,6 +28,7 @@ const SearchInput = memo<SearchInputProps>(({ value, onChangeText }) => {
20
28
  radius="borderless"
21
29
  withBorder
22
30
  height={40}
31
+ onFocus={onFocus}
23
32
  />
24
33
  </KContainer.View>
25
34
  );
@@ -1,4 +1,4 @@
1
- import { memo } from 'react';
1
+ import { memo, useCallback } from 'react';
2
2
  import { StyleSheet } from 'react-native';
3
3
  import {
4
4
  KContainer,
@@ -8,6 +8,8 @@ import {
8
8
  KImage,
9
9
  } from '@droppii/libs';
10
10
  import { SessionSearchItem } from '../../types/dto';
11
+ import { openSessionOptionsBottomSheet } from './SessionOptionsBottomSheet';
12
+ import { useChatContext } from '../../context/ChatContext';
11
13
 
12
14
  interface SessionItemProps {
13
15
  item: SessionSearchItem;
@@ -16,14 +18,23 @@ interface SessionItemProps {
16
18
  }
17
19
 
18
20
  const SessionItem = memo<SessionItemProps>(({ item, isActive, onPress }) => {
21
+ const { closeDrawer, logGA } = useChatContext();
22
+
23
+ const handlePressOptions = useCallback(() => {
24
+ openSessionOptionsBottomSheet(item, closeDrawer, logGA);
25
+ }, [item, closeDrawer, logGA]);
26
+
19
27
  return (
28
+ // @ts-ignore
20
29
  <KContainer.View
21
30
  style={[styles.sessionItem, isActive && styles.sessionItemActive]}
22
31
  >
32
+ {/* @ts-ignore */}
23
33
  <KContainer.Touchable
24
34
  style={styles.sessionItemTouchable}
25
35
  onPress={() => onPress(item)}
26
36
  >
37
+ {/* @ts-ignore */}
27
38
  <KLabel.Text
28
39
  typo="TextMdNormal"
29
40
  color={KColors.gray.dark}
@@ -32,12 +43,15 @@ const SessionItem = memo<SessionItemProps>(({ item, isActive, onPress }) => {
32
43
  {item.title}
33
44
  </KLabel.Text>
34
45
  </KContainer.Touchable>
35
- <KImage.VectorIcons
36
- name="more-horizontal-b"
37
- size={20}
38
- color={KColors.gray.dark}
39
- style={styles.menuIcon}
40
- />
46
+ {/* @ts-ignore */}
47
+ <KContainer.Touchable onPress={handlePressOptions}>
48
+ <KImage.VectorIcons
49
+ name="more-horizontal-b"
50
+ size={20}
51
+ color={KColors.gray.dark}
52
+ style={styles.menuIcon}
53
+ />
54
+ </KContainer.Touchable>
41
55
  </KContainer.View>
42
56
  );
43
57
  });
@@ -55,7 +69,7 @@ const styles = StyleSheet.create({
55
69
  // marginVertical: KSpacingValue['0.25rem'],
56
70
  },
57
71
  sessionItemActive: {
58
- backgroundColor: KColors.primary.lightest,
72
+ backgroundColor: KColors.hexToRgba(KColors.primary.normal, 0.1),
59
73
  },
60
74
  sessionItemTouchable: {
61
75
  flex: 1,
@@ -41,14 +41,12 @@ const SessionList = memo<SessionListProps>(
41
41
  const keyExtractor = useCallback((item: SessionSearchItem) => item.id, []);
42
42
 
43
43
  return (
44
- /* @ts-expect-error - FlashList type issue */
45
44
  <FlashList
46
45
  data={sessions}
47
46
  renderItem={renderItem}
48
47
  keyExtractor={keyExtractor}
49
48
  contentContainerStyle={styles.listContainer}
50
49
  refreshControl={
51
- /* @ts-expect-error - React Native RefreshControl type issue */
52
50
  <RefreshControl refreshing={isRefetching} onRefresh={onRefresh} />
53
51
  }
54
52
  onEndReached={onEndReached}