ordering-ui-react-native 0.22.75 → 0.22.76-release

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 (137) hide show
  1. package/package.json +5 -7
  2. package/src/components/BusinessesListing/index.tsx +1 -1
  3. package/src/components/Checkout/index.tsx +40 -39
  4. package/src/components/VerifyPhone/styles.tsx +1 -2
  5. package/src/context/OfflineActions/index.tsx +236 -0
  6. package/src/providers/AlertProvider.tsx +3 -1
  7. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +5 -3
  8. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +1 -0
  9. package/themes/business/src/components/BusinessController/index.tsx +8 -3
  10. package/themes/business/src/components/BusinessProductList/index.tsx +3 -2
  11. package/themes/business/src/components/Chat/index.tsx +15 -3
  12. package/themes/business/src/components/DriverMap/index.tsx +44 -33
  13. package/themes/business/src/components/FloatingButton/index.tsx +3 -2
  14. package/themes/business/src/components/LanguageSelector/index.tsx +1 -1
  15. package/themes/business/src/components/LoginForm/index.tsx +123 -98
  16. package/themes/business/src/components/LogoutButton/index.tsx +13 -4
  17. package/themes/business/src/components/MapView/RenderMarker.tsx +146 -0
  18. package/themes/business/src/components/MapView/index.tsx +68 -142
  19. package/themes/business/src/components/NewOrderNotification/index.tsx +38 -54
  20. package/themes/business/src/components/OrderDetails/Business.tsx +56 -20
  21. package/themes/business/src/components/OrderDetails/Delivery.tsx +111 -42
  22. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +146 -36
  23. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +51 -28
  24. package/themes/business/src/components/OrderDetails/styles.tsx +39 -3
  25. package/themes/business/src/components/OrderDetails/usePrinterCommands.tsx +17 -16
  26. package/themes/business/src/components/OrderDetailsLogistic/index.tsx +3 -2
  27. package/themes/business/src/components/OrderSummary/index.tsx +271 -176
  28. package/themes/business/src/components/OrdersListManager/index.tsx +13 -1
  29. package/themes/business/src/components/OrdersOption/index.tsx +207 -144
  30. package/themes/business/src/components/OrdersOption/styles.tsx +14 -0
  31. package/themes/business/src/components/PreviousMessages/index.tsx +26 -3
  32. package/themes/business/src/components/PreviousOrders/OrderItem.tsx +20 -8
  33. package/themes/business/src/components/PreviousOrders/index.tsx +74 -66
  34. package/themes/business/src/components/PreviousOrders/styles.tsx +2 -1
  35. package/themes/business/src/components/PrinterEdition/MessageAlert.tsx +33 -0
  36. package/themes/business/src/components/PrinterEdition/index.tsx +143 -75
  37. package/themes/business/src/components/PrinterEdition/printerList.tsx +23 -0
  38. package/themes/business/src/components/PrinterSettings/index.tsx +1 -1
  39. package/themes/business/src/components/ProductItemAccordion/index.tsx +15 -16
  40. package/themes/business/src/components/ReviewCustomer/index.tsx +2 -0
  41. package/themes/business/src/components/StoresList/index.tsx +2 -2
  42. package/themes/business/src/components/UserProfileForm/index.tsx +48 -10
  43. package/themes/business/src/components/UserProfileForm/styles.tsx +7 -0
  44. package/themes/business/src/components/WebsocketStatus/index.tsx +2 -2
  45. package/themes/business/src/config/currency.tsx +1010 -0
  46. package/themes/business/src/hooks/useLocation.tsx +16 -12
  47. package/themes/business/src/layouts/SafeAreaContainer.tsx +35 -19
  48. package/themes/business/src/types/index.tsx +26 -4
  49. package/themes/business/src/utils/index.tsx +26 -2
  50. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  51. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  52. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  53. package/themes/kiosk/src/components/Checkout/index.tsx +9 -5
  54. package/themes/kiosk/src/components/CustomerName/index.tsx +1 -1
  55. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  56. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  57. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +8 -10
  58. package/themes/kiosk/src/components/PaymentOptions/index.tsx +121 -57
  59. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  60. package/themes/original/index.tsx +223 -219
  61. package/themes/original/src/components/AddressForm/index.tsx +56 -17
  62. package/themes/original/src/components/AppleLogin/index.tsx +3 -4
  63. package/themes/original/src/components/BusinessController/index.tsx +4 -2
  64. package/themes/original/src/components/BusinessItemAccordion/index.tsx +8 -3
  65. package/themes/original/src/components/BusinessListingSearch/BusinessSearchFooter.tsx +102 -90
  66. package/themes/original/src/components/BusinessListingSearch/BusinessSearchHeader.tsx +7 -3
  67. package/themes/original/src/components/BusinessListingSearch/index.tsx +8 -13
  68. package/themes/original/src/components/BusinessPreorder/index.tsx +30 -17
  69. package/themes/original/src/components/BusinessProductsList/SubcategoriesComponent/index.tsx +72 -69
  70. package/themes/original/src/components/BusinessProductsList/index.tsx +4 -5
  71. package/themes/original/src/components/BusinessProductsList/styles.tsx +0 -3
  72. package/themes/original/src/components/BusinessProductsListing/index.tsx +5 -4
  73. package/themes/original/src/components/BusinessesListing/Layout/Appointment/styles.tsx +1 -0
  74. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +2 -1
  75. package/themes/original/src/components/Cart/index.tsx +43 -12
  76. package/themes/original/src/components/Checkout/index.tsx +126 -98
  77. package/themes/original/src/components/FloatingButton/index.tsx +1 -1
  78. package/themes/original/src/components/GPSButton/index.tsx +2 -1
  79. package/themes/original/src/components/GoogleMap/index.tsx +3 -2
  80. package/themes/original/src/components/Help/functions.tsx +76 -0
  81. package/themes/original/src/components/Help/index.tsx +74 -29
  82. package/themes/original/src/components/Help/styles.tsx +4 -1
  83. package/themes/original/src/components/HelpOptions/index.tsx +53 -0
  84. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +1 -1
  85. package/themes/original/src/components/Home/index.tsx +36 -11
  86. package/themes/original/src/components/LastOrder/index.tsx +1 -1
  87. package/themes/original/src/components/LoginForm/index.tsx +11 -5
  88. package/themes/original/src/components/MessageListing/index.tsx +1 -1
  89. package/themes/original/src/components/Messages/index.tsx +562 -555
  90. package/themes/original/src/components/MomentOption/TimeListItem.tsx +56 -0
  91. package/themes/original/src/components/MomentOption/index.tsx +141 -61
  92. package/themes/original/src/components/MomentOption/styles.tsx +1 -1
  93. package/themes/original/src/components/MomentSelector/index.tsx +5 -2
  94. package/themes/original/src/components/MultiCheckout/index.tsx +78 -33
  95. package/themes/original/src/components/MultiOrdersDetails/SingleOrderCard.tsx +2 -2
  96. package/themes/original/src/components/MultiOrdersDetails/index.tsx +2 -2
  97. package/themes/original/src/components/NavBar/index.tsx +6 -2
  98. package/themes/original/src/components/NotFoundSource/index.tsx +40 -39
  99. package/themes/original/src/components/NotFoundSource/styles.tsx +18 -9
  100. package/themes/original/src/components/OrderDetails/OrderEta.tsx +4 -3
  101. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +11 -4
  102. package/themes/original/src/components/OrderDetails/index.tsx +44 -20
  103. package/themes/original/src/components/OrderDetails/styles.tsx +0 -1
  104. package/themes/original/src/components/OrderProgress/index.tsx +5 -4
  105. package/themes/original/src/components/OrderSummary/index.tsx +32 -11
  106. package/themes/original/src/components/OrderTypeSelector/index.tsx +120 -120
  107. package/themes/original/src/components/OrdersOption/index.tsx +325 -325
  108. package/themes/original/src/components/PaymentOptionWallet/index.tsx +1 -0
  109. package/themes/original/src/components/PaymentOptions/index.tsx +471 -459
  110. package/themes/original/src/components/PhoneInputNumber/index.tsx +92 -7
  111. package/themes/original/src/components/ProductItemAccordion/index.tsx +28 -37
  112. package/themes/original/src/components/ProductOptionSubOption/index.tsx +15 -14
  113. package/themes/original/src/components/ServiceForm/index.tsx +2 -2
  114. package/themes/original/src/components/SignupForm/index.tsx +40 -24
  115. package/themes/original/src/components/SingleOrderCard/index.tsx +8 -5
  116. package/themes/original/src/components/SingleProductCard/index.tsx +2 -1
  117. package/themes/original/src/components/SingleProductCard/styles.tsx +0 -3
  118. package/themes/original/src/components/StripeCardsList/index.tsx +7 -1
  119. package/themes/original/src/components/StripeElementsForm/index.tsx +2 -2
  120. package/themes/original/src/components/TaxInformation/index.tsx +3 -2
  121. package/themes/original/src/components/UpsellingProducts/UpsellingContent.tsx +7 -2
  122. package/themes/original/src/components/UserDetails/index.tsx +17 -16
  123. package/themes/original/src/components/UserFormDetails/index.tsx +109 -67
  124. package/themes/original/src/components/UserVerification/index.tsx +18 -5
  125. package/themes/original/src/components/VerifyPhone/index.tsx +1 -1
  126. package/themes/original/src/components/shared/OInput.tsx +97 -97
  127. package/themes/original/src/components/shared/OModal.tsx +7 -2
  128. package/themes/original/src/providers/AlertProvider.tsx +1 -1
  129. package/themes/original/src/types/index.tsx +700 -695
  130. package/themes/original/src/utils/index.tsx +50 -34
  131. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
  132. package/themes/original/src/components/HelpAccountAndPayment/index.tsx +0 -62
  133. package/themes/original/src/components/HelpAccountAndPayment/styles.tsx +0 -12
  134. package/themes/original/src/components/HelpGuide/index.tsx +0 -68
  135. package/themes/original/src/components/HelpGuide/styles.tsx +0 -12
  136. package/themes/original/src/components/HelpOrder/index.tsx +0 -71
  137. package/themes/original/src/components/HelpOrder/styles.tsx +0 -13
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect, useState } from 'react'
2
2
  import Clipboard from '@react-native-clipboard/clipboard';
3
- import { Messages as MessagesController, useSession, useUtils, useLanguage, ToastType, useToast } from 'ordering-components/native'
3
+ import { Messages as MessagesController, useSession, useUtils, useLanguage, ToastType, useToast, useConfig } from 'ordering-components/native'
4
4
  import { useTheme } from 'styled-components/native';
5
5
  import { launchImageLibrary } from 'react-native-image-picker'
6
6
  import { GiftedChat, Actions, ActionsProps, InputToolbar, Composer, Send, Bubble, MessageImage, InputToolbarProps, ComposerProps } from 'react-native-gifted-chat'
@@ -16,571 +16,578 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'
16
16
  import { getLogisticTag } from '../../utils'
17
17
 
18
18
  const ORDER_STATUS: any = {
19
- 0: 'ORDER_STATUS_PENDING',
20
- 1: 'ORDERS_COMPLETED',
21
- 2: 'ORDER_REJECTED',
22
- 3: 'ORDER_STATUS_IN_BUSINESS',
23
- 4: 'ORDER_READY',
24
- 5: 'ORDER_REJECTED_RESTAURANT',
25
- 6: 'ORDER_STATUS_CANCELLEDBYDRIVER',
26
- 7: 'ORDER_STATUS_ACCEPTEDBYRESTAURANT',
27
- 8: 'ORDER_CONFIRMED_ACCEPTED_BY_DRIVER',
28
- 9: 'ORDER_PICKUP_COMPLETED_BY_DRIVER',
29
- 10: 'ORDER_PICKUP_FAILED_BY_DRIVER',
30
- 11: 'ORDER_DELIVERY_COMPLETED_BY_DRIVER',
31
- 12: 'ORDER_DELIVERY_FAILED_BY_DRIVER',
32
- 13: 'PREORDER',
33
- 14: 'ORDER_NOT_READY',
34
- 15: 'ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER',
35
- 16: 'ORDER_STATUS_CANCELLED_BY_CUSTOMER',
36
- 17: 'ORDER_NOT_PICKEDUP_BY_CUSTOMER',
37
- 18: 'ORDER_DRIVER_ALMOST_ARRIVED_BUSINESS',
38
- 19: 'ORDER_DRIVER_ALMOST_ARRIVED_CUSTOMER',
39
- 20: 'ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS',
40
- 21: 'ORDER_CUSTOMER_ARRIVED_BUSINESS',
41
- 22: 'ORDER_LOOKING_FOR_DRIVER',
42
- 23: 'ORDER_DRIVER_ON_WAY'
19
+ 0: 'ORDER_STATUS_PENDING',
20
+ 1: 'ORDERS_COMPLETED',
21
+ 2: 'ORDER_REJECTED',
22
+ 3: 'ORDER_STATUS_IN_BUSINESS',
23
+ 4: 'ORDER_READY',
24
+ 5: 'ORDER_REJECTED_RESTAURANT',
25
+ 6: 'ORDER_STATUS_CANCELLEDBYDRIVER',
26
+ 7: 'ORDER_STATUS_ACCEPTEDBYRESTAURANT',
27
+ 8: 'ORDER_CONFIRMED_ACCEPTED_BY_DRIVER',
28
+ 9: 'ORDER_PICKUP_COMPLETED_BY_DRIVER',
29
+ 10: 'ORDER_PICKUP_FAILED_BY_DRIVER',
30
+ 11: 'ORDER_DELIVERY_COMPLETED_BY_DRIVER',
31
+ 12: 'ORDER_DELIVERY_FAILED_BY_DRIVER',
32
+ 13: 'PREORDER',
33
+ 14: 'ORDER_NOT_READY',
34
+ 15: 'ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER',
35
+ 16: 'ORDER_STATUS_CANCELLED_BY_CUSTOMER',
36
+ 17: 'ORDER_NOT_PICKEDUP_BY_CUSTOMER',
37
+ 18: 'ORDER_DRIVER_ALMOST_ARRIVED_BUSINESS',
38
+ 19: 'ORDER_DRIVER_ALMOST_ARRIVED_CUSTOMER',
39
+ 20: 'ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS',
40
+ 21: 'ORDER_CUSTOMER_ARRIVED_BUSINESS',
41
+ 22: 'ORDER_LOOKING_FOR_DRIVER',
42
+ 23: 'ORDER_DRIVER_ON_WAY',
43
+ 24: 'ORDER_DRIVER_WAITING_FOR_ORDER',
44
+ 25: 'ORDER_ACCEPTED_BY_DRIVER_COMPANY',
45
+ 26: 'ORDER_DRIVER_ARRIVED_CUSTOMER'
43
46
  }
44
47
 
45
48
  const filterSpecialStatus = ['prepared_in', 'delivered_in', 'delivery_datetime']
46
49
 
47
50
 
48
51
  const MessagesUI = (props: MessagesParams) => {
49
- const {
50
- type,
51
- order,
52
- messages,
53
- image,
54
- message,
55
- messagesToShow,
56
- sendMessage,
57
- setCanRead,
58
- setMessage,
59
- handleSend,
60
- setImage,
61
- readMessages,
62
- onClose,
63
- business,
64
- driver,
65
- onMessages,
66
- isMeesageListing
67
- } = props
68
-
69
- const [{ user }] = useSession()
70
- const [{ parseDate }] = useUtils()
71
- const [, t] = useLanguage()
72
- const [, { showToast }] = useToast();
73
-
74
- const [formattedMessages, setFormattedMessages] = useState<Array<any>>([])
75
- const [isKeyboardShow, setIsKeyboardShow] = useState(false)
76
- const previousStatus = [1, 2, 5, 6, 10, 11, 12, 16, 17]
77
- const chatDisabled = previousStatus.includes(order?.status)
78
- const { height } = useWindowDimensions();
79
- const { top, bottom } = useSafeAreaInsets();
80
-
81
- const theme = useTheme();
82
-
83
- const quickMessageList = [
84
- { key: 'customer_message_1', text: t('CUSTOMER_MESSAGE_1', 'Lorem ipsum 1') },
85
- { key: 'customer_message_2', text: t('CUSTOMER_MESSAGE_2', 'Lorem ipsum 2') },
86
- { key: 'customer_message_3', text: t('CUSTOMER_MESSAGE_3', 'Lorem ipsum 3') },
87
- { key: 'customer_message_4', text: t('CUSTOMER_MESSAGE_4', 'Lorem ipsum 4') }
88
- ]
89
-
90
- const handleClickQuickMessage = (text: string) => {
91
- setMessage && setMessage(`${message}${text}`)
92
- }
93
-
94
- const onChangeMessage = (val: string) => {
95
- setMessage && setMessage(val)
96
- }
97
-
98
- const removeImage = () => {
99
- setImage && setImage(null)
100
- }
101
-
102
- const handleImagePicker = () => {
103
- launchImageLibrary({ mediaType: 'photo', maxHeight: 2048, maxWidth: 2048, includeBase64: true }, (response: any) => {
104
- if (response?.didCancel) {
105
- showToast(ToastType.Error, t('IMAGE_CANCELLED', 'User cancelled image picker'));
106
- } else if (response?.errorMessage) {
107
- showToast(ToastType.Error, response.errorMessage);
108
- } else {
109
- if (response?.assets?.length > 0) {
110
- const image = response?.assets[0]
111
- const url = `data:${image.type};base64,${image.base64}`
112
- setImage && setImage(url);
113
- } else {
114
- showToast(ToastType.Error, t('IMAGE_NOT_FOUND', 'Image not found'));
115
- }
116
- }
117
- });
118
- };
119
-
120
- const onSubmit = (values: any) => {
121
- handleSend && handleSend()
122
- setImage && setImage(null)
123
- setMessage && setMessage('')
124
- }
125
-
126
- const messageConsole = (message: any) => {
127
- return message.change?.attribute !== 'driver_id'
128
- ?
129
- `${t('ORDER', 'Order')} ${t(message.change.attribute.toUpperCase(), message.change.attribute.replace('_', ' '))} ${t('CHANGED_FROM', 'Changed from')} ${filterSpecialStatus.includes(message.change.attribute)
130
- ? `${message.change.old === null ? '0' : message.change.old} ${t('TO', 'to')} ${message.change.new} ${t('MINUTES', 'Minutes')}`
131
- : `${message.change?.attribute !== 'logistic_status'
132
- ? message.change.old !== null && t(ORDER_STATUS[parseInt(message.change.old, 10)])
133
- : message.change.old !== null && getLogisticTag(message.change.old)} ${t('TO', 'to')} ${message.change?.attribute !== 'logistic_status'
134
- ? t(ORDER_STATUS[parseInt(message.change.new, 10)])
135
- : getLogisticTag(message.change.new)}`
136
- }`
137
- : message.change.new
138
- ?
139
- `${message.driver?.name} ${message.driver?.lastname !== null ? message.driver.lastname : ''} ${t('WAS_ASSIGNED_AS_DRIVER', 'Was assigned as driver')} ${message.comment ? message.comment.length : ''}`
140
- :
141
- `${t('DRIVER_UNASSIGNED', 'Driver unassigned')}`
142
- }
143
-
144
- useEffect(() => {
145
- let newMessages: Array<any> = []
146
- const _console = `${t('ORDER_PLACED_FOR', 'Order placed for')} ${parseDate(order?.created_at)} ${t('VIA', 'Via')} ${order?.app_id ? t(order?.app_id.toUpperCase(), order?.app_id) : t('OTHER', 'Other')}`
147
- const firstMessage = {
148
- _id: 0,
149
- text: _console,
150
- createdAt: parseDate(order?.created_at, { outputFormat: 'YYYY-MM-DD HH:mm:ss' }),
151
- system: true
152
- }
153
- const newMessage: any = [];
154
- messages.messages.map((message: any) => {
155
- if (message.change?.attribute === 'driver_group_id') return
156
- if (business && message.type !== 0 && (messagesToShow?.messages?.length || message?.can_see?.includes('2'))) {
157
- newMessage.push({
158
- _id: message?.id,
159
- text: message.type === 1 ? messageConsole(message) : message.comment,
160
- createdAt: message.type !== 0 && parseDate(message?.created_at, { outputFormat: 'YYYY-MM-DD HH:mm:ss' }),
161
- image: message.source,
162
- system: message.type === 1,
163
- user: {
164
- _id: message.author && message.author.id,
165
- name: message.author && message.author.name,
166
- avatar: message.author && (message.author.id !== user.id && type === USER_TYPE.DRIVER ? order?.driver?.photo : order?.business?.logo)
167
- }
168
- });
169
- }
170
-
171
- if (driver && message.type !== 0 && (messagesToShow?.messages?.length || message?.can_see?.includes('4'))) {
172
- newMessage.push({
173
- _id: message?.id,
174
- text: message.type === 1 ? messageConsole(message) : message.comment,
175
- createdAt: message.type !== 0 && parseDate(message?.created_at, { outputFormat: 'YYYY-MM-DD HH:mm:ss' }),
176
- image: message.source,
177
- system: message.type === 1,
178
- user: {
179
- _id: message.author && message.author.id,
180
- name: message.author && message.author.name,
181
- avatar: message.author && (message.author.id !== user.id && type === USER_TYPE.DRIVER ? order?.driver?.photo : order?.business?.logo)
182
- }
183
- });
184
- }
185
-
186
- if (message.type === 0) {
187
- newMessage.push(firstMessage);
188
- }
189
- })
190
- setFormattedMessages(newMessage.reverse())
191
- }, [messages.messages.length, business, driver])
192
-
193
- useEffect(() => {
194
- const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
195
- setIsKeyboardShow(true)
196
- })
197
- const keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => {
198
- setIsKeyboardShow(false)
199
- })
200
- const keyboardWillHideListener = Keyboard.addListener('keyboardWillHide', () => {
201
- setIsKeyboardShow(false)
202
- })
203
- return () => {
204
- keyboardDidShowListener.remove()
205
- keyboardDidHideListener.remove()
206
- keyboardWillHideListener.remove()
207
- }
208
- }, [])
209
-
210
- useEffect(() => {
211
- if (business) setCanRead({ business: true, administrator: true, customer: true, driver: false })
212
- else if (driver) setCanRead({ business: false, administrator: true, customer: true, driver: true })
213
- }, [business, driver])
214
-
215
- const RenderActions = (props: any) => {
216
- return (
217
- <Actions
218
- {...props}
219
- options={{
220
- 'Send Image': () => handleImagePicker(),
221
- }}
222
- containerStyle={styles.containerActions}
223
- optionTintColor='#222845'
224
- icon={() => (
225
- <>
226
- <OIconButton
227
- borderColor={theme.colors.white}
228
- style={{ width: 32, height: 44, borderRadius: 10, backgroundColor: theme.colors.clear, borderColor: theme.colors.clear }}
229
- icon={image ? { uri: image } : theme.images.general.image}
230
- iconStyle={{ borderRadius: image ? 10 : 0, width: image ? 32 : 16, height: image ? 32 : 16 }}
231
- onClick={handleImagePicker}
232
- iconCover
233
- />
234
- {image && (
235
- <TouchableOpacity
236
- style={{ position: 'absolute', top: -5, right: -5, borderColor: theme.colors.backgroundDark, backgroundColor: theme.colors.white, borderRadius: 25 }}
237
- onPress={removeImage}
238
- >
239
- <MaterialCommunityIcon name='close-circle-outline' color={theme.colors.backgroundDark} size={24} />
240
- </TouchableOpacity>
241
- )}
242
- </>
243
- )}
244
- />
245
- )
246
- }
247
-
248
- const renderAccessory = () => {
249
- return (
250
- !chatDisabled &&
251
- <QuickMessageContainer
252
- style={{
253
- marginLeft: 10,
254
- marginBottom: 10
255
- }}
256
- contentContainerStyle={{
257
- alignItems: 'center',
258
- }}
259
- horizontal
260
- showsHorizontalScrollIndicator={false}
261
- >
262
- {quickMessageList.map((quickMessage, i) => (
263
- <OButton
264
- key={i}
265
- text={quickMessage.text}
266
- bgColor='#E9ECEF'
267
- borderColor='#E9ECEF'
268
- imgRightSrc={null}
269
- textStyle={{
270
- fontSize: 11,
271
- lineHeight: 16,
272
- color: '#414954'
273
- }}
274
- style={{ ...styles.editButton }}
275
- onClick={() => handleClickQuickMessage(quickMessage.text)}
276
- />
277
- ))}
278
- </QuickMessageContainer>
279
- )
280
- }
281
-
282
- const renderInputToolbar = (props: typeof InputToolbarProps) => (
283
- <InputToolbar
284
- {...props}
285
- containerStyle={{
286
- padding: Platform.OS === 'ios' && isKeyboardShow ? 0 : 10,
287
- flexDirection: 'column-reverse'
288
- }}
289
- primaryStyle={{ alignItems: 'center', justifyContent: 'flex-start' }}
290
- renderAccessory={() => renderAccessory()}
291
- />
292
- )
293
-
294
- const renderComposer = (props: typeof ComposerProps) => (
295
- chatDisabled ? (
296
- <View
297
- style={{
298
- width: '100%',
299
- flexDirection: 'column',
300
- alignItems: 'center'
301
- }}
302
- >
303
- <MaterialCommunityIcon
304
- name='close-octagon-outline'
305
- size={24}
306
- />
307
- <OText size={14}>{t('NOT_SEND_MESSAGES', 'You can\'t send messages because the order has ended')}</OText>
308
- </View>
309
- ) : (
310
- <View style={{
311
- flexDirection: 'row', width: '80%', alignItems: 'center', backgroundColor: theme.colors.backgroundGray100,
312
- borderRadius: 7.6,
313
- }}>
314
- <Composer
315
- {...props}
316
- textInputStyle={{
317
- height: 32,
318
- minHeight: 32,
319
- alignItems: 'center',
320
- justifyContent: 'center',
321
- paddingHorizontal: 12,
322
- borderColor: '#DBDCDB',
323
- color: '#010300',
324
- }}
325
- textInputProps={{
326
- value: message,
327
- onSubmitEditing: onSubmit,
328
- returnKeyType: message ? 'send' : 'done',
329
- blurOnSubmit: true,
330
- multiline: false,
331
- numberOfLines: 1,
332
- autoCorrect: false,
333
- autoCompleteType: 'off',
334
- enablesReturnKeyAutomatically: false
335
- }}
336
- placeholder={t('WRITE_MESSAGE', 'Write message...')}
337
- />
338
- <RenderActions {...props} />
339
- </View>
340
- )
341
- )
342
-
343
- const renderSend = (props: any) => {
344
- const isDisabled = (sendMessage?.loading || (message === '' && !image) || messages?.loading)
345
- return (
346
- <Send
347
- {...props}
348
- disabled={isDisabled}
349
- alwaysShowSend
350
- containerStyle={styles.containerSend}
351
- >
352
- <OIconButton
353
- onClick={onSubmit}
354
- style={{
355
- height: 44,
356
- width: 44,
357
- borderRadius: 7.6,
358
- opacity: isDisabled ? 0.2 : 1,
359
- borderColor: isDisabled ? theme.colors.secondary : theme.colors.primary,
360
- backgroundColor: isDisabled ? theme.colors.secondary : theme.colors.primary,
361
- }}
362
- iconStyle={{ marginTop: 3, marginRight: 2 }}
363
- icon={theme.images.general.enter}
364
- iconColor={isDisabled ? '#000' : '#fff'}
365
- disabled={isDisabled}
366
- disabledColor={theme.colors.secondary}
367
- />
368
- </Send>
369
- )
370
- }
371
-
372
- const renderBubble = (props: any) => (
373
- <Bubble
374
- {...props}
375
- textStyle={{
376
- left: {},
377
- right: { color: theme.colors.white }
378
- }}
379
- containerStyle={{
380
- left: { marginVertical: 5, borderBottomRightRadius: 7.6 },
381
- right: { marginVertical: 5, borderBottomRightRadius: 7.6 }
382
- }}
383
- wrapperStyle={{
384
- left: { backgroundColor: '#f7f7f7', padding: 5, borderBottomLeftRadius: 0 },
385
- right: { backgroundColor: theme.colors.primary, padding: 5, borderBottomRightRadius: 0 }
386
- }}
387
- />
388
- )
389
-
390
- const renderMessageImage = (props: any) => (
391
- <MessageImage
392
- {...props}
393
- />
394
- )
395
-
396
- const renderScrollToBottomComponent = () => (
397
- <MaterialCommunityIcon name='chevron-double-down' size={32} />
398
- )
399
-
400
- const getViewHeight = () => {
401
- if (Platform.OS === 'android') {
402
- return '100%';
403
- } else {
404
- return height - top - bottom - (isKeyboardShow ? 48 : 0);
405
- }
406
- }
407
-
408
- const onLongPress = (context: any, message: any) => {
409
- const options = [
410
- t('COPY_TEXT', 'Copy text'),
411
- t('CANCEL', 'Cancel'),
412
- ];
413
- const cancelButtonIndex = options.length - 1;
414
- context.actionSheet().showActionSheetWithOptions({
415
- options,
416
- cancelButtonIndex
417
- }, (buttonIndex: any) => buttonIndex === 0 && Clipboard.setString(message.text)
418
- );
419
- }
420
-
421
- useEffect(() => {
422
- if (!order?.id || messages?.loading) return
423
- readMessages && readMessages()
424
- }, [order?.id, messages?.loading])
425
-
426
- return (
427
- <View style={{ height: getViewHeight(), width: '100%', paddingTop: 12, backgroundColor: 'white' }}>
428
- <Wrapper>
429
- {!isMeesageListing ? (
430
- <Header>
431
- <TouchableOpacity onPress={onClose} style={{ paddingStart: 10, borderColor: theme.colors.clear }}>
432
- <AntDesignIcon name='arrowleft' size={26} />
433
- </TouchableOpacity>
434
- <View style={{ marginRight: 10, shadowColor: theme.colors.black, shadowOpacity: 0.1, shadowOffset: { width: 0, height: 1 }, shadowRadius: 2 }}>
435
- <OIcon
436
- url={type === USER_TYPE.DRIVER ? order?.driver?.photo : order?.business?.logo}
437
- width={32}
438
- height={32}
439
- style={{ borderRadius: 7.6 }}
440
- />
441
- </View>
442
- <TitleHeader>
443
- <OText size={14} lineHeight={21} weight={'600'}>{type === USER_TYPE.DRIVER ? order?.driver?.name : order?.business?.name}</OText>
444
- <OText size={12} color={theme.colors.textSecondary}>{type === USER_TYPE.DRIVER ? t('DRIVER', 'Driver') : t('BUSINESS', 'Business')}</OText>
445
- </TitleHeader>
446
- </Header>
447
- ) : (
448
- <ProfileMessageHeader>
449
- <View style={{ ...styles.headerTitle }}>
450
- <TouchableOpacity onPress={onClose} style={styles.headerItem}>
451
- <AntDesignIcon name='arrowleft' size={26} />
452
- </TouchableOpacity>
453
- <OText size={18}>{t('ORDER', theme?.defaultLanguages?.ORDER || 'Order')} #{order?.id}</OText>
454
- </View>
455
- <View style={{ ...styles.typeWraper }}>
456
- {order.business && (
457
- <TouchableOpacity
458
- onPress={() => onMessages({ business: true, driver: false })}
459
- >
460
- <MessageTypeItem
461
- active={business}
462
- >
463
- <OIcon
464
- url={order?.business?.logo || theme.images.dummies.businessLogo}
465
- width={32}
466
- height={32}
467
- style={{ borderRadius: 32 }}
468
- />
469
- </MessageTypeItem>
470
- </TouchableOpacity>
471
- )}
472
-
473
- {order?.driver && (
474
- <TouchableOpacity
475
- onPress={() => onMessages({ business: false, driver: true })}
476
- >
477
- <MessageTypeItem
478
- active={driver}
479
- >
480
- <OIcon
481
- url={order?.driver?.photo}
482
- width={32}
483
- height={32}
484
- style={{ borderRadius: 32 }}
485
- />
486
- </MessageTypeItem>
487
- </TouchableOpacity>
488
- )}
489
- </View>
490
- </ProfileMessageHeader>
491
- )}
492
- <GiftedChat
493
- messages={formattedMessages}
494
- user={{
495
- _id: user.id,
496
- name: user.name,
497
- avatar: user.photo
498
- }}
499
- onSend={onSubmit}
500
- onInputTextChanged={onChangeMessage}
501
- alignTop
502
- onLongPress={(context: any, message: any) => onLongPress(context, message)}
503
- scrollToBottom
504
- renderAvatarOnTop
505
- renderUsernameOnMessage
506
- renderAvatar={() => null}
507
- renderInputToolbar={renderInputToolbar}
508
- renderComposer={renderComposer}
509
- renderSend={renderSend}
510
- renderBubble={renderBubble}
511
- renderMessageImage={renderMessageImage}
512
- scrollToBottomComponent={() => renderScrollToBottomComponent()}
513
- messagesContainerStyle={{
514
- paddingTop: 18,
515
- paddingHorizontal: 28,
516
- paddingBottom: 55
517
- }}
518
- isLoadingEarlier={messages.loading}
519
- renderLoading={() => <ActivityIndicator size="small" color="#000" />}
520
- keyboardShouldPersistTaps='handled'
521
- />
522
- </Wrapper>
523
- </View>
524
- )
52
+ const {
53
+ type,
54
+ order,
55
+ messages,
56
+ image,
57
+ message,
58
+ sendMessage,
59
+ setCanRead,
60
+ setMessage,
61
+ handleSend,
62
+ setImage,
63
+ readMessages,
64
+ onClose,
65
+ business,
66
+ driver,
67
+ onMessages,
68
+ isMeesageListing
69
+ } = props
70
+
71
+ const [{ user }] = useSession()
72
+ const [{ configs }] = useConfig()
73
+ const [{ parseDate }] = useUtils()
74
+ const [, t] = useLanguage()
75
+ const [, { showToast }] = useToast();
76
+
77
+ const [formattedMessages, setFormattedMessages] = useState<Array<any>>([])
78
+ const [isKeyboardShow, setIsKeyboardShow] = useState(false)
79
+ const previousStatus = [1, 2, 5, 6, 10, 11, 12, 15, 16, 17]
80
+ const chatDisabled = previousStatus.includes(order?.status)
81
+ const { height } = useWindowDimensions();
82
+ const { top, bottom } = useSafeAreaInsets();
83
+
84
+ const theme = useTheme();
85
+
86
+ const quickMessageList = [
87
+ { key: 'customer_message_1', text: t('CUSTOMER_MESSAGE_1', 'Lorem ipsum 1') },
88
+ { key: 'customer_message_2', text: t('CUSTOMER_MESSAGE_2', 'Lorem ipsum 2') },
89
+ { key: 'customer_message_3', text: t('CUSTOMER_MESSAGE_3', 'Lorem ipsum 3') },
90
+ { key: 'customer_message_4', text: t('CUSTOMER_MESSAGE_4', 'Lorem ipsum 4') }
91
+ ]
92
+
93
+ const handleClickQuickMessage = (text: string) => {
94
+ setMessage && setMessage(`${message}${text}`)
95
+ }
96
+
97
+ const onChangeMessage = (val: string) => {
98
+ setMessage && setMessage(val)
99
+ }
100
+
101
+ const removeImage = () => {
102
+ setImage && setImage(null)
103
+ }
104
+
105
+ const handleImagePicker = () => {
106
+ launchImageLibrary({ mediaType: 'photo', maxHeight: 2048, maxWidth: 2048, includeBase64: true }, (response: any) => {
107
+ if (response?.didCancel) {
108
+ showToast(ToastType.Error, t('IMAGE_CANCELLED', 'User cancelled image picker'));
109
+ } else if (response?.errorMessage) {
110
+ showToast(ToastType.Error, response.errorMessage);
111
+ } else {
112
+ if (response?.assets?.length > 0) {
113
+ const image = response?.assets[0]
114
+ const url = `data:${image.type};base64,${image.base64}`
115
+ setImage && setImage(url);
116
+ } else {
117
+ showToast(ToastType.Error, t('IMAGE_NOT_FOUND', 'Image not found'));
118
+ }
119
+ }
120
+ });
121
+ };
122
+
123
+ const onSubmit = (values: any) => {
124
+ handleSend && handleSend()
125
+ setImage && setImage(null)
126
+ setMessage && setMessage('')
127
+ }
128
+
129
+ const messageConsole = (message: any) => {
130
+ return message.change?.attribute !== 'driver_id'
131
+ ?
132
+ `${t('ORDER', 'Order')} ${t(message.change.attribute.toUpperCase(), message.change.attribute.replace('_', ' '))} ${t('CHANGED_FROM', 'Changed from')} ${filterSpecialStatus.includes(message.change.attribute)
133
+ ? `${message.change.old === null ? '0' : message.change.old} ${t('TO', 'to')} ${message.change.new} ${t('MINUTES', 'Minutes')}`
134
+ : `${message.change?.attribute !== 'logistic_status'
135
+ ? message.change.old !== null && t(ORDER_STATUS[parseInt(message.change.old, 10)])
136
+ : message.change.old !== null && getLogisticTag(message.change.old, t)} ${t('TO', 'to')} ${message.change?.attribute !== 'logistic_status'
137
+ ? t(ORDER_STATUS[parseInt(message.change.new, 10)])
138
+ : getLogisticTag(message.change.new, t)}`
139
+ }`
140
+ : message.change.new
141
+ ?
142
+ `${message.driver?.name} ${message.driver?.lastname !== null ? message.driver.lastname : ''} ${t('WAS_ASSIGNED_AS_DRIVER', 'Was assigned as driver')} ${message.comment ? message.comment.length : ''}`
143
+ :
144
+ `${t('DRIVER_UNASSIGNED', 'Driver unassigned')}`
145
+ }
146
+
147
+ useEffect(() => {
148
+ const newMessages: Array<any> = []
149
+ const _console = `${t('ORDER_PLACED_FOR', 'Order placed for')} ${parseDate(order?.created_at)} ${t('VIA', 'Via')} ${order?.app_id ? t(order?.app_id.toUpperCase(), order?.app_id) : t('OTHER', 'Other')}`
150
+ const firstMessage = {
151
+ _id: 0,
152
+ type: 0,
153
+ text: _console,
154
+ createdAt: parseDate(order?.created_at, { outputFormat: 'YYYY-MM-DD HH:mm:ss' }),
155
+ system: true
156
+ }
157
+ messages.messages.map((message: any) => {
158
+ if (message.change?.attribute === 'driver_group_id') return
159
+ if (business && message.type !== 0 && (props?.messagesToShow?.messages?.length || message?.can_see?.includes('2'))) {
160
+ newMessages.push({
161
+ _id: message?.id,
162
+ text: message.type === 1 ? messageConsole(message) : message.comment,
163
+ createdAt: message.type !== 0 && parseDate(message?.created_at, { outputFormat: 'YYYY-MM-DD HH:mm:ss' }),
164
+ image: message.source,
165
+ type: message.type,
166
+ system: message.type === 1,
167
+ user: {
168
+ _id: message.author && message.author.id,
169
+ name: message.author && message.author.name,
170
+ avatar: message.author && (message.author.id !== user.id && type === USER_TYPE.DRIVER ? order?.driver?.photo : order?.business?.logo)
171
+ }
172
+ });
173
+ }
174
+
175
+ if (driver && message.type !== 0 && (props?.messagesToShow?.messages?.length || message?.can_see?.includes('4'))) {
176
+ newMessages.push({
177
+ _id: message?.id,
178
+ text: message.type === 1 ? messageConsole(message) : message.comment,
179
+ createdAt: message.type !== 0 && parseDate(message?.created_at, { outputFormat: 'YYYY-MM-DD HH:mm:ss' }),
180
+ image: message.source,
181
+ type: message.type,
182
+ system: message.type === 1,
183
+ user: {
184
+ _id: message.author && message.author.id,
185
+ name: message.author && message.author.name,
186
+ avatar: message.author && (message.author.id !== user.id && type === USER_TYPE.DRIVER ? order?.driver?.photo : order?.business?.logo)
187
+ }
188
+ });
189
+ }
190
+
191
+ if (message.type === 0) {
192
+ newMessages.push(firstMessage);
193
+ }
194
+ })
195
+ let _arrayMessages = [...newMessages.reverse()]
196
+
197
+ setFormattedMessages(_arrayMessages);
198
+ }, [messages.messages.length, business, driver])
199
+
200
+ useEffect(() => {
201
+ const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
202
+ setIsKeyboardShow(true)
203
+ })
204
+ const keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => {
205
+ setIsKeyboardShow(false)
206
+ })
207
+ const keyboardWillHideListener = Keyboard.addListener('keyboardWillHide', () => {
208
+ setIsKeyboardShow(false)
209
+ })
210
+ return () => {
211
+ keyboardDidShowListener.remove()
212
+ keyboardDidHideListener.remove()
213
+ keyboardWillHideListener.remove()
214
+ }
215
+ }, [])
216
+
217
+ useEffect(() => {
218
+ if (business) setCanRead({ business: true, administrator: true, customer: true, driver: false })
219
+ else if (driver) setCanRead({ business: false, administrator: true, customer: true, driver: true })
220
+ }, [business, driver])
221
+
222
+ const RenderActions = (props: any) => {
223
+ return (
224
+ <Actions
225
+ {...props}
226
+ options={{
227
+ 'Send Image': () => handleImagePicker(),
228
+ }}
229
+ containerStyle={styles.containerActions}
230
+ optionTintColor='#222845'
231
+ icon={() => (
232
+ <>
233
+ <OIconButton
234
+ borderColor={theme.colors.white}
235
+ style={{ width: 32, height: 44, borderRadius: 10, backgroundColor: theme.colors.clear, borderColor: theme.colors.clear }}
236
+ icon={image ? { uri: image } : theme.images.general.image}
237
+ iconStyle={{ borderRadius: image ? 10 : 0, width: image ? 32 : 16, height: image ? 32 : 16 }}
238
+ onClick={handleImagePicker}
239
+ iconCover
240
+ />
241
+ {image && (
242
+ <TouchableOpacity
243
+ style={{ position: 'absolute', top: -5, right: -5, borderColor: theme.colors.backgroundDark, backgroundColor: theme.colors.white, borderRadius: 25 }}
244
+ onPress={removeImage}
245
+ >
246
+ <MaterialCommunityIcon name='close-circle-outline' color={theme.colors.backgroundDark} size={24} />
247
+ </TouchableOpacity>
248
+ )}
249
+ </>
250
+ )}
251
+ />
252
+ )
253
+ }
254
+
255
+ const renderAccessory = () => {
256
+ return (
257
+ !chatDisabled &&
258
+ <QuickMessageContainer
259
+ style={{
260
+ marginLeft: 10,
261
+ marginBottom: 10
262
+ }}
263
+ contentContainerStyle={{
264
+ alignItems: 'center',
265
+ }}
266
+ horizontal
267
+ showsHorizontalScrollIndicator={false}
268
+ >
269
+ {quickMessageList.map((quickMessage, i) => (
270
+ <OButton
271
+ key={i}
272
+ text={quickMessage.text}
273
+ bgColor='#E9ECEF'
274
+ borderColor='#E9ECEF'
275
+ imgRightSrc={null}
276
+ textStyle={{
277
+ fontSize: 11,
278
+ lineHeight: 16,
279
+ color: '#414954'
280
+ }}
281
+ style={{ ...styles.editButton }}
282
+ onClick={() => handleClickQuickMessage(quickMessage.text)}
283
+ />
284
+ ))}
285
+ </QuickMessageContainer>
286
+ )
287
+ }
288
+
289
+ const renderInputToolbar = (props: typeof InputToolbarProps) => (
290
+ <InputToolbar
291
+ {...props}
292
+ containerStyle={{
293
+ padding: Platform.OS === 'ios' && isKeyboardShow ? 0 : 10,
294
+ flexDirection: 'column-reverse'
295
+ }}
296
+ primaryStyle={{ alignItems: 'center', justifyContent: 'flex-start' }}
297
+ renderAccessory={() => renderAccessory()}
298
+ />
299
+ )
300
+
301
+ const renderComposer = (props: typeof ComposerProps) => (
302
+ chatDisabled ? (
303
+ <View
304
+ style={{
305
+ width: '100%',
306
+ flexDirection: 'column',
307
+ alignItems: 'center'
308
+ }}
309
+ >
310
+ <MaterialCommunityIcon
311
+ name='close-octagon-outline'
312
+ size={24}
313
+ />
314
+ <OText size={14}>{t('NOT_SEND_MESSAGES', 'You can\'t send messages because the order has ended')}</OText>
315
+ </View>
316
+ ) : (
317
+ <View style={{
318
+ flexDirection: 'row', width: '80%', alignItems: 'center', backgroundColor: theme.colors.backgroundGray100,
319
+ borderRadius: 7.6,
320
+ }}>
321
+ <Composer
322
+ {...props}
323
+ textInputStyle={{
324
+ height: 32,
325
+ minHeight: 32,
326
+ alignItems: 'center',
327
+ justifyContent: 'center',
328
+ paddingHorizontal: 12,
329
+ borderColor: '#DBDCDB',
330
+ color: '#010300',
331
+ }}
332
+ textInputProps={{
333
+ value: message,
334
+ onSubmitEditing: onSubmit,
335
+ returnKeyType: message ? 'send' : 'done',
336
+ blurOnSubmit: true,
337
+ multiline: false,
338
+ numberOfLines: 1,
339
+ autoCorrect: false,
340
+ autoCompleteType: 'off',
341
+ enablesReturnKeyAutomatically: false
342
+ }}
343
+ placeholder={t('WRITE_MESSAGE', 'Write message...')}
344
+ />
345
+ <RenderActions {...props} />
346
+ </View>
347
+ )
348
+ )
349
+
350
+ const renderSend = (props: any) => {
351
+ const isDisabled = (sendMessage?.loading || (message === '' && !image) || messages?.loading)
352
+ return (
353
+ <Send
354
+ {...props}
355
+ disabled={isDisabled}
356
+ alwaysShowSend
357
+ containerStyle={styles.containerSend}
358
+ >
359
+ <OIconButton
360
+ onClick={onSubmit}
361
+ style={{
362
+ height: 44,
363
+ width: 44,
364
+ borderRadius: 7.6,
365
+ opacity: isDisabled ? 0.2 : 1,
366
+ borderColor: isDisabled ? theme.colors.secondary : theme.colors.primary,
367
+ backgroundColor: isDisabled ? theme.colors.secondary : theme.colors.primary,
368
+ }}
369
+ iconStyle={{ marginTop: 3, marginRight: 2 }}
370
+ icon={theme.images.general.enter}
371
+ iconColor={isDisabled ? '#000' : '#fff'}
372
+ disabled={isDisabled}
373
+ disabledColor={theme.colors.secondary}
374
+ />
375
+ </Send>
376
+ )
377
+ }
378
+
379
+ const renderBubble = (props: any) => (
380
+ <Bubble
381
+ {...props}
382
+ textStyle={{
383
+ left: {},
384
+ right: { color: theme.colors.white }
385
+ }}
386
+ containerStyle={{
387
+ left: { marginVertical: 5, borderBottomRightRadius: 7.6 },
388
+ right: { marginVertical: 5, borderBottomRightRadius: 7.6 }
389
+ }}
390
+ wrapperStyle={{
391
+ left: { backgroundColor: '#f7f7f7', padding: 5, borderBottomLeftRadius: 0 },
392
+ right: { backgroundColor: theme.colors.primary, padding: 5, borderBottomRightRadius: 0 }
393
+ }}
394
+ />
395
+ )
396
+
397
+ const renderMessageImage = (props: any) => (
398
+ <MessageImage
399
+ {...props}
400
+ />
401
+ )
402
+
403
+ const renderScrollToBottomComponent = () => (
404
+ <MaterialCommunityIcon name='chevron-double-down' size={32} />
405
+ )
406
+
407
+ const getViewHeight = () => {
408
+ if (Platform.OS === 'android') {
409
+ return '100%';
410
+ } else {
411
+ return height - top - bottom - (isKeyboardShow ? 48 : 0);
412
+ }
413
+ }
414
+
415
+ const onLongPress = (context: any, message: any) => {
416
+ const options = [
417
+ t('COPY_TEXT', 'Copy text'),
418
+ t('CANCEL', 'Cancel'),
419
+ ];
420
+ const cancelButtonIndex = options.length - 1;
421
+ context.actionSheet().showActionSheetWithOptions({
422
+ options,
423
+ cancelButtonIndex
424
+ }, (buttonIndex: any) => buttonIndex === 0 && Clipboard.setString(message.text)
425
+ );
426
+ }
427
+
428
+ useEffect(() => {
429
+ if (!order?.id || messages?.loading) return
430
+ readMessages && readMessages()
431
+ }, [order?.id, messages?.loading])
432
+
433
+ return (
434
+ <View style={{ height: getViewHeight(), width: '100%', paddingTop: 12, backgroundColor: 'white' }}>
435
+ <Wrapper>
436
+ {!isMeesageListing ? (
437
+ <Header>
438
+ <TouchableOpacity onPress={onClose} style={{ paddingStart: 10, borderColor: theme.colors.clear }}>
439
+ <AntDesignIcon name='arrowleft' size={26} />
440
+ </TouchableOpacity>
441
+ <View style={{ marginRight: 10, shadowColor: theme.colors.black, shadowOpacity: 0.1, shadowOffset: { width: 0, height: 1 }, shadowRadius: 2 }}>
442
+ <OIcon
443
+ url={type === USER_TYPE.DRIVER ? order?.driver?.photo : order?.business?.logo}
444
+ width={32}
445
+ height={32}
446
+ style={{ borderRadius: 7.6 }}
447
+ />
448
+ </View>
449
+ <TitleHeader>
450
+ <OText size={14} lineHeight={21} weight={'600'}>{type === USER_TYPE.DRIVER ? order?.driver?.name : order?.business?.name}</OText>
451
+ <OText size={12} color={theme.colors.textSecondary}>{type === USER_TYPE.DRIVER ? t('DRIVER', 'Driver') : t('BUSINESS', 'Business')}</OText>
452
+ </TitleHeader>
453
+ </Header>
454
+ ) : (
455
+ <ProfileMessageHeader>
456
+ <View style={{ ...styles.headerTitle }}>
457
+ <TouchableOpacity onPress={onClose} style={styles.headerItem}>
458
+ <AntDesignIcon name='arrowleft' size={26} />
459
+ </TouchableOpacity>
460
+ <OText size={18}>{t('ORDER', theme?.defaultLanguages?.ORDER || 'Order')} #{order?.id}</OText>
461
+ </View>
462
+ <View style={{ ...styles.typeWraper }}>
463
+ {order.business && (
464
+ <TouchableOpacity
465
+ onPress={() => onMessages({ business: true, driver: false })}
466
+ >
467
+ <MessageTypeItem
468
+ active={business}
469
+ >
470
+ <OIcon
471
+ url={order?.business?.logo || theme.images.dummies.businessLogo}
472
+ width={32}
473
+ height={32}
474
+ style={{ borderRadius: 32 }}
475
+ />
476
+ </MessageTypeItem>
477
+ </TouchableOpacity>
478
+ )}
479
+
480
+ {order?.driver && (
481
+ <TouchableOpacity
482
+ onPress={() => onMessages({ business: false, driver: true })}
483
+ >
484
+ <MessageTypeItem
485
+ active={driver}
486
+ >
487
+ <OIcon
488
+ url={order?.driver?.photo}
489
+ width={32}
490
+ height={32}
491
+ style={{ borderRadius: 32 }}
492
+ />
493
+ </MessageTypeItem>
494
+ </TouchableOpacity>
495
+ )}
496
+ </View>
497
+ </ProfileMessageHeader>
498
+ )}
499
+ <GiftedChat
500
+ messages={formattedMessages}
501
+ user={{
502
+ _id: user.id,
503
+ name: user.name,
504
+ avatar: user.photo
505
+ }}
506
+ onSend={onSubmit}
507
+ onInputTextChanged={onChangeMessage}
508
+ alignTop
509
+ onLongPress={(context: any, message: any) => onLongPress(context, message)}
510
+ scrollToBottom
511
+ renderAvatarOnTop
512
+ renderUsernameOnMessage
513
+ renderAvatar={() => null}
514
+ renderInputToolbar={renderInputToolbar}
515
+ renderComposer={renderComposer}
516
+ renderSend={renderSend}
517
+ renderBubble={renderBubble}
518
+ renderMessageImage={renderMessageImage}
519
+ scrollToBottomComponent={() => renderScrollToBottomComponent()}
520
+ messagesContainerStyle={{
521
+ paddingTop: 18,
522
+ paddingHorizontal: 28,
523
+ paddingBottom: 55
524
+ }}
525
+ isLoadingEarlier={messages.loading}
526
+ renderLoading={() => <ActivityIndicator size="small" color="#000" />}
527
+ keyboardShouldPersistTaps='handled'
528
+ />
529
+ </Wrapper>
530
+ </View>
531
+ )
525
532
  }
526
533
 
527
534
  const styles = StyleSheet.create({
528
- containerActions: {
529
- width: 44,
530
- height: 44,
531
- alignItems: 'center',
532
- justifyContent: 'center',
533
- marginHorizontal: 4,
534
- marginBottom: 0,
535
- },
536
- containerSend: {
537
- width: 64,
538
- height: 44,
539
- alignItems: 'center',
540
- justifyContent: 'center',
541
- marginHorizontal: 4
542
- },
543
- editButton: {
544
- borderRadius: 50,
545
- backgroundColor: '#E9ECEF',
546
- marginRight: 10,
547
- height: 24,
548
- borderWidth: 1,
549
- paddingLeft: 0,
550
- paddingRight: 0
551
- },
552
- headerTitle: {
553
- flexDirection: 'row',
554
- alignItems: 'center'
555
- },
556
- headerItem: {
557
- overflow: 'hidden',
558
- width: 35,
559
- marginVertical: 18,
560
- },
561
- typeWraper: {
562
- flexDirection: 'row',
563
- height: 45,
564
- alignItems: 'center'
565
- }
535
+ containerActions: {
536
+ width: 44,
537
+ height: 44,
538
+ alignItems: 'center',
539
+ justifyContent: 'center',
540
+ marginHorizontal: 4,
541
+ marginBottom: 0,
542
+ },
543
+ containerSend: {
544
+ width: 64,
545
+ height: 44,
546
+ alignItems: 'center',
547
+ justifyContent: 'center',
548
+ marginHorizontal: 4
549
+ },
550
+ editButton: {
551
+ borderRadius: 50,
552
+ backgroundColor: '#E9ECEF',
553
+ marginRight: 10,
554
+ height: 24,
555
+ borderWidth: 1,
556
+ paddingLeft: 0,
557
+ paddingRight: 0
558
+ },
559
+ headerTitle: {
560
+ flexDirection: 'row',
561
+ alignItems: 'center'
562
+ },
563
+ headerItem: {
564
+ overflow: 'hidden',
565
+ width: 35,
566
+ marginVertical: 18,
567
+ },
568
+ typeWraper: {
569
+ flexDirection: 'row',
570
+ height: 45,
571
+ alignItems: 'center'
572
+ }
566
573
 
567
574
  })
568
575
 
569
576
  export const Messages = (props: MessagesParams) => {
570
- const [allMessages, setAllMessages] = useState(props.messages)
571
-
572
- useEffect(() => {
573
- setAllMessages(props.messages)
574
- }, [props.messages])
575
-
576
- const MessagesProps = {
577
- ...props,
578
- UIComponent: MessagesUI,
579
- messages: allMessages,
580
- setMessages: (values: any) => {
581
- props.setMessages && props.setMessages(values)
582
- setAllMessages(values)
583
- }
584
- }
585
- return <MessagesController {...MessagesProps} />
577
+ const [allMessages, setAllMessages] = useState(props.messages)
578
+
579
+ useEffect(() => {
580
+ setAllMessages(props.messages)
581
+ }, [props.messages])
582
+
583
+ const MessagesProps = {
584
+ ...props,
585
+ UIComponent: MessagesUI,
586
+ messages: allMessages,
587
+ setMessages: (values: any) => {
588
+ props.setMessages && props.setMessages(values)
589
+ setAllMessages(values)
590
+ }
591
+ }
592
+ return <MessagesController {...MessagesProps} />
586
593
  }