ordering-ui-react-native 0.12.76 → 0.12.80
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.
- package/package.json +1 -1
- package/src/components/BusinessesListing/index.tsx +35 -3
- package/src/components/BusinessesListing/styles.tsx +10 -0
- package/src/components/Checkout/index.tsx +77 -8
- package/src/components/Messages/index.tsx +3 -3
- package/src/components/PaymentOptions/index.tsx +2 -2
- package/src/theme.json +3 -1
- package/src/utils/index.tsx +27 -0
- package/themes/business/src/components/OrderDetails/Delivery.tsx +134 -131
- package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +1 -1
- package/themes/doordash/src/components/BusinessesListing/index.tsx +33 -1
- package/themes/doordash/src/components/BusinessesListing/styles.tsx +11 -1
- package/themes/doordash/src/utils/index.tsx +27 -0
- package/themes/instacart/src/components/BusinessesListing/index.tsx +35 -3
- package/themes/instacart/src/components/BusinessesListing/styles.tsx +11 -1
- package/themes/instacart/src/utils/index.tsx +27 -0
- package/themes/original/index.tsx +2 -0
- package/themes/original/src/components/ActiveOrders/index.tsx +36 -16
- package/themes/original/src/components/ActiveOrders/styles.tsx +10 -0
- package/themes/original/src/components/MessageListing/index.tsx +298 -0
- package/themes/original/src/components/MessageListing/styles.tsx +16 -0
- package/themes/original/src/components/Messages/index.tsx +123 -81
- package/themes/original/src/components/Messages/styles.tsx +8 -0
- package/themes/original/src/components/UserProfile/index.tsx +10 -0
- package/themes/original/src/utils/index.tsx +18 -0
- package/themes/single-business/src/components/BusinessesListing/index.tsx +33 -0
- package/themes/single-business/src/components/BusinessesListing/styles.tsx +9 -0
- package/themes/single-business/src/utils/index.tsx +27 -0
- package/themes/uber-eats/src/components/BusinessesListing/index.tsx +36 -3
- package/themes/uber-eats/src/components/BusinessesListing/styles.tsx +8 -0
- package/themes/uber-eats/src/utils/index.tsx +27 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import styled from 'styled-components/native'
|
|
2
|
+
|
|
3
|
+
export const MessageListingWrapper = styled.View`
|
|
4
|
+
position: relative;
|
|
5
|
+
`
|
|
6
|
+
|
|
7
|
+
export const MessageContainer = styled.View`
|
|
8
|
+
position: absolute;
|
|
9
|
+
top: 0;
|
|
10
|
+
left: 0;
|
|
11
|
+
margin: 0;
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
`
|
|
15
|
+
|
|
16
|
+
|
|
@@ -7,13 +7,12 @@ import { USER_TYPE } from '../../config/constants'
|
|
|
7
7
|
import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons'
|
|
8
8
|
import { OIcon, OIconButton, OText, OButton } from '../shared'
|
|
9
9
|
import { TouchableOpacity, ActivityIndicator, StyleSheet, View, Platform, Keyboard } from 'react-native'
|
|
10
|
-
import { Header, TitleHeader, Wrapper, QuickMessageContainer } from './styles'
|
|
10
|
+
import { Header, TitleHeader, Wrapper, QuickMessageContainer, ProfileMessageHeader } from './styles'
|
|
11
11
|
import { MessagesParams } from '../../types'
|
|
12
12
|
import { useWindowDimensions } from 'react-native'
|
|
13
13
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
14
14
|
|
|
15
15
|
const MessagesUI = (props: MessagesParams) => {
|
|
16
|
-
|
|
17
16
|
const {
|
|
18
17
|
type,
|
|
19
18
|
order,
|
|
@@ -27,6 +26,7 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
27
26
|
setImage,
|
|
28
27
|
readMessages,
|
|
29
28
|
onClose,
|
|
29
|
+
isMeesageListing
|
|
30
30
|
} = props
|
|
31
31
|
|
|
32
32
|
const [{ user }] = useSession()
|
|
@@ -37,22 +37,22 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
37
37
|
const [formattedMessages, setFormattedMessages] = useState<Array<any>>([])
|
|
38
38
|
const [isKeyboardShow, setIsKeyboardShow] = useState(false)
|
|
39
39
|
const previousStatus = [1, 2, 5, 6, 10, 11, 12, 16, 17]
|
|
40
|
-
|
|
40
|
+
const chatDisabled = previousStatus.includes(order?.status)
|
|
41
41
|
const { height } = useWindowDimensions();
|
|
42
42
|
const { top, bottom } = useSafeAreaInsets();
|
|
43
43
|
|
|
44
44
|
const theme = useTheme();
|
|
45
45
|
|
|
46
46
|
const quickMessageList = [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
{ key: 'customer_message_1', text: t('CUSTOMER_MESSAGE_1', 'Lorem ipsum 1') },
|
|
48
|
+
{ key: 'customer_message_2', text: t('CUSTOMER_MESSAGE_2', 'Lorem ipsum 2') },
|
|
49
|
+
{ key: 'customer_message_3', text: t('CUSTOMER_MESSAGE_3', 'Lorem ipsum 3') },
|
|
50
|
+
{ key: 'customer_message_4', text: t('CUSTOMER_MESSAGE_4', 'Lorem ipsum 4') }
|
|
51
|
+
]
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
const handleClickQuickMessage = (text: string) => {
|
|
54
|
+
setMessage && setMessage(`${message}${text}`)
|
|
55
|
+
}
|
|
56
56
|
|
|
57
57
|
const onChangeMessage = (val: string) => {
|
|
58
58
|
setMessage && setMessage(val)
|
|
@@ -239,37 +239,37 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
const renderAccessory = () => {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
242
|
+
return (
|
|
243
|
+
<QuickMessageContainer
|
|
244
|
+
style={{
|
|
245
|
+
marginLeft: 10,
|
|
246
|
+
marginBottom: 10
|
|
247
|
+
}}
|
|
248
|
+
contentContainerStyle={{
|
|
249
|
+
alignItems: 'center',
|
|
250
|
+
}}
|
|
251
|
+
horizontal
|
|
252
|
+
showsHorizontalScrollIndicator={false}
|
|
253
|
+
>
|
|
254
|
+
{quickMessageList.map((quickMessage, i) => (
|
|
255
|
+
<OButton
|
|
256
|
+
key={i}
|
|
257
|
+
text={quickMessage.text}
|
|
258
|
+
bgColor='#E9ECEF'
|
|
259
|
+
borderColor='#E9ECEF'
|
|
260
|
+
imgRightSrc={null}
|
|
261
|
+
textStyle={{
|
|
262
|
+
fontSize: 11,
|
|
263
|
+
lineHeight: 16,
|
|
264
|
+
color: '#414954'
|
|
265
|
+
}}
|
|
266
|
+
style={{ ...styles.editButton }}
|
|
267
|
+
onClick={() => handleClickQuickMessage(quickMessage.text)}
|
|
268
|
+
/>
|
|
269
|
+
))}
|
|
270
|
+
</QuickMessageContainer>
|
|
271
|
+
)
|
|
272
|
+
}
|
|
273
273
|
|
|
274
274
|
const renderInputToolbar = (props: typeof InputToolbarProps) => (
|
|
275
275
|
<InputToolbar
|
|
@@ -285,20 +285,20 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
285
285
|
|
|
286
286
|
const renderComposer = (props: typeof ComposerProps) => (
|
|
287
287
|
chatDisabled ? (
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
288
|
+
<View
|
|
289
|
+
style={{
|
|
290
|
+
width: '100%',
|
|
291
|
+
flexDirection: 'column',
|
|
292
|
+
alignItems: 'center'
|
|
293
|
+
}}
|
|
294
|
+
>
|
|
295
|
+
<MaterialCommunityIcon
|
|
296
|
+
name='close-octagon-outline'
|
|
297
|
+
size={24}
|
|
298
|
+
/>
|
|
299
|
+
<OText size={14}>{t('NOT_SEND_MESSAGES', 'You can\'t send messages because the order has ended')}</OText>
|
|
300
|
+
</View>
|
|
301
|
+
) : (
|
|
302
302
|
<View style={{
|
|
303
303
|
flexDirection: 'row', width: '80%', alignItems: 'center', backgroundColor: theme.colors.backgroundGray100,
|
|
304
304
|
borderRadius: 7.6,
|
|
@@ -387,7 +387,7 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
387
387
|
|
|
388
388
|
const getViewHeight = () => {
|
|
389
389
|
if (Platform.OS === 'android') {
|
|
390
|
-
return height - top - bottom - (isKeyboardShow ?
|
|
390
|
+
return height - top - bottom - (isKeyboardShow ? 300 : 24);
|
|
391
391
|
} else {
|
|
392
392
|
return height - top - bottom - 10;
|
|
393
393
|
}
|
|
@@ -396,21 +396,53 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
396
396
|
return (
|
|
397
397
|
<View style={{ height: getViewHeight(), width: '100%', paddingTop: 12, backgroundColor: 'white' }}>
|
|
398
398
|
<Wrapper>
|
|
399
|
-
|
|
400
|
-
<
|
|
401
|
-
|
|
402
|
-
<
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
<
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
399
|
+
{!isMeesageListing ? (
|
|
400
|
+
<Header>
|
|
401
|
+
<OIconButton icon={theme.images.general.arrow_left} style={{ paddingStart: 10, borderColor: theme.colors.clear }} onClick={onClose} />
|
|
402
|
+
<View style={{ marginRight: 10, shadowColor: theme.colors.black, shadowOpacity: 0.1, shadowOffset: { width: 0, height: 1 }, shadowRadius: 2 }}>
|
|
403
|
+
<OIcon
|
|
404
|
+
url={type === USER_TYPE.DRIVER ? order?.driver?.photo : order?.business?.logo}
|
|
405
|
+
width={32}
|
|
406
|
+
height={32}
|
|
407
|
+
style={{ borderRadius: 7.6 }}
|
|
408
|
+
/>
|
|
409
|
+
</View>
|
|
410
|
+
<TitleHeader>
|
|
411
|
+
<OText size={14} lineHeight={21} weight={'600'}>{type === USER_TYPE.DRIVER ? order?.driver?.name : order?.business?.name}</OText>
|
|
412
|
+
<OText size={12} color={theme.colors.textSecondary}>{type === USER_TYPE.DRIVER ? t('DRIVER', 'Driver') : t('BUSINESS', 'Business')}</OText>
|
|
413
|
+
</TitleHeader>
|
|
414
|
+
</Header>
|
|
415
|
+
) : (
|
|
416
|
+
<ProfileMessageHeader>
|
|
417
|
+
<View style={{ ...styles.headerTitle }}>
|
|
418
|
+
<TouchableOpacity
|
|
419
|
+
style={styles.headerItem}
|
|
420
|
+
onPress={onClose}>
|
|
421
|
+
<OIcon src={theme.images.general.arrow_left} width={16} />
|
|
422
|
+
</TouchableOpacity>
|
|
423
|
+
<OText size={18}>{t('ORDER', theme?.defaultLanguages?.ORDER || 'Order')} #{order?.id}</OText>
|
|
424
|
+
</View>
|
|
425
|
+
<View>
|
|
426
|
+
{order.business && (
|
|
427
|
+
<OIcon
|
|
428
|
+
url={order?.business?.logo}
|
|
429
|
+
width={32}
|
|
430
|
+
height={32}
|
|
431
|
+
style={{ borderRadius: 7.6 }}
|
|
432
|
+
/>
|
|
433
|
+
)}
|
|
434
|
+
|
|
435
|
+
{order?.driver && (
|
|
436
|
+
<OIcon
|
|
437
|
+
url={order?.driver?.photo}
|
|
438
|
+
width={32}
|
|
439
|
+
height={32}
|
|
440
|
+
style={{ borderRadius: 7.6 }}
|
|
441
|
+
/>
|
|
442
|
+
)}
|
|
443
|
+
</View>
|
|
444
|
+
</ProfileMessageHeader>
|
|
445
|
+
)}
|
|
414
446
|
<GiftedChat
|
|
415
447
|
messages={formattedMessages}
|
|
416
448
|
user={{
|
|
@@ -460,15 +492,25 @@ const styles = StyleSheet.create({
|
|
|
460
492
|
justifyContent: 'center',
|
|
461
493
|
marginHorizontal: 4
|
|
462
494
|
},
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
495
|
+
editButton: {
|
|
496
|
+
borderRadius: 50,
|
|
497
|
+
backgroundColor: '#E9ECEF',
|
|
498
|
+
marginRight: 10,
|
|
499
|
+
height: 24,
|
|
500
|
+
borderWidth: 1,
|
|
501
|
+
paddingLeft: 0,
|
|
502
|
+
paddingRight: 0
|
|
503
|
+
},
|
|
504
|
+
headerTitle: {
|
|
505
|
+
flexDirection: 'row',
|
|
506
|
+
alignItems: 'center'
|
|
507
|
+
},
|
|
508
|
+
headerItem: {
|
|
509
|
+
overflow: 'hidden',
|
|
510
|
+
width: 35,
|
|
511
|
+
marginVertical: 18,
|
|
512
|
+
}
|
|
513
|
+
|
|
472
514
|
})
|
|
473
515
|
|
|
474
516
|
export const Messages = (props: MessagesParams) => {
|
|
@@ -17,3 +17,11 @@ export const Header = styled.View`
|
|
|
17
17
|
export const TitleHeader = styled.View``
|
|
18
18
|
|
|
19
19
|
export const QuickMessageContainer = styled.ScrollView``
|
|
20
|
+
|
|
21
|
+
export const ProfileMessageHeader = styled.View`
|
|
22
|
+
flex-direction: row;
|
|
23
|
+
justify-content: space-between;
|
|
24
|
+
align-items: center;
|
|
25
|
+
padding-bottom: 0px;
|
|
26
|
+
padding-horizontal: 20px;
|
|
27
|
+
`
|
|
@@ -13,6 +13,7 @@ import { Platform, StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
|
13
13
|
import { ProfileParams } from '../../types';
|
|
14
14
|
import { LogoutButton } from '../LogoutButton'
|
|
15
15
|
import { LanguageSelector } from '../LanguageSelector'
|
|
16
|
+
import MessageCircle from 'react-native-vector-icons/AntDesign'
|
|
16
17
|
|
|
17
18
|
import {
|
|
18
19
|
OIcon,
|
|
@@ -78,6 +79,11 @@ const ProfileListUI = (props: ProfileParams) => {
|
|
|
78
79
|
pagePadding: {
|
|
79
80
|
paddingLeft: 40,
|
|
80
81
|
paddingRight: 40
|
|
82
|
+
},
|
|
83
|
+
messageIconStyle: {
|
|
84
|
+
fontSize: 18,
|
|
85
|
+
fontWeight: 'bold',
|
|
86
|
+
marginEnd: 14
|
|
81
87
|
}
|
|
82
88
|
});
|
|
83
89
|
|
|
@@ -150,6 +156,10 @@ const ProfileListUI = (props: ProfileParams) => {
|
|
|
150
156
|
<OIcon src={theme.images.general.pin} width={16} color={theme.colors.textNormal} style={{ marginEnd: 14 }} />
|
|
151
157
|
<OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('MY_SAVED_PLACES', 'My saved places')}</OText>
|
|
152
158
|
</ListItem>
|
|
159
|
+
<ListItem onPress={() => onRedirect('Messages', { isFromProfile: true, isGoBack: true })} activeOpacity={0.7}>
|
|
160
|
+
<MessageCircle name='message1' style={styles.messageIconStyle} color={theme.colors.textNormal} />
|
|
161
|
+
<OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('MESSAGES', 'Messages')}</OText>
|
|
162
|
+
</ListItem>
|
|
153
163
|
<ListItem onPress={() => navigation.navigate('Help', {})} activeOpacity={0.7}>
|
|
154
164
|
<OIcon src={theme.images.general.ic_help} width={16} color={theme.colors.textNormal} style={{ marginEnd: 14 }} />
|
|
155
165
|
<OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('HELP', 'Help')}</OText>
|
|
@@ -177,4 +177,22 @@ export const getTypesText = (value: number) => {
|
|
|
177
177
|
*/
|
|
178
178
|
export const convertToRadian = (value: number) => {
|
|
179
179
|
return value * Math.PI / 180
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Function to distance between two locations
|
|
184
|
+
* @param lat1 Lat for first location
|
|
185
|
+
* @param lon1 Lon for first location
|
|
186
|
+
* @param lat2 Lat for second location
|
|
187
|
+
* @param lon2 Lon for second location
|
|
188
|
+
*/
|
|
189
|
+
export const getDistance = (lat1: any, lon1: any, lat2: any, lon2: any) => {
|
|
190
|
+
const R = 6371 // km
|
|
191
|
+
const dLat = convertToRadian(lat2 - lat1)
|
|
192
|
+
const dLon = convertToRadian(lon2 - lon1)
|
|
193
|
+
const curLat1 = convertToRadian(lat1)
|
|
194
|
+
const curLat2 = convertToRadian(lat2)
|
|
195
|
+
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(curLat1) * Math.cos(curLat2)
|
|
196
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
|
|
197
|
+
return R * c
|
|
180
198
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
|
|
3
|
+
import Geolocation from '@react-native-community/geolocation'
|
|
3
4
|
import {
|
|
4
5
|
View,
|
|
5
6
|
StyleSheet,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
TopHeader,
|
|
29
30
|
DropOptionButton,
|
|
30
31
|
WrapSearchBar,
|
|
32
|
+
FarAwayMessage
|
|
31
33
|
} from './styles';
|
|
32
34
|
|
|
33
35
|
import { SearchBar } from '../SearchBar';
|
|
@@ -41,6 +43,8 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
41
43
|
import { BusinessFeaturedController } from '../BusinessFeaturedController';
|
|
42
44
|
import { getTypesText } from '../../utils';
|
|
43
45
|
import NavBar from '../NavBar';
|
|
46
|
+
import { getDistance } from '../../utils'
|
|
47
|
+
import Ionicons from 'react-native-vector-icons/Ionicons'
|
|
44
48
|
|
|
45
49
|
const PIXELS_TO_SCROLL = 1000;
|
|
46
50
|
|
|
@@ -97,6 +101,15 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
97
101
|
height: 260,
|
|
98
102
|
paddingHorizontal: 40
|
|
99
103
|
},
|
|
104
|
+
iconStyle: {
|
|
105
|
+
fontSize: 18,
|
|
106
|
+
color: theme.colors.warning5,
|
|
107
|
+
marginRight: 8
|
|
108
|
+
},
|
|
109
|
+
farAwayMsg: {
|
|
110
|
+
paddingVertical: 6,
|
|
111
|
+
paddingHorizontal: 20
|
|
112
|
+
}
|
|
100
113
|
});
|
|
101
114
|
|
|
102
115
|
|
|
@@ -109,6 +122,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
109
122
|
const { top } = useSafeAreaInsets();
|
|
110
123
|
|
|
111
124
|
const [featuredBusiness, setFeaturedBusinesses] = useState(Array);
|
|
125
|
+
const [isFarAway, setIsFarAway] = useState(false)
|
|
112
126
|
|
|
113
127
|
const configTypes = configs?.order_types_allowed?.value.split('|').map((value: any) => Number(value)) || [];
|
|
114
128
|
|
|
@@ -135,6 +149,19 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
135
149
|
}
|
|
136
150
|
}, [businessesList.businesses]);
|
|
137
151
|
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
Geolocation.getCurrentPosition((pos) => {
|
|
154
|
+
const crd = pos.coords
|
|
155
|
+
const distance = getDistance(crd.latitude, crd.longitude, orderState?.options?.address?.location?.lat, orderState?.options?.address?.location?.lng)
|
|
156
|
+
if (distance > 20) setIsFarAway(true)
|
|
157
|
+
else setIsFarAway(false)
|
|
158
|
+
}, (err) => {
|
|
159
|
+
console.log(`ERROR(${err.code}): ${err.message}`)
|
|
160
|
+
}, {
|
|
161
|
+
enableHighAccuracy: true, timeout: 15000, maximumAge: 10000
|
|
162
|
+
})
|
|
163
|
+
}, [orderState?.options?.address?.location])
|
|
164
|
+
|
|
138
165
|
return (
|
|
139
166
|
<ScrollView
|
|
140
167
|
style={styles.container}
|
|
@@ -171,6 +198,12 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
171
198
|
{orderState?.options?.address?.address}
|
|
172
199
|
</OText>
|
|
173
200
|
</AddressInput>
|
|
201
|
+
{isFarAway && (
|
|
202
|
+
<FarAwayMessage style={styles.farAwayMsg}>
|
|
203
|
+
<Ionicons name='md-warning-outline' style={styles.iconStyle} />
|
|
204
|
+
<OText size={12} numberOfLines={1} ellipsizeMode={'tail'} color={theme.colors.textNormal}>{t('YOU_ARE_FAR_FROM_ADDRESS', 'Your are far from this address')}</OText>
|
|
205
|
+
</FarAwayMessage>
|
|
206
|
+
)}
|
|
174
207
|
<OrderControlContainer>
|
|
175
208
|
<View style={styles.wrapperOrderOptions}>
|
|
176
209
|
<DropOptionButton
|
|
@@ -95,3 +95,12 @@ export const WrapSearchBar = styled.View`
|
|
|
95
95
|
background-color: ${(props: any) => props.theme.colors.white};
|
|
96
96
|
flex: 1;
|
|
97
97
|
`
|
|
98
|
+
|
|
99
|
+
export const FarAwayMessage = styled.View`
|
|
100
|
+
flex-direction: row;
|
|
101
|
+
align-items: center;
|
|
102
|
+
background-color: ${(props: any) => props.theme.colors.warning1};
|
|
103
|
+
border-radius: 7.6px;
|
|
104
|
+
border: 1px solid ${(props: any) => props.theme.colors.warning5};
|
|
105
|
+
width: 100%;
|
|
106
|
+
`
|
|
@@ -251,3 +251,30 @@ export const getTextOrderStatus = (s: string, t: any) => {
|
|
|
251
251
|
const objectStatus = orderStatus.find((o) => o.key === status)
|
|
252
252
|
return objectStatus && objectStatus
|
|
253
253
|
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Function to transform degree to radian
|
|
257
|
+
* @param {number} value for transform
|
|
258
|
+
*
|
|
259
|
+
*/
|
|
260
|
+
export const convertToRadian = (value: number) => {
|
|
261
|
+
return value * Math.PI / 180
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Function to distance between two locations
|
|
266
|
+
* @param lat1 Lat for first location
|
|
267
|
+
* @param lon1 Lon for first location
|
|
268
|
+
* @param lat2 Lat for second location
|
|
269
|
+
* @param lon2 Lon for second location
|
|
270
|
+
*/
|
|
271
|
+
export const getDistance = (lat1: any, lon1: any, lat2: any, lon2: any) => {
|
|
272
|
+
const R = 6371 // km
|
|
273
|
+
const dLat = convertToRadian(lat2 - lat1)
|
|
274
|
+
const dLon = convertToRadian(lon2 - lon1)
|
|
275
|
+
const curLat1 = convertToRadian(lat1)
|
|
276
|
+
const curLat2 = convertToRadian(lat2)
|
|
277
|
+
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(curLat1) * Math.cos(curLat2)
|
|
278
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
|
|
279
|
+
return R * c
|
|
280
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
1
|
+
import React, { useState, useEffect } from 'react'
|
|
2
2
|
import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'
|
|
3
3
|
import { View, StyleSheet, ScrollView, Platform, PanResponder, I18nManager } from 'react-native'
|
|
4
4
|
import MaterialIcon from 'react-native-vector-icons/MaterialIcons'
|
|
5
|
+
import Geolocation from '@react-native-community/geolocation'
|
|
6
|
+
import Ionicons from 'react-native-vector-icons/Ionicons'
|
|
7
|
+
|
|
5
8
|
import {
|
|
6
9
|
BusinessList as BusinessesListingController,
|
|
7
10
|
useLanguage,
|
|
@@ -13,7 +16,7 @@ import {
|
|
|
13
16
|
useToast
|
|
14
17
|
} from 'ordering-components/native'
|
|
15
18
|
|
|
16
|
-
import { BusinessListContainer, Divider, Search, OrderControlContainer, AddressInput, WrapMomentOption } from './styles'
|
|
19
|
+
import { BusinessListContainer, Divider, Search, OrderControlContainer, AddressInput, WrapMomentOption, FarAwayMessage } from './styles'
|
|
17
20
|
|
|
18
21
|
import NavBar from '../NavBar'
|
|
19
22
|
import { SearchBar } from '../SearchBar'
|
|
@@ -27,6 +30,7 @@ import { OrderTypeSelector } from '../OrderTypeSelector'
|
|
|
27
30
|
import { MomentOption } from '../MomentOption'
|
|
28
31
|
import { HighestRatedBusinesses } from '../HighestRatedBusinesses'
|
|
29
32
|
import { useTheme } from 'styled-components/native'
|
|
33
|
+
import { getDistance } from '../../utils'
|
|
30
34
|
|
|
31
35
|
const PIXELS_TO_SCROLL = 1200
|
|
32
36
|
|
|
@@ -61,7 +65,16 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
61
65
|
borderColor: theme.colors.backgroundGray,
|
|
62
66
|
borderWidth: 1,
|
|
63
67
|
borderRadius: 10,
|
|
64
|
-
}
|
|
68
|
+
},
|
|
69
|
+
iconStyle: {
|
|
70
|
+
fontSize: 18,
|
|
71
|
+
color: theme.colors.warning5,
|
|
72
|
+
marginRight: 8
|
|
73
|
+
},
|
|
74
|
+
farAwayMsg: {
|
|
75
|
+
paddingVertical: 6,
|
|
76
|
+
paddingHorizontal: 20
|
|
77
|
+
}
|
|
65
78
|
})
|
|
66
79
|
|
|
67
80
|
const [, t] = useLanguage()
|
|
@@ -73,6 +86,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
73
86
|
|
|
74
87
|
const [openMomentOption, setOpenMomentOption] = useState(false)
|
|
75
88
|
const configTypes = configs?.order_types_allowed?.value.split('|').map((value: any) => Number(value)) || []
|
|
89
|
+
const [isFarAway, setIsFarAway] = useState(false)
|
|
76
90
|
|
|
77
91
|
const handleScroll = ({ nativeEvent }: any) => {
|
|
78
92
|
const y = nativeEvent.contentOffset.y
|
|
@@ -85,6 +99,19 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
85
99
|
}
|
|
86
100
|
}
|
|
87
101
|
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
Geolocation.getCurrentPosition((pos) => {
|
|
104
|
+
const crd = pos.coords
|
|
105
|
+
const distance = getDistance(crd.latitude, crd.longitude, orderState?.options?.address?.location?.lat, orderState?.options?.address?.location?.lng)
|
|
106
|
+
if (distance > 20) setIsFarAway(true)
|
|
107
|
+
else setIsFarAway(false)
|
|
108
|
+
}, (err) => {
|
|
109
|
+
console.log(`ERROR(${err.code}): ${err.message}`)
|
|
110
|
+
}, {
|
|
111
|
+
enableHighAccuracy: true, timeout: 15000, maximumAge: 10000
|
|
112
|
+
})
|
|
113
|
+
}, [orderState?.options?.address?.location])
|
|
114
|
+
|
|
88
115
|
return (
|
|
89
116
|
<BusinessListContainer>
|
|
90
117
|
{!auth && (
|
|
@@ -114,6 +141,12 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
114
141
|
style={{ marginRight: 10 }}
|
|
115
142
|
/>
|
|
116
143
|
</AddressInput>
|
|
144
|
+
{isFarAway && (
|
|
145
|
+
<FarAwayMessage style={styles.farAwayMsg}>
|
|
146
|
+
<Ionicons name='md-warning-outline' style={styles.iconStyle} />
|
|
147
|
+
<OText size={12} numberOfLines={1} ellipsizeMode={'tail'} color={theme.colors.textNormal}>{t('YOU_ARE_FAR_FROM_ADDRESS', 'Your are far from this address')}</OText>
|
|
148
|
+
</FarAwayMessage>
|
|
149
|
+
)}
|
|
117
150
|
<View style={styles.wrapperOrderOptions}>
|
|
118
151
|
<OrderTypeSelector configTypes={configTypes} />
|
|
119
152
|
<WrapMomentOption
|
|
@@ -52,3 +52,11 @@ export const WrapMomentOption = styled.TouchableOpacity`
|
|
|
52
52
|
margin-horizontal: 10px;
|
|
53
53
|
max-width: 240px;
|
|
54
54
|
`
|
|
55
|
+
|
|
56
|
+
export const FarAwayMessage = styled.View`
|
|
57
|
+
flex-direction: row;
|
|
58
|
+
align-items: center;
|
|
59
|
+
background-color: ${(props: any) => props.theme.colors.warning1};
|
|
60
|
+
border-radius: 7.6px;
|
|
61
|
+
border: 1px solid ${(props: any) => props.theme.colors.warning5};
|
|
62
|
+
`
|
|
@@ -162,3 +162,30 @@ export const transformCountryCode = (countryCode : number) => {
|
|
|
162
162
|
return parser(value)
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Function to transform degree to radian
|
|
168
|
+
* @param {number} value for transform
|
|
169
|
+
*
|
|
170
|
+
*/
|
|
171
|
+
export const convertToRadian = (value: number) => {
|
|
172
|
+
return value * Math.PI / 180
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Function to distance between two locations
|
|
177
|
+
* @param lat1 Lat for first location
|
|
178
|
+
* @param lon1 Lon for first location
|
|
179
|
+
* @param lat2 Lat for second location
|
|
180
|
+
* @param lon2 Lon for second location
|
|
181
|
+
*/
|
|
182
|
+
export const getDistance = (lat1: any, lon1: any, lat2: any, lon2: any) => {
|
|
183
|
+
const R = 6371 // km
|
|
184
|
+
const dLat = convertToRadian(lat2 - lat1)
|
|
185
|
+
const dLon = convertToRadian(lon2 - lon1)
|
|
186
|
+
const curLat1 = convertToRadian(lat1)
|
|
187
|
+
const curLat2 = convertToRadian(lat2)
|
|
188
|
+
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(curLat1) * Math.cos(curLat2)
|
|
189
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
|
|
190
|
+
return R * c
|
|
191
|
+
}
|