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,307 @@
1
+ import React, {
2
+ ComponentType,
3
+ forwardRef,
4
+ memo,
5
+ useCallback,
6
+ useEffect,
7
+ useImperativeHandle,
8
+ useMemo,
9
+ useRef,
10
+ useState,
11
+ } from 'react';
12
+ import { BackHandler, Keyboard, StyleSheet } from 'react-native';
13
+ import {
14
+ BottomSheetBackdrop,
15
+ BottomSheetModal,
16
+ BottomSheetView,
17
+ } from '@gorhom/bottom-sheet';
18
+ import isEmpty from 'lodash/isEmpty';
19
+ import set from 'lodash/set';
20
+ import { ScrollView } from 'react-native-gesture-handler';
21
+ import {
22
+ KBars,
23
+ KButton,
24
+ KContainer,
25
+ KLabel,
26
+ KRadiusValue,
27
+ KSpacingValue,
28
+ KColors,
29
+ KDims,
30
+ } from '@droppii/libs';
31
+ import { KBottomSheetPropsEnhance, WithBottomSheetProps } from '../../types';
32
+ import { Z_INDEX_PRIORITY } from '../../constants';
33
+
34
+ const UNIT = KSpacingValue['1rem'];
35
+ const ANIMATE_CONFIGS = {
36
+ damping: 80,
37
+ overshootClamping: true,
38
+ restDisplacementThreshold: 0.1,
39
+ restSpeedThreshold: 0.1,
40
+ stiffness: 500,
41
+ };
42
+
43
+ export const useBottomSheetBackHandler = (
44
+ bottomSheetRef: React.RefObject<any>
45
+ ) => {
46
+ const backHandlerSubscriptionRef = useRef<ReturnType<
47
+ typeof BackHandler.addEventListener
48
+ > | null>(null);
49
+ const handleSheetPositionChange = useCallback<
50
+ NonNullable<React.ComponentProps<typeof BottomSheetModal>['onChange']>
51
+ >(
52
+ (index: number) => {
53
+ const isBottomSheetVisible = index >= 0;
54
+ if (isBottomSheetVisible && !backHandlerSubscriptionRef.current) {
55
+ backHandlerSubscriptionRef.current = BackHandler.addEventListener(
56
+ 'hardwareBackPress',
57
+ () => {
58
+ bottomSheetRef.current?.close();
59
+ return true;
60
+ }
61
+ );
62
+ } else if (!isBottomSheetVisible) {
63
+ backHandlerSubscriptionRef.current?.remove();
64
+ backHandlerSubscriptionRef.current = null;
65
+ }
66
+ },
67
+ [bottomSheetRef, backHandlerSubscriptionRef]
68
+ );
69
+ return { handleSheetPositionChange };
70
+ };
71
+
72
+ const BottomSheet = forwardRef<WithBottomSheetProps>((_, ref) => {
73
+ const [data, setData] = useState<KBottomSheetPropsEnhance | undefined>(
74
+ undefined
75
+ );
76
+
77
+ const bottomSheetRef = useRef<any>(null);
78
+
79
+ const { handleSheetPositionChange } =
80
+ useBottomSheetBackHandler(bottomSheetRef);
81
+
82
+ const dismiss = useCallback(() => {
83
+ bottomSheetRef.current?.close();
84
+ }, []);
85
+
86
+ const onBackdropPress = useCallback(() => {}, []);
87
+
88
+ const renderBackdrop = useCallback(
89
+ (p: any) => (
90
+ <BottomSheetBackdrop
91
+ {...p}
92
+ opacity={0.8}
93
+ disappearsOnIndex={-1}
94
+ appearsOnIndex={0}
95
+ onPress={onBackdropPress}
96
+ />
97
+ ),
98
+ [onBackdropPress]
99
+ );
100
+
101
+ useImperativeHandle(
102
+ ref,
103
+ () => ({
104
+ open: (payload) => {
105
+ setData(payload);
106
+ Keyboard.dismiss();
107
+ },
108
+ dismiss,
109
+ }),
110
+ [dismiss]
111
+ );
112
+
113
+ useEffect(() => {
114
+ if (data) {
115
+ bottomSheetRef.current?.present();
116
+ }
117
+ }, [data, dismiss]);
118
+
119
+ const onPressWrapper = useCallback(
120
+ (callback: any) => {
121
+ dismiss();
122
+ callback?.();
123
+ },
124
+ [dismiss]
125
+ );
126
+
127
+ const renderHeader = useMemo(() => {
128
+ if (!data?.header) {
129
+ return null;
130
+ }
131
+ const {
132
+ header: { showCloseButton, subTitle, title, alignment, customRenderer },
133
+ } = data;
134
+
135
+ if (customRenderer) {
136
+ return customRenderer(dismiss);
137
+ }
138
+
139
+ return (
140
+ // @ts-ignore
141
+ <KContainer.View
142
+ padding="1rem"
143
+ row
144
+ alignItems
145
+ brBW={1}
146
+ brBC={KColors.border.light}
147
+ >
148
+ {showCloseButton && alignment === 'center' && (
149
+ // @ts-ignore
150
+ <KContainer.View marginR={'1rem'}>
151
+ <KButton.Close color={KColors.transparent} />
152
+ </KContainer.View>
153
+ )}
154
+ {/* @ts-ignore */}
155
+ <KContainer.View
156
+ alignItems={alignment === 'left' ? 'flex-start' : 'center'}
157
+ flex
158
+ justifyContent
159
+ >
160
+ {!!title && (
161
+ // @ts-ignore
162
+ <KLabel.Text
163
+ typo={title.typo || 'TextLgBold'}
164
+ color={title.color}
165
+ numberOfLines={2}
166
+ textAlign="left"
167
+ >
168
+ {title.text}
169
+ </KLabel.Text>
170
+ )}
171
+ {!!subTitle && (
172
+ // @ts-ignore
173
+ <KLabel.Text
174
+ typo={subTitle.typo || 'TextSmNormal'}
175
+ color={subTitle.color || KColors.gray.light}
176
+ numberOfLines={2}
177
+ marginT="0.25rem"
178
+ >
179
+ {subTitle.text}
180
+ </KLabel.Text>
181
+ )}
182
+ </KContainer.View>
183
+ {showCloseButton && (
184
+ // @ts-ignore
185
+ <KContainer.View marginL={'1rem'}>
186
+ <KButton.Close onPress={dismiss} color={KColors.gray.dark} />
187
+ </KContainer.View>
188
+ )}
189
+ </KContainer.View>
190
+ );
191
+ }, [data, dismiss]);
192
+
193
+ const renderActions = useMemo(() => {
194
+ if (!data || !data.actions || isEmpty(data.actions.buttons)) {
195
+ return null;
196
+ }
197
+ const mActions = data.actions;
198
+ mActions.buttons = mActions.buttons.map((i: any) => {
199
+ const clone = { ...i };
200
+ delete clone.onPress;
201
+ set(clone, 'onPress', () => onPressWrapper(() => i.onPress?.()));
202
+ return clone;
203
+ });
204
+ return (
205
+ // @ts-ignore
206
+ <KContainer.View paddingH="1rem" brTW={1} brTC={KColors.border.light}>
207
+ <KBars.ActionBar {...mActions} type="horizontal-button" />
208
+ </KContainer.View>
209
+ );
210
+ }, [data, onPressWrapper]);
211
+
212
+ const renderBody = useMemo(() => {
213
+ if (!data) {
214
+ return null;
215
+ }
216
+
217
+ const message = data?.body?.message;
218
+ const renderContent = data?.body?.renderContent;
219
+
220
+ return (
221
+ <>
222
+ {message ? (
223
+ // @ts-ignore
224
+ <KContainer.View padding={'1rem'} background={KColors.white}>
225
+ {/* @ts-ignore */}
226
+ <KLabel.Text typo={message.typo} color={message.color}>
227
+ {message.text}
228
+ </KLabel.Text>
229
+ </KContainer.View>
230
+ ) : (
231
+ (renderContent?.(dismiss) ?? null)
232
+ )}
233
+ </>
234
+ );
235
+ }, [data, dismiss]);
236
+
237
+ const onDismiss = useCallback(() => {
238
+ data?.onDismiss?.();
239
+ }, [data]);
240
+
241
+ if (!data) {
242
+ return null;
243
+ }
244
+
245
+ const { scrollable = true } = data || {};
246
+
247
+ return (
248
+ <BottomSheetModal
249
+ ref={bottomSheetRef}
250
+ handleComponent={null}
251
+ enableDynamicSizing
252
+ backdropComponent={renderBackdrop}
253
+ onDismiss={onDismiss}
254
+ bottomInset={KDims.bottomSafeHeight > 0 ? UNIT * 1.5 : UNIT}
255
+ keyboardBehavior="interactive"
256
+ keyboardBlurBehavior="restore"
257
+ containerStyle={styles.sheetContainer}
258
+ backgroundStyle={styles.sheetBackground}
259
+ animationConfigs={ANIMATE_CONFIGS}
260
+ onChange={handleSheetPositionChange}
261
+ >
262
+ <BottomSheetView
263
+ style={styles.sheetView}
264
+
265
+ // onLayout={handleContentLayout}
266
+ >
267
+ {renderHeader}
268
+ {scrollable ? (
269
+ <ScrollView
270
+ showsVerticalScrollIndicator={false}
271
+ keyboardShouldPersistTaps="handled"
272
+ bounces={false}
273
+ >
274
+ {renderBody}
275
+ </ScrollView>
276
+ ) : (
277
+ renderBody
278
+ )}
279
+ {renderActions}
280
+ </BottomSheetView>
281
+ </BottomSheetModal>
282
+ );
283
+ });
284
+
285
+ (BottomSheet as ComponentType<any>).displayName = 'Portal.BottomSheet';
286
+
287
+ export default memo(BottomSheet);
288
+
289
+ const styles = StyleSheet.create({
290
+ sheetBackground: {
291
+ backgroundColor: KColors.transparent,
292
+ },
293
+ sheetContainer: {
294
+ borderRadius: KRadiusValue['4x'],
295
+ overflow: 'hidden',
296
+ paddingBottom: KDims.height,
297
+ zIndex: Z_INDEX_PRIORITY.bottomSheet,
298
+ },
299
+ sheetView: {
300
+ marginHorizontal: UNIT,
301
+ maxHeight: KDims.height * 0.9,
302
+ borderRadius: KRadiusValue['4x'],
303
+ overflow: 'hidden',
304
+ backgroundColor: KColors.white,
305
+ marginBottom: UNIT,
306
+ },
307
+ });
@@ -0,0 +1,345 @@
1
+ import {
2
+ ComponentType,
3
+ forwardRef,
4
+ memo,
5
+ useCallback,
6
+ useEffect,
7
+ useImperativeHandle,
8
+ useMemo,
9
+ useRef,
10
+ useState,
11
+ } from 'react';
12
+ import {
13
+ BackHandler,
14
+ Dimensions,
15
+ StatusBar,
16
+ StyleSheet,
17
+ TouchableWithoutFeedback,
18
+ Keyboard,
19
+ } from 'react-native';
20
+ import Animated, {
21
+ FadeIn,
22
+ FadeInUp,
23
+ FadeOut,
24
+ FadeOutDown,
25
+ useAnimatedStyle,
26
+ useSharedValue,
27
+ withSequence,
28
+ withSpring,
29
+ } from 'react-native-reanimated';
30
+ import set from 'lodash/set';
31
+ import isEmpty from 'lodash/isEmpty';
32
+ import isEqual from 'lodash/isEqual';
33
+ import last from 'lodash/last';
34
+ import {
35
+ KBars,
36
+ KButton,
37
+ KContainer,
38
+ KLabel,
39
+ KRadiusValue,
40
+ KSpacingValue,
41
+ KPopupProps,
42
+ KColors,
43
+ KDims,
44
+ } from '@droppii/libs';
45
+ import { Z_INDEX_PRIORITY } from '../../constants';
46
+ import { ScrollView } from 'react-native-gesture-handler';
47
+ import { WithPopupProps } from '../../types';
48
+
49
+ const UNIT = KSpacingValue['1rem'];
50
+ const STATUS_BAR_HEIGHT = KDims.os === 'ios' ? 0 : StatusBar.currentHeight || 0;
51
+ const VIEWABLE_HEIGHT =
52
+ KDims.os === 'ios'
53
+ ? Dimensions.get('screen').height
54
+ : Dimensions.get('window').height - STATUS_BAR_HEIGHT; // ignore statusBar area & soft navigation bar height
55
+
56
+ const PADDING_VERTICAL = KDims.isIphoneX ? UNIT * 3 : UNIT * 2.25;
57
+ const PADDING_HORIZONTAL = UNIT;
58
+ const CONTENT_MAX_HEIGHT = VIEWABLE_HEIGHT - 2 * PADDING_VERTICAL;
59
+
60
+ const Popup = forwardRef<WithPopupProps>((_, ref) => {
61
+ const queue = useRef<KPopupProps[]>([]);
62
+ const [data, setData] = useState<KPopupProps | undefined>(undefined);
63
+
64
+ const scale = useSharedValue(1);
65
+
66
+ const {
67
+ touchOutsideToDismiss = true,
68
+ header,
69
+ actions,
70
+ backgroundColor = KColors.white,
71
+ wrapperStyle = {},
72
+ } = data || {};
73
+
74
+ const { showCloseButton, subTitle, title, alignment } = header || {};
75
+
76
+ const dismiss = useCallback(() => {
77
+ const newPayload = queue.current.shift();
78
+ if (newPayload) {
79
+ scale.value = withSequence(
80
+ withSpring(0.9, { mass: 0.3 }),
81
+ withSpring(1, { mass: 0.3 })
82
+ );
83
+ }
84
+ setData(newPayload);
85
+ }, [scale]);
86
+
87
+ useImperativeHandle(
88
+ ref,
89
+ () => ({
90
+ open: (payload) => {
91
+ if (!isEqual(last(queue.current), payload)) {
92
+ if (data) {
93
+ scale.value = withSequence(
94
+ withSpring(1.1, { mass: 0.3 }),
95
+ withSpring(1, { mass: 0.3 })
96
+ );
97
+ queue.current?.push(payload);
98
+ } else {
99
+ setData(payload);
100
+ Keyboard.dismiss();
101
+ }
102
+ }
103
+ },
104
+ dismiss,
105
+ dismissAll: () => {
106
+ setData(undefined);
107
+ queue.current = [];
108
+ },
109
+ }),
110
+ [dismiss, scale, data]
111
+ );
112
+
113
+ useEffect(() => {
114
+ if (data && KDims.os === 'android') {
115
+ const sub = BackHandler.addEventListener('hardwareBackPress', () => {
116
+ if (touchOutsideToDismiss) {
117
+ dismiss?.();
118
+ return true;
119
+ }
120
+ return false;
121
+ });
122
+
123
+ return () => {
124
+ sub.remove();
125
+ };
126
+ }
127
+
128
+ return undefined;
129
+ // eslint-disable-next-line react-hooks/exhaustive-deps
130
+ }, [data]);
131
+
132
+ const onPressWrapper = useCallback(
133
+ (onPress: any) => {
134
+ onPress?.();
135
+ dismiss();
136
+ },
137
+ [dismiss]
138
+ );
139
+
140
+ const renderHeader = useMemo(() => {
141
+ if (!data || isEmpty(data.header)) {
142
+ return null;
143
+ }
144
+
145
+ return (
146
+ <KContainer.View style={styles.header} padding="1rem">
147
+ {showCloseButton && alignment !== 'left' && (
148
+ <KContainer.View marginR={'1rem'}>
149
+ <KButton.Close color={KColors.transparent} />
150
+ </KContainer.View>
151
+ )}
152
+ <KContainer.View
153
+ alignItems={alignment === 'left' ? 'flex-start' : 'center'}
154
+ flex
155
+ justifyContent
156
+ >
157
+ {!!title && (
158
+ <KLabel.Text
159
+ typo={title.typo || 'TextLgBold'}
160
+ color={title.color}
161
+ numberOfLines={2}
162
+ textAlign="left"
163
+ >
164
+ {title.text}
165
+ </KLabel.Text>
166
+ )}
167
+ {!!subTitle && (
168
+ <KLabel.Text
169
+ typo={subTitle.typo || 'TextSmNormal'}
170
+ color={subTitle.color || KColors.gray.light}
171
+ numberOfLines={2}
172
+ marginT="0.25rem"
173
+ >
174
+ {subTitle.text}
175
+ </KLabel.Text>
176
+ )}
177
+ </KContainer.View>
178
+ {showCloseButton && (
179
+ <KContainer.View marginL={'1rem'}>
180
+ <KButton.Close onPress={dismiss} />
181
+ </KContainer.View>
182
+ )}
183
+ </KContainer.View>
184
+ );
185
+ }, [alignment, data, dismiss, showCloseButton, subTitle, title]);
186
+
187
+ const renderActions = useMemo(() => {
188
+ if (!actions?.buttons) {
189
+ return null;
190
+ }
191
+
192
+ actions.buttons = actions.buttons.map((i: any) => {
193
+ const clone = { ...i };
194
+ delete clone.onPress;
195
+ set(clone, 'onPress', () => onPressWrapper(() => i.onPress?.()));
196
+ return clone;
197
+ });
198
+ return (
199
+ <KContainer.View paddingH="1rem" style={styles.actions}>
200
+ <KBars.ActionBar {...(actions as any)} />
201
+ </KContainer.View>
202
+ );
203
+ }, [actions, onPressWrapper]);
204
+
205
+ const onStartShouldSetResponder = useCallback(() => true, []);
206
+
207
+ const renderBody = useMemo(() => {
208
+ if (!data || !data.body) {
209
+ return null;
210
+ }
211
+
212
+ const {
213
+ body: { message, renderContent, scrollable = true },
214
+ } = data;
215
+
216
+ const content = (
217
+ <KContainer.View onStartShouldSetResponder={onStartShouldSetResponder}>
218
+ {message ? (
219
+ <KContainer.View padding={'1rem'}>
220
+ <KLabel.Text typo={message.typo} color={message.color} textAlign>
221
+ {message.text}
222
+ </KLabel.Text>
223
+ </KContainer.View>
224
+ ) : (
225
+ (renderContent?.(dismiss) ?? null)
226
+ )}
227
+ </KContainer.View>
228
+ );
229
+
230
+ if (scrollable) {
231
+ return <ScrollView bounces={false}>{content}</ScrollView>;
232
+ }
233
+
234
+ return content;
235
+ }, [data, dismiss, onStartShouldSetResponder]);
236
+
237
+ const stopPropagation = useCallback((e: any) => {
238
+ e.stopPropagation();
239
+ }, []);
240
+
241
+ const rStyle = useAnimatedStyle(() => ({
242
+ transform: [{ scale: scale.value }],
243
+ }));
244
+
245
+ if (!data) {
246
+ return null;
247
+ }
248
+
249
+ return (
250
+ <TouchableWithoutFeedback
251
+ onPress={touchOutsideToDismiss ? dismiss : undefined}
252
+ >
253
+ <Animated.View
254
+ style={[styles.wrapper, wrapperStyle]}
255
+ entering={FadeIn}
256
+ exiting={FadeOut}
257
+ >
258
+ <TouchableWithoutFeedback onPress={stopPropagation}>
259
+ <Animated.View entering={FadeInUp} exiting={FadeOutDown}>
260
+ <Animated.View
261
+ style={[
262
+ styles.content,
263
+ rStyle,
264
+ { backgroundColor },
265
+ data?.contentStyle,
266
+ ]}
267
+ >
268
+ {renderHeader}
269
+ {renderBody}
270
+ {renderActions}
271
+ </Animated.View>
272
+ </Animated.View>
273
+ </TouchableWithoutFeedback>
274
+ </Animated.View>
275
+ </TouchableWithoutFeedback>
276
+ );
277
+ });
278
+
279
+ (Popup as ComponentType<any>).displayName = 'Portal.Popup';
280
+
281
+ export default memo(Popup);
282
+
283
+ const styles = StyleSheet.create({
284
+ flex: {
285
+ flex: 1,
286
+ },
287
+ wrapper: {
288
+ // @ts-ignore
289
+ ...StyleSheet.absoluteFill,
290
+ zIndex: Z_INDEX_PRIORITY.popup,
291
+ backgroundColor: KColors.overlayDark,
292
+ paddingHorizontal: PADDING_HORIZONTAL,
293
+ paddingVertical: PADDING_VERTICAL,
294
+ justifyContent: 'center',
295
+ },
296
+ avoiding: {
297
+ flex: 1,
298
+ justifyContent: 'center',
299
+ },
300
+ content: {
301
+ maxHeight: CONTENT_MAX_HEIGHT,
302
+ overflow: 'hidden',
303
+ borderRadius: KRadiusValue['4x'],
304
+ },
305
+ header: {
306
+ flexDirection: 'row',
307
+ alignItems: 'center',
308
+ borderBottomWidth: 1,
309
+ borderColor: KColors.border.light,
310
+ overflow: 'hidden',
311
+ },
312
+ actions: {
313
+ borderTopWidth: 1,
314
+ borderColor: KColors.border.light,
315
+ overflow: 'hidden',
316
+ },
317
+ item: {
318
+ flex: 1,
319
+ justifyContent: 'center',
320
+ alignItems: 'center',
321
+ },
322
+ actionsVertical: {
323
+ flexDirection: 'column',
324
+ },
325
+ actionsHorizontal: {
326
+ flexDirection: 'row',
327
+ },
328
+ itemWrapperLastHorizontal: {
329
+ marginRight: 0,
330
+ },
331
+ verticalItem: {
332
+ borderBottomWidth: 1,
333
+ borderColor: KColors.border.light,
334
+ },
335
+ verticalLastItem: {
336
+ borderBottomWidth: 0,
337
+ },
338
+ horizontalItem: {
339
+ borderRightWidth: 1,
340
+ borderColor: KColors.border.light,
341
+ },
342
+ horizontalLastItem: {
343
+ borderRightWidth: 0,
344
+ },
345
+ });
@@ -1,11 +1,15 @@
1
1
  import { memo } from 'react';
2
2
  import ToastBar from './Toast';
3
- import { toastRef } from '../../constants';
3
+ import BottomSheet from './BottomSheet';
4
+ import Popup from './Popup';
5
+ import { toastRef, bottomSheetRef, popupRef } from '../../constants';
4
6
 
5
7
  const Portal = memo(() => {
6
8
  return (
7
9
  <>
8
10
  <ToastBar ref={toastRef} />
11
+ <BottomSheet ref={bottomSheetRef} />
12
+ <Popup ref={popupRef} />
9
13
  </>
10
14
  );
11
15
  });