ordering-ui-react-native 0.17.37 → 0.17.39

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.17.37",
3
+ "version": "0.17.39",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -120,7 +120,8 @@
120
120
  "styled-components": "^5.1.1",
121
121
  "styled-system": "^5.1.5",
122
122
  "toggle-react-native": "^1.1.2",
123
- "toggle-switch-react-native": "^3.2.0"
123
+ "toggle-switch-react-native": "^3.2.0",
124
+ "lottie-react-native": "4.1.3"
124
125
  },
125
126
  "devDependencies": {
126
127
  "@babel/core": "^7.11.6",
@@ -11,15 +11,14 @@ import {
11
11
  ToastType
12
12
  } from 'ordering-components/native';
13
13
  import { OIcon, OText } from '../shared';
14
- import { StyleSheet, TouchableOpacity, View, Animated } from 'react-native';
14
+ import { StyleSheet, View } from 'react-native';
15
15
  import { InView } from 'react-native-intersection-observer'
16
16
  import { BusinessControllerParams } from '../../types';
17
17
  import { convertHoursToMinutes, shape } from '../../utils';
18
+
18
19
  import {
19
- Card,
20
20
  BusinessHero,
21
21
  BusinessContent,
22
- BusinessCategory,
23
22
  BusinessInfo,
24
23
  Metadata,
25
24
  BusinessState,
@@ -30,8 +29,9 @@ import {
30
29
  } from './styles';
31
30
  import { useTheme } from 'styled-components/native';
32
31
  import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome5';
33
- import IconAntDesign from 'react-native-vector-icons/AntDesign'
34
32
  import FastImage from 'react-native-fast-image'
33
+ import { LottieAnimation } from '../LottieAnimation';
34
+ import { CardAnimation } from '../shared/CardAnimation';
35
35
 
36
36
  export const BusinessControllerUI = (props: BusinessControllerParams) => {
37
37
  const {
@@ -54,13 +54,19 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
54
54
  const [{ parsePrice, parseDistance, parseNumber, optimizeImage }] = useUtils();
55
55
  const [, { showToast }] = useToast()
56
56
  const [orderState] = useOrder();
57
- const [ { auth }] = useSession()
57
+ const [{ auth }] = useSession()
58
58
  const [configState] = useConfig();
59
59
  const [, t] = useLanguage();
60
60
  const theme = useTheme()
61
61
  const [isIntersectionObserver, setIsIntersectionObserver] = useState(!enableIntersection)
62
62
 
63
63
  const styles = StyleSheet.create({
64
+ container: {
65
+ marginVertical: 20,
66
+ borderRadius: 7.6,
67
+ width: '100%',
68
+ position: 'relative'
69
+ },
64
70
  headerStyle: {
65
71
  borderTopLeftRadius: 7.6,
66
72
  borderTopRightRadius: 7.6,
@@ -110,7 +116,7 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
110
116
  flexDirection: 'row',
111
117
  alignItems: 'center',
112
118
  justifyContent: 'flex-start',
113
- },
119
+ }
114
120
  });
115
121
 
116
122
  const types = ['food', 'laundry', 'alcohol', 'groceries'];
@@ -152,7 +158,13 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
152
158
  return (
153
159
  <InView style={{ minHeight: 200 }} triggerOnce={true} onChange={(inView: boolean) => handleChangeInterSection(inView)}>
154
160
  {isIntersectionObserver ? (
155
- <Card activeOpacity={1} onPress={() => handleBusinessClick(business)} style={style}>
161
+ <CardAnimation
162
+ onClick={() => handleBusinessClick(business)}
163
+ style={[
164
+ style,
165
+ styles.container
166
+ ]}
167
+ >
156
168
  {business?.ribbon?.enabled && (
157
169
  <RibbonBox
158
170
  bgColor={business?.ribbon?.color}
@@ -219,15 +231,15 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
219
231
  </OText>
220
232
  </Reviews>
221
233
  )}
222
- <TouchableOpacity
223
- onPress={handleChangeFavorite}
224
- >
225
- <IconAntDesign
226
- name={business?.favorite ? 'heart' : 'hearto'}
227
- color={theme.colors.danger5}
228
- size={18}
229
- />
230
- </TouchableOpacity>
234
+ <LottieAnimation
235
+ type='favorite'
236
+ onClick={handleChangeFavorite}
237
+ initialValue={business?.favorite ? 1 : 0}
238
+ toValue={business?.favorite ? 0 : 1}
239
+ disableAnimation={!auth}
240
+ iconProps={{ color: theme.colors.danger5, size: 18 }}
241
+ isActive={business?.favorite}
242
+ />
231
243
  </ReviewAndFavorite>
232
244
  </BusinessInfo>
233
245
  <OText
@@ -266,7 +278,7 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
266
278
  )}
267
279
  </Metadata>
268
280
  </BusinessContent>
269
- </Card>
281
+ </CardAnimation>
270
282
  ) : (
271
283
  <Placeholder
272
284
  Animation={Fade}
@@ -1,12 +1,5 @@
1
1
  import styled, { css } from 'styled-components/native';
2
2
 
3
- export const Card = styled.TouchableOpacity`
4
- margin-vertical: 20px;
5
- border-radius: 7.6px;
6
- width: 100%;
7
- position: relative;
8
- `
9
-
10
3
  export const BusinessHero = styled.View`
11
4
  position: relative;
12
5
  border-top-right-radius: 7.6px;
@@ -0,0 +1,69 @@
1
+ import React, { useRef } from 'react'
2
+ import Lottie from 'lottie-react-native';
3
+ import { TouchableOpacity, Easing, ViewStyle, Animated } from 'react-native';
4
+ import IconAntDesign from 'react-native-vector-icons/AntDesign'
5
+ import { useTheme } from 'styled-components';
6
+
7
+ interface Props {
8
+ initialValue: number,
9
+ onClick: any,
10
+ disableAnimation?: boolean
11
+ toValue: number,
12
+ style?: ViewStyle,
13
+ duration?: number,
14
+ type: 'favorite', // animation types
15
+ isActive: boolean,
16
+ animationType?: ((value : number) => number);
17
+ useNativeDriver?: boolean,
18
+ iconProps?: {color?: string, size?: number, style?: ViewStyle}
19
+ }
20
+
21
+ export const LottieAnimation = (props: Props) => {
22
+ const {
23
+ initialValue,
24
+ onClick,
25
+ disableAnimation,
26
+ toValue,
27
+ style,
28
+ duration,
29
+ type,
30
+ isActive,
31
+ useNativeDriver,
32
+ animationType,
33
+ iconProps
34
+ } = props
35
+ const theme = useTheme()
36
+ const animationProgress = useRef(new Animated.Value(initialValue))
37
+ const favoriteArray = ['heart', 'hearto']
38
+ const icon = type === 'favorite' ? favoriteArray : []
39
+ const animationGif = type === 'favorite' ? theme.images?.general?.heart : ''
40
+ const onPressLottie = () => {
41
+ if (!disableAnimation) {
42
+ Animated.timing(animationProgress.current, {
43
+ toValue,
44
+ duration: duration || 5000,
45
+ easing: animationType || Easing.linear,
46
+ useNativeDriver: useNativeDriver ?? true
47
+ }).start();
48
+ }
49
+ onClick()
50
+ }
51
+
52
+ return (
53
+ <TouchableOpacity
54
+ onPress={onPressLottie}
55
+ style={style}
56
+ >
57
+ <Lottie
58
+ progress={animationProgress.current}
59
+ source={animationGif}
60
+ />
61
+ <IconAntDesign
62
+ name={isActive ? icon[0] : icon[1]}
63
+ color={iconProps?.color || theme.colors.danger5}
64
+ size={iconProps?.size || 16}
65
+ style={iconProps?.style}
66
+ />
67
+ </TouchableOpacity>
68
+ )
69
+ }
@@ -5,6 +5,7 @@ import { useTheme } from 'styled-components/native';
5
5
  import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons'
6
6
  import RNPickerSelect from 'react-native-picker-select'
7
7
  import { ServiceForm } from '../ServiceForm';
8
+ import FastImage from 'react-native-fast-image'
8
9
 
9
10
  import {
10
11
  Accordion,
@@ -157,12 +158,40 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
157
158
  {(product?.images || theme?.images?.dummies?.product) && (
158
159
  <ProductImage>
159
160
  {isFromCheckout ? (
160
- <OIcon url={optimizeImage(product?.images || theme?.images?.dummies?.product, 'h_100,c_limit')} style={{ ...styles.productImage, ...{ width: 82, height: 82 } }} />
161
+ product?.images ? (
162
+ <FastImage
163
+ style={{ ...styles.productImage, ...{ width: 82, height: 82 } }}
164
+ source={{
165
+ uri: optimizeImage(product?.images, 'h_100,c_limit'),
166
+ priority: FastImage.priority.normal,
167
+ }}
168
+ resizeMode={FastImage.resizeMode.cover}
169
+ />
170
+ ) : (
171
+ <OIcon
172
+ src={theme?.images?.dummies?.product}
173
+ style={{ ...styles.productImage, ...{ width: 82, height: 82 } }}
174
+ />
175
+ )
161
176
  ) : (
162
- <OIcon url={optimizeImage(product?.images || theme?.images?.dummies?.product, 'h_100,c_limit')} style={styles.productImage} />
177
+ product?.images ? (
178
+ <FastImage
179
+ style={styles.productImage}
180
+ source={{
181
+ uri: optimizeImage(product?.images, 'h_100,c_limit'),
182
+ priority: FastImage.priority.normal,
183
+ }}
184
+ resizeMode={FastImage.resizeMode.cover}
185
+ />
186
+ ) : (
187
+ <OIcon
188
+ src={theme?.images?.dummies?.product}
189
+ style={styles.productImage}
190
+ />
191
+ )
163
192
  )}
164
193
  </ProductImage>
165
- )}
194
+ )}
166
195
  {!!product?.calendar_event ? (
167
196
  <View style={{ flex: 1, marginLeft: 10, flexDirection: 'column' }}>
168
197
  <View>
@@ -8,12 +8,10 @@ import {
8
8
  import { StyleSheet, TouchableOpacity, View } from 'react-native';
9
9
  import { useTheme } from 'styled-components/native';
10
10
  import { OIcon, OText, OButton } from '../shared';
11
- import IconAntDesign from 'react-native-vector-icons/AntDesign'
12
11
  import { SingleOrderCardParams } from '../../types';
13
12
  import { OAlert } from '../../../../../src/components/shared'
14
13
 
15
14
  import {
16
- Container,
17
15
  InnerContainer,
18
16
  Logo,
19
17
  CardInfoWrapper,
@@ -23,6 +21,8 @@ import {
23
21
  UnreadMessageCounter,
24
22
  Price
25
23
  } from './styles';
24
+ import { LottieAnimation } from '../LottieAnimation';
25
+ import { CardAnimation } from '../shared/CardAnimation';
26
26
 
27
27
  const SingleOrderCardUI = (props: SingleOrderCardParams) => {
28
28
  const {
@@ -46,10 +46,16 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
46
46
 
47
47
  const [reorderSelected, setReorderSelected] = useState<number | null>(null);
48
48
  const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
49
+ const [isPressed, setIsPressed] = useState(false)
49
50
 
50
51
  const allowedOrderStatus = [1, 2, 5, 6, 10, 11, 12];
51
52
 
52
53
  const styles = StyleSheet.create({
54
+ container: {
55
+ borderRadius: 7.6,
56
+ marginBottom: 10,
57
+ paddingVertical: 5,
58
+ },
53
59
  logo: {
54
60
  borderRadius: 8,
55
61
  width: 64,
@@ -100,6 +106,14 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
100
106
  infoText: {
101
107
  flexDirection: 'row',
102
108
  alignItems: 'center'
109
+ },
110
+ cardAnimation: {
111
+ elevation: isPressed ? 2 : 0,
112
+ shadowColor: '#888',
113
+ shadowOffset: { width: 0, height: isPressed ? 2 : 0 },
114
+ shadowRadius: 18,
115
+ shadowOpacity: isPressed ? 0.8 : 0,
116
+ borderRadius: 12,
103
117
  }
104
118
  });
105
119
 
@@ -165,9 +179,9 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
165
179
 
166
180
  return (
167
181
  <>
168
- <Container
169
- onPress={() => handleClickViewOrder(order?.uuid)}
170
- activeOpacity={0.7}
182
+ <CardAnimation
183
+ onClick={() => handleClickViewOrder(order?.uuid)}
184
+ style={[styles.container]}
171
185
  >
172
186
  <InnerContainer>
173
187
  {(!!order.business?.logo || theme?.images?.dummies?.businessLogo) && (
@@ -280,21 +294,20 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
280
294
  </OText>
281
295
  </View>
282
296
  {!isMessageView && (
283
- <TouchableOpacity
284
- onPress={handleChangeFavorite}
285
- style={{ marginTop: 5 }}
286
- >
287
- <IconAntDesign
288
- name={order?.favorite ? 'heart' : 'hearto'}
289
- color={theme.colors.danger5}
290
- size={16}
291
- />
292
- </TouchableOpacity>
297
+ <LottieAnimation
298
+ type='favorite'
299
+ onClick={handleChangeFavorite}
300
+ initialValue={order?.favorite ? 1 : 0}
301
+ toValue={order?.favorite ? 0 : 1}
302
+ style={{ marginBottom: 5 }}
303
+ iconProps={{ color: theme.colors.danger5, size: 16, style: { top: 7 } }}
304
+ isActive={order?.favorite}
305
+ />
293
306
  )}
294
307
  </ContentFooter>
295
308
  </CardInfoWrapper>
296
309
  </InnerContainer>
297
- </Container>
310
+ </CardAnimation>
298
311
  <OAlert
299
312
  open={confirm.open}
300
313
  title={confirm.title}
@@ -1,12 +1,5 @@
1
1
  import styled from 'styled-components/native'
2
2
 
3
- export const Container = styled.TouchableOpacity`
4
- border-radius: 7.6px;
5
- box-shadow: 0 1px 2px #0000001A;
6
- margin-bottom: 10px;
7
- padding-vertical: 5px;
8
- `
9
-
10
3
  export const InnerContainer = styled.View`
11
4
  flex-direction: row;
12
5
  width: 100%;
@@ -11,14 +11,15 @@ import {
11
11
  } from 'ordering-components/native';
12
12
  import { useTheme } from 'styled-components/native';
13
13
  import { SingleProductCardParams } from '../../types';
14
- import { CardContainer, CardInfo, SoldOut, QuantityContainer, PricesContainer, RibbonBox, LogoWrapper } from './styles';
15
- import { StyleSheet, View, TouchableOpacity, Image, Animated } from 'react-native';
14
+ import { CardInfo, SoldOut, QuantityContainer, PricesContainer, RibbonBox, LogoWrapper } from './styles';
15
+ import { StyleSheet, View } from 'react-native';
16
16
  import { InView } from 'react-native-intersection-observer'
17
17
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
18
18
  import { OButton, OIcon, OText } from '../shared';
19
19
  import FastImage from 'react-native-fast-image'
20
- import IconAntDesign from 'react-native-vector-icons/AntDesign'
21
20
  import { shape } from '../../utils';
21
+ import { LottieAnimation } from '../LottieAnimation';
22
+ import { CardAnimation } from '../shared/CardAnimation'
22
23
 
23
24
  function SingleProductCardPropsAreEqual(prevProps: any, nextProps: any) {
24
25
  return JSON.stringify(prevProps.product) === JSON.stringify(nextProps.product) &&
@@ -47,10 +48,16 @@ const SingleProductCardUI = React.memo((props: SingleProductCardParams) => {
47
48
  const styles = StyleSheet.create({
48
49
  container: {
49
50
  borderWidth: 1,
50
- borderRadius: 7.6,
51
51
  borderColor: theme.colors.border,
52
52
  marginBottom: 25,
53
- minHeight: hideAddButton ? 100 : 165
53
+ minHeight: hideAddButton ? 100 : 165,
54
+ flex: 1,
55
+ flexDirection: hideAddButton ? 'row' : 'column',
56
+ justifyContent: 'space-between',
57
+ alignItems: 'center',
58
+ padding: 12,
59
+ borderRadius: 10,
60
+ position: 'relative'
54
61
  },
55
62
  titleWrapper: {
56
63
  flexDirection: 'row',
@@ -150,14 +157,13 @@ const SingleProductCardUI = React.memo((props: SingleProductCardParams) => {
150
157
  return (
151
158
  <InView style={{ minHeight: hideAddButton ? 125 : 190 }} triggerOnce={true} onChange={(inView: boolean) => handleChangeIntersection()}>
152
159
  {isIntersectionObserver ? (
153
- <CardContainer
154
- showAddButton={!hideAddButton}
160
+ <CardAnimation
161
+ onClick={() => handleClickproduct()}
155
162
  style={[
156
163
  styles.container,
157
164
  (isSoldOut || maxProductQuantity <= 0) && styles.soldOutBackgroundStyle,
158
- (style && { ...style }),
165
+ (style && { ...style })
159
166
  ]}
160
- onPress={() => handleClickproduct()}
161
167
  >
162
168
  <View style={{ flexDirection: 'row' }}>
163
169
  {productAddedToCartLength > 0 && (
@@ -178,15 +184,15 @@ const SingleProductCardUI = React.memo((props: SingleProductCardParams) => {
178
184
  {product?.name}
179
185
  </OText>
180
186
  {!isPreviously && (
181
- <TouchableOpacity
182
- onPress={handleChangeFavorite}
183
- >
184
- <IconAntDesign
185
- name={product?.favorite ? 'heart' : 'hearto'}
186
- color={theme.colors.danger5}
187
- size={18}
188
- />
189
- </TouchableOpacity>
187
+ <LottieAnimation
188
+ type='favorite'
189
+ onClick={handleChangeFavorite}
190
+ initialValue={product?.favorite ? 1 : 0}
191
+ toValue={product?.favorite ? 0 : 1}
192
+ disableAnimation={!auth}
193
+ iconProps={{ color: theme.colors.danger5, size: 18 }}
194
+ isActive={product?.favorite}
195
+ />
190
196
  )}
191
197
  </View>
192
198
  <PricesContainer>
@@ -236,20 +242,20 @@ const SingleProductCardUI = React.memo((props: SingleProductCardParams) => {
236
242
  </RibbonBox>
237
243
  )}
238
244
  {product?.images ? (
239
- <FastImage
240
- style={styles.productStyle}
241
- source={{
242
- uri: optimizeImage(product?.images, 'h_250,c_limit'),
243
- priority: FastImage.priority.normal,
244
- }}
245
- resizeMode={FastImage.resizeMode.cover}
246
- />
247
- ) : (
248
- <OIcon
249
- src={theme?.images?.dummies?.product}
250
- style={styles.productStyle}
251
- />
252
- )}
245
+ <FastImage
246
+ style={styles.productStyle}
247
+ source={{
248
+ uri: optimizeImage(product?.images, 'h_250,c_limit'),
249
+ priority: FastImage.priority.normal,
250
+ }}
251
+ resizeMode={FastImage.resizeMode.cover}
252
+ />
253
+ ) : (
254
+ <OIcon
255
+ src={theme?.images?.dummies?.product}
256
+ style={styles.productStyle}
257
+ />
258
+ )}
253
259
  </LogoWrapper>
254
260
 
255
261
  {(isSoldOut || maxProductQuantity <= 0) && (
@@ -275,7 +281,7 @@ const SingleProductCardUI = React.memo((props: SingleProductCardParams) => {
275
281
  text={t('ADD', 'Add')}
276
282
  />
277
283
  )}
278
- </CardContainer>
284
+ </CardAnimation>
279
285
  ) : (
280
286
  <View style={{ marginBottom: 28, padding: 12, height: hideAddButton ? 125 : 165 }}>
281
287
  <Placeholder style={{ padding: 5 }} Animation={Fade}>
@@ -1,14 +1,5 @@
1
1
  import styled, { css } from 'styled-components/native'
2
2
 
3
- export const CardContainer = styled.TouchableOpacity`
4
- flex: 1;
5
- flex-direction: ${(props : any) => props.showAddButton ? 'column' : 'row'};
6
- justify-content: space-between;
7
- align-items: center;
8
- padding: 12px;
9
- border-radius: 10px;
10
- position: relative;
11
- `
12
3
  export const CardInfo = styled.View`
13
4
  padding-start: 3px;
14
5
  flex: 1;
@@ -0,0 +1,47 @@
1
+ import React, { useState } from 'react'
2
+ import { StyleSheet, ViewStyle } from 'react-native'
3
+ import styled from 'styled-components/native'
4
+
5
+ const CardContainerTouchable = styled.TouchableOpacity``
6
+
7
+ interface Props {
8
+ children: React.ReactChildren | Element,
9
+ style?: Array<ViewStyle> | any,
10
+ onClick: any
11
+ }
12
+
13
+ export const CardAnimation = (props : Props) => {
14
+ const {
15
+ children,
16
+ onClick,
17
+ style
18
+ } = props
19
+ const [isPressed, setIsPressed] = useState(false)
20
+ const styles = StyleSheet.create({
21
+ cardAnimation: {
22
+ elevation: isPressed ? 2 : 0,
23
+ shadowColor: '#888',
24
+ shadowOffset: { width: 0, height: isPressed ? 2 : 0 },
25
+ shadowRadius: 18,
26
+ shadowOpacity: isPressed ? 0.8 : 0,
27
+ borderRadius: 12,
28
+ }
29
+ })
30
+
31
+ const styleProvided = style || []
32
+ return (
33
+ <CardContainerTouchable
34
+ onPress={onClick}
35
+ activeOpacity={0.8}
36
+ delayPressIn={20}
37
+ onPressIn={() => setIsPressed(true)}
38
+ onPressOut={() => setIsPressed(false)}
39
+ style={[
40
+ ...styleProvided,
41
+ styles.cardAnimation
42
+ ]}
43
+ >
44
+ {children}
45
+ </CardContainerTouchable>
46
+ )
47
+ }