@aws-amplify/ui-react-native 0.0.0-in-app-messaging-20220826014803
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/.eslintrc.js +100 -0
- package/.lintstagedrc.js +6 -0
- package/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +11 -0
- package/LICENSE +201 -0
- package/README.md +25 -0
- package/babel.config.js +3 -0
- package/dist/InAppMessaging/components/BannerMessage/BannerMessage.d.ts +3 -0
- package/dist/InAppMessaging/components/BannerMessage/BannerMessage.js +16 -0
- package/dist/InAppMessaging/components/BannerMessage/index.d.ts +2 -0
- package/dist/InAppMessaging/components/BannerMessage/index.js +1 -0
- package/dist/InAppMessaging/components/BannerMessage/styles.d.ts +7 -0
- package/dist/InAppMessaging/components/BannerMessage/styles.js +77 -0
- package/dist/InAppMessaging/components/BannerMessage/types.d.ts +12 -0
- package/dist/InAppMessaging/components/BannerMessage/types.js +1 -0
- package/dist/InAppMessaging/components/CarouselMessage/CarouselMessage.d.ts +3 -0
- package/dist/InAppMessaging/components/CarouselMessage/CarouselMessage.js +20 -0
- package/dist/InAppMessaging/components/CarouselMessage/CarouselMessageItem.d.ts +3 -0
- package/dist/InAppMessaging/components/CarouselMessage/CarouselMessageItem.js +18 -0
- package/dist/InAppMessaging/components/CarouselMessage/index.d.ts +2 -0
- package/dist/InAppMessaging/components/CarouselMessage/index.js +1 -0
- package/dist/InAppMessaging/components/CarouselMessage/styles.d.ts +5 -0
- package/dist/InAppMessaging/components/CarouselMessage/styles.js +98 -0
- package/dist/InAppMessaging/components/CarouselMessage/types.d.ts +18 -0
- package/dist/InAppMessaging/components/CarouselMessage/types.js +1 -0
- package/dist/InAppMessaging/components/FullScreenMessage/FullScreenMessage.d.ts +3 -0
- package/dist/InAppMessaging/components/FullScreenMessage/FullScreenMessage.js +18 -0
- package/dist/InAppMessaging/components/FullScreenMessage/index.d.ts +2 -0
- package/dist/InAppMessaging/components/FullScreenMessage/index.js +1 -0
- package/dist/InAppMessaging/components/FullScreenMessage/styles.d.ts +3 -0
- package/dist/InAppMessaging/components/FullScreenMessage/styles.js +86 -0
- package/dist/InAppMessaging/components/FullScreenMessage/types.d.ts +6 -0
- package/dist/InAppMessaging/components/FullScreenMessage/types.js +1 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/InAppMessageDisplay.d.ts +10 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/InAppMessageDisplay.js +29 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/handleMessageLinkAction.d.ts +3 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/handleMessageLinkAction.js +24 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/index.d.ts +2 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/index.js +1 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/types.d.ts +24 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/types.js +1 -0
- package/dist/InAppMessaging/components/MessageLayout/MessageLayout.d.ts +3 -0
- package/dist/InAppMessaging/components/MessageLayout/MessageLayout.js +34 -0
- package/dist/InAppMessaging/components/MessageLayout/index.d.ts +1 -0
- package/dist/InAppMessaging/components/MessageLayout/index.js +1 -0
- package/dist/InAppMessaging/components/MessageLayout/types.d.ts +7 -0
- package/dist/InAppMessaging/components/MessageLayout/types.js +1 -0
- package/dist/InAppMessaging/components/MessageWrapper/MessageWrapper.d.ts +3 -0
- package/dist/InAppMessaging/components/MessageWrapper/MessageWrapper.js +20 -0
- package/dist/InAppMessaging/components/MessageWrapper/index.d.ts +2 -0
- package/dist/InAppMessaging/components/MessageWrapper/index.js +1 -0
- package/dist/InAppMessaging/components/MessageWrapper/styles.d.ts +2 -0
- package/dist/InAppMessaging/components/MessageWrapper/styles.js +5 -0
- package/dist/InAppMessaging/components/MessageWrapper/types.d.ts +10 -0
- package/dist/InAppMessaging/components/MessageWrapper/types.js +1 -0
- package/dist/InAppMessaging/components/ModalMessage/ModalMessage.d.ts +3 -0
- package/dist/InAppMessaging/components/ModalMessage/ModalMessage.js +18 -0
- package/dist/InAppMessaging/components/ModalMessage/index.d.ts +2 -0
- package/dist/InAppMessaging/components/ModalMessage/index.js +1 -0
- package/dist/InAppMessaging/components/ModalMessage/styles.d.ts +4 -0
- package/dist/InAppMessaging/components/ModalMessage/styles.js +99 -0
- package/dist/InAppMessaging/components/ModalMessage/types.d.ts +6 -0
- package/dist/InAppMessaging/components/ModalMessage/types.js +1 -0
- package/dist/InAppMessaging/components/index.d.ts +6 -0
- package/dist/InAppMessaging/components/index.js +2 -0
- package/dist/InAppMessaging/components/withInAppMessaging/index.d.ts +1 -0
- package/dist/InAppMessaging/components/withInAppMessaging/index.js +1 -0
- package/dist/InAppMessaging/components/withInAppMessaging/withInAppMessaging.d.ts +5 -0
- package/dist/InAppMessaging/components/withInAppMessaging/withInAppMessaging.js +11 -0
- package/dist/InAppMessaging/constants.d.ts +31 -0
- package/dist/InAppMessaging/constants.js +43 -0
- package/dist/InAppMessaging/hooks/index.d.ts +2 -0
- package/dist/InAppMessaging/hooks/index.js +2 -0
- package/dist/InAppMessaging/hooks/useMessageImage/constants.d.ts +8 -0
- package/dist/InAppMessaging/hooks/useMessageImage/constants.js +18 -0
- package/dist/InAppMessaging/hooks/useMessageImage/index.d.ts +2 -0
- package/dist/InAppMessaging/hooks/useMessageImage/index.js +1 -0
- package/dist/InAppMessaging/hooks/useMessageImage/types.d.ts +15 -0
- package/dist/InAppMessaging/hooks/useMessageImage/types.js +6 -0
- package/dist/InAppMessaging/hooks/useMessageImage/useMessageImage.d.ts +10 -0
- package/dist/InAppMessaging/hooks/useMessageImage/useMessageImage.js +50 -0
- package/dist/InAppMessaging/hooks/useMessageImage/utils.d.ts +4 -0
- package/dist/InAppMessaging/hooks/useMessageImage/utils.js +56 -0
- package/dist/InAppMessaging/hooks/useMessageProps/index.d.ts +2 -0
- package/dist/InAppMessaging/hooks/useMessageProps/index.js +1 -0
- package/dist/InAppMessaging/hooks/useMessageProps/types.d.ts +109 -0
- package/dist/InAppMessaging/hooks/useMessageProps/types.js +1 -0
- package/dist/InAppMessaging/hooks/useMessageProps/useMessageProps.d.ts +12 -0
- package/dist/InAppMessaging/hooks/useMessageProps/useMessageProps.js +49 -0
- package/dist/InAppMessaging/hooks/useMessageProps/utils.d.ts +43 -0
- package/dist/InAppMessaging/hooks/useMessageProps/utils.js +192 -0
- package/dist/InAppMessaging/index.d.ts +2 -0
- package/dist/InAppMessaging/index.js +2 -0
- package/dist/__mocks__/react-native-safe-area-context.d.ts +3 -0
- package/dist/__mocks__/react-native-safe-area-context.js +4 -0
- package/dist/assets/close.png +0 -0
- package/dist/assets/index.d.ts +5 -0
- package/dist/assets/index.js +4 -0
- package/dist/assets/index.ts +7 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useDeviceOrientation/index.d.ts +1 -0
- package/dist/hooks/useDeviceOrientation/index.js +1 -0
- package/dist/hooks/useDeviceOrientation/useDeviceOrientation.d.ts +6 -0
- package/dist/hooks/useDeviceOrientation/useDeviceOrientation.js +33 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/primitives/Button/Button.d.ts +3 -0
- package/dist/primitives/Button/Button.js +8 -0
- package/dist/primitives/Button/index.d.ts +2 -0
- package/dist/primitives/Button/index.js +1 -0
- package/dist/primitives/Button/styles.d.ts +2 -0
- package/dist/primitives/Button/styles.js +4 -0
- package/dist/primitives/Button/types.d.ts +7 -0
- package/dist/primitives/Button/types.js +1 -0
- package/dist/primitives/Carousel/Carousel.d.ts +3 -0
- package/dist/primitives/Carousel/Carousel.js +58 -0
- package/dist/primitives/Carousel/CarouselPageIndicator.d.ts +3 -0
- package/dist/primitives/Carousel/CarouselPageIndicator.js +10 -0
- package/dist/primitives/Carousel/constants.d.ts +9 -0
- package/dist/primitives/Carousel/constants.js +18 -0
- package/dist/primitives/Carousel/index.d.ts +3 -0
- package/dist/primitives/Carousel/index.js +2 -0
- package/dist/primitives/Carousel/styles.d.ts +2 -0
- package/dist/primitives/Carousel/styles.js +11 -0
- package/dist/primitives/Carousel/types.d.ts +19 -0
- package/dist/primitives/Carousel/types.js +1 -0
- package/dist/primitives/IconButton/IconButton.d.ts +3 -0
- package/dist/primitives/IconButton/IconButton.js +9 -0
- package/dist/primitives/IconButton/index.d.ts +2 -0
- package/dist/primitives/IconButton/index.js +1 -0
- package/dist/primitives/IconButton/styles.d.ts +2 -0
- package/dist/primitives/IconButton/styles.js +9 -0
- package/dist/primitives/IconButton/types.d.ts +18 -0
- package/dist/primitives/IconButton/types.js +1 -0
- package/dist/primitives/index.d.ts +3 -0
- package/dist/primitives/index.js +3 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +4 -0
- package/jest.config.js +20 -0
- package/package.json +55 -0
- package/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx +37 -0
- package/src/InAppMessaging/components/BannerMessage/__tests__/BannerMessage.spec.tsx +138 -0
- package/src/InAppMessaging/components/BannerMessage/__tests__/__snapshots__/BannerMessage.spec.tsx.snap +224 -0
- package/src/InAppMessaging/components/BannerMessage/index.ts +2 -0
- package/src/InAppMessaging/components/BannerMessage/styles.ts +105 -0
- package/src/InAppMessaging/components/BannerMessage/types.ts +15 -0
- package/src/InAppMessaging/components/CarouselMessage/CarouselMessage.tsx +42 -0
- package/src/InAppMessaging/components/CarouselMessage/CarouselMessageItem.tsx +37 -0
- package/src/InAppMessaging/components/CarouselMessage/__tests__/CarouselMessage.spec.tsx +55 -0
- package/src/InAppMessaging/components/CarouselMessage/__tests__/CarouselMessageItem.spec.tsx +56 -0
- package/src/InAppMessaging/components/CarouselMessage/__tests__/__snapshots__/CarouselMessage.spec.tsx.snap +86 -0
- package/src/InAppMessaging/components/CarouselMessage/__tests__/__snapshots__/CarouselMessageItem.spec.tsx.snap +248 -0
- package/src/InAppMessaging/components/CarouselMessage/index.ts +2 -0
- package/src/InAppMessaging/components/CarouselMessage/styles.ts +125 -0
- package/src/InAppMessaging/components/CarouselMessage/types.ts +28 -0
- package/src/InAppMessaging/components/FullScreenMessage/FullScreenMessage.tsx +38 -0
- package/src/InAppMessaging/components/FullScreenMessage/__tests__/FullScreenMessage.spec.tsx +53 -0
- package/src/InAppMessaging/components/FullScreenMessage/__tests__/__snapshots__/FullScreenMessage.spec.tsx.snap +236 -0
- package/src/InAppMessaging/components/FullScreenMessage/index.ts +2 -0
- package/src/InAppMessaging/components/FullScreenMessage/styles.ts +106 -0
- package/src/InAppMessaging/components/FullScreenMessage/types.ts +7 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/InAppMessageDisplay.tsx +48 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/__tests__/InAppMessageDisplay.spec.tsx +33 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/__tests__/__snapshots__/InAppMessageDisplay.spec.tsx.snap +9 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/__tests__/handleMessageLinkAction.spec.ts +51 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/handleMessageLinkAction.ts +30 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/index.ts +2 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/types.ts +32 -0
- package/src/InAppMessaging/components/MessageLayout/MessageLayout.tsx +102 -0
- package/src/InAppMessaging/components/MessageLayout/index.ts +1 -0
- package/src/InAppMessaging/components/MessageLayout/types.ts +15 -0
- package/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx +34 -0
- package/src/InAppMessaging/components/MessageWrapper/__tests__/MessageWrapper.spec.tsx +19 -0
- package/src/InAppMessaging/components/MessageWrapper/__tests__/__snapshots__/MessageWrapper.spec.tsx.snap +35 -0
- package/src/InAppMessaging/components/MessageWrapper/index.ts +2 -0
- package/src/InAppMessaging/components/MessageWrapper/styles.ts +7 -0
- package/src/InAppMessaging/components/MessageWrapper/types.ts +12 -0
- package/src/InAppMessaging/components/ModalMessage/ModalMessage.tsx +37 -0
- package/src/InAppMessaging/components/ModalMessage/__tests__/ModalMessage.spec.tsx +155 -0
- package/src/InAppMessaging/components/ModalMessage/__tests__/__snapshots__/ModalMessage.spec.tsx.snap +323 -0
- package/src/InAppMessaging/components/ModalMessage/index.ts +2 -0
- package/src/InAppMessaging/components/ModalMessage/styles.ts +132 -0
- package/src/InAppMessaging/components/ModalMessage/types.ts +8 -0
- package/src/InAppMessaging/components/index.ts +6 -0
- package/src/InAppMessaging/components/withInAppMessaging/__tests__/__snapshots__/withInAppMessaging.spec.tsx.snap +3 -0
- package/src/InAppMessaging/components/withInAppMessaging/__tests__/withInAppMessaging.spec.tsx +15 -0
- package/src/InAppMessaging/components/withInAppMessaging/index.ts +1 -0
- package/src/InAppMessaging/components/withInAppMessaging/withInAppMessaging.tsx +18 -0
- package/src/InAppMessaging/constants.ts +56 -0
- package/src/InAppMessaging/hooks/index.ts +9 -0
- package/src/InAppMessaging/hooks/useMessageImage/__tests__/useMessageImage.spec.ts +141 -0
- package/src/InAppMessaging/hooks/useMessageImage/__tests__/utils.spec.ts +107 -0
- package/src/InAppMessaging/hooks/useMessageImage/constants.ts +27 -0
- package/src/InAppMessaging/hooks/useMessageImage/index.ts +2 -0
- package/src/InAppMessaging/hooks/useMessageImage/types.ts +18 -0
- package/src/InAppMessaging/hooks/useMessageImage/useMessageImage.ts +74 -0
- package/src/InAppMessaging/hooks/useMessageImage/utils.ts +80 -0
- package/src/InAppMessaging/hooks/useMessageProps/__tests__/__snapshots__/utils.spec.ts.snap +223 -0
- package/src/InAppMessaging/hooks/useMessageProps/__tests__/useMessageProps.spec.ts +162 -0
- package/src/InAppMessaging/hooks/useMessageProps/__tests__/utils.spec.ts +354 -0
- package/src/InAppMessaging/hooks/useMessageProps/index.ts +8 -0
- package/src/InAppMessaging/hooks/useMessageProps/types.ts +131 -0
- package/src/InAppMessaging/hooks/useMessageProps/useMessageProps.ts +70 -0
- package/src/InAppMessaging/hooks/useMessageProps/utils.ts +274 -0
- package/src/InAppMessaging/index.ts +14 -0
- package/src/__mocks__/react-native-safe-area-context.ts +6 -0
- package/src/__tests__/__snapshots__/index.spec.ts.snap +15 -0
- package/src/__tests__/index.spec.ts +8 -0
- package/src/assets/close.png +0 -0
- package/src/assets/index.ts +7 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useDeviceOrientation/__tests__/useDeviceOrientation.spec.ts +87 -0
- package/src/hooks/useDeviceOrientation/index.ts +4 -0
- package/src/hooks/useDeviceOrientation/useDeviceOrientation.ts +47 -0
- package/src/index.ts +1 -0
- package/src/primitives/Button/Button.tsx +21 -0
- package/src/primitives/Button/__tests__/Button.spec.tsx +24 -0
- package/src/primitives/Button/__tests__/__snapshots__/Button.spec.tsx.snap +52 -0
- package/src/primitives/Button/index.ts +2 -0
- package/src/primitives/Button/styles.ts +6 -0
- package/src/primitives/Button/types.ts +9 -0
- package/src/primitives/Carousel/Carousel.tsx +115 -0
- package/src/primitives/Carousel/CarouselPageIndicator.tsx +39 -0
- package/src/primitives/Carousel/__tests__/Carousel.spec.tsx +185 -0
- package/src/primitives/Carousel/__tests__/CarouselPageIndicator.spec.tsx +71 -0
- package/src/primitives/Carousel/__tests__/__snapshots__/Carousel.spec.tsx.snap +216 -0
- package/src/primitives/Carousel/__tests__/__snapshots__/CarouselPageIndicator.spec.tsx.snap +191 -0
- package/src/primitives/Carousel/constants.ts +25 -0
- package/src/primitives/Carousel/index.ts +3 -0
- package/src/primitives/Carousel/styles.ts +14 -0
- package/src/primitives/Carousel/types.ts +22 -0
- package/src/primitives/IconButton/IconButton.tsx +20 -0
- package/src/primitives/IconButton/__tests__/IconButton.spec.tsx +13 -0
- package/src/primitives/IconButton/__tests__/__snapshots__/IconButton.spec.tsx.snap +34 -0
- package/src/primitives/IconButton/index.ts +2 -0
- package/src/primitives/IconButton/styles.ts +16 -0
- package/src/primitives/IconButton/types.ts +27 -0
- package/src/primitives/index.ts +3 -0
- package/src/utils/index.ts +6 -0
- package/tsconfig.dist.json +4 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { ImageStyle, StyleSheet } from 'react-native';
|
|
2
|
+
import {
|
|
3
|
+
BORDER_RADIUS_BASE,
|
|
4
|
+
COLOR_BLACK,
|
|
5
|
+
COLOR_LIGHT_GREY,
|
|
6
|
+
COLOR_WHITE,
|
|
7
|
+
FONT_SIZE_BASE,
|
|
8
|
+
FONT_SIZE_LARGE,
|
|
9
|
+
FONT_WEIGHT_BASE,
|
|
10
|
+
LINE_HEIGHT_BASE,
|
|
11
|
+
LINE_HEIGHT_LARGE,
|
|
12
|
+
MESSAGE_ELEVATION,
|
|
13
|
+
MESSAGE_SHADOW_HEIGHT,
|
|
14
|
+
MESSAGE_SHADOW_OPACITY,
|
|
15
|
+
MESSAGE_SHADOW_RADIUS,
|
|
16
|
+
MESSAGE_SHADOW_WIDTH,
|
|
17
|
+
SPACING_EXTRA_LARGE,
|
|
18
|
+
SPACING_LARGE,
|
|
19
|
+
SPACING_MEDIUM,
|
|
20
|
+
SPACING_SMALL,
|
|
21
|
+
} from '../../constants';
|
|
22
|
+
|
|
23
|
+
import { ModalMessageStyle } from './types';
|
|
24
|
+
|
|
25
|
+
const commonStyles: Omit<
|
|
26
|
+
ModalMessageStyle,
|
|
27
|
+
'contentContainer' | 'image' | 'textContainer'
|
|
28
|
+
> = {
|
|
29
|
+
body: {
|
|
30
|
+
fontSize: FONT_SIZE_BASE,
|
|
31
|
+
fontWeight: FONT_WEIGHT_BASE,
|
|
32
|
+
lineHeight: LINE_HEIGHT_BASE,
|
|
33
|
+
},
|
|
34
|
+
buttonContainer: {
|
|
35
|
+
backgroundColor: COLOR_LIGHT_GREY,
|
|
36
|
+
borderRadius: BORDER_RADIUS_BASE,
|
|
37
|
+
flex: 1,
|
|
38
|
+
margin: SPACING_MEDIUM,
|
|
39
|
+
padding: SPACING_LARGE,
|
|
40
|
+
},
|
|
41
|
+
buttonsContainer: {
|
|
42
|
+
flexDirection: 'row',
|
|
43
|
+
justifyContent: 'center',
|
|
44
|
+
},
|
|
45
|
+
container: {
|
|
46
|
+
backgroundColor: COLOR_WHITE,
|
|
47
|
+
elevation: MESSAGE_ELEVATION,
|
|
48
|
+
margin: SPACING_EXTRA_LARGE,
|
|
49
|
+
shadowColor: COLOR_BLACK,
|
|
50
|
+
shadowOffset: {
|
|
51
|
+
width: MESSAGE_SHADOW_WIDTH,
|
|
52
|
+
height: MESSAGE_SHADOW_HEIGHT,
|
|
53
|
+
},
|
|
54
|
+
shadowOpacity: MESSAGE_SHADOW_OPACITY,
|
|
55
|
+
shadowRadius: MESSAGE_SHADOW_RADIUS,
|
|
56
|
+
},
|
|
57
|
+
buttonText: {
|
|
58
|
+
fontSize: FONT_SIZE_BASE,
|
|
59
|
+
fontWeight: FONT_WEIGHT_BASE,
|
|
60
|
+
lineHeight: LINE_HEIGHT_BASE,
|
|
61
|
+
textAlign: 'center',
|
|
62
|
+
},
|
|
63
|
+
header: {
|
|
64
|
+
fontSize: FONT_SIZE_LARGE,
|
|
65
|
+
fontWeight: FONT_WEIGHT_BASE,
|
|
66
|
+
lineHeight: LINE_HEIGHT_LARGE,
|
|
67
|
+
},
|
|
68
|
+
iconButton: {
|
|
69
|
+
alignSelf: 'flex-start',
|
|
70
|
+
marginLeft: 'auto',
|
|
71
|
+
},
|
|
72
|
+
imageContainer: {
|
|
73
|
+
alignItems: 'center',
|
|
74
|
+
margin: SPACING_LARGE,
|
|
75
|
+
},
|
|
76
|
+
wrapper: {
|
|
77
|
+
flex: 1,
|
|
78
|
+
justifyContent: 'center',
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const getPortraitStyles = (
|
|
83
|
+
imageDimensions: ImageStyle
|
|
84
|
+
): ModalMessageStyle =>
|
|
85
|
+
StyleSheet.create({
|
|
86
|
+
...commonStyles,
|
|
87
|
+
buttonsContainer: {
|
|
88
|
+
...commonStyles.buttonsContainer,
|
|
89
|
+
marginTop: 'auto',
|
|
90
|
+
paddingHorizontal: SPACING_SMALL,
|
|
91
|
+
paddingBottom: SPACING_SMALL,
|
|
92
|
+
},
|
|
93
|
+
container: {
|
|
94
|
+
...commonStyles.container,
|
|
95
|
+
minHeight: '40%',
|
|
96
|
+
},
|
|
97
|
+
contentContainer: { padding: SPACING_LARGE },
|
|
98
|
+
image: { ...imageDimensions },
|
|
99
|
+
textContainer: {
|
|
100
|
+
marginTop: SPACING_LARGE,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
export const getLandscapeStyles = (
|
|
105
|
+
imageDimensions: ImageStyle
|
|
106
|
+
): ModalMessageStyle =>
|
|
107
|
+
StyleSheet.create({
|
|
108
|
+
...commonStyles,
|
|
109
|
+
container: {
|
|
110
|
+
...commonStyles.container,
|
|
111
|
+
flex: 1,
|
|
112
|
+
padding: SPACING_EXTRA_LARGE,
|
|
113
|
+
},
|
|
114
|
+
contentContainer: {
|
|
115
|
+
flex: 1,
|
|
116
|
+
flexDirection: 'row',
|
|
117
|
+
},
|
|
118
|
+
iconButton: {
|
|
119
|
+
...commonStyles.iconButton,
|
|
120
|
+
marginRight: SPACING_MEDIUM,
|
|
121
|
+
},
|
|
122
|
+
image: { ...imageDimensions },
|
|
123
|
+
imageContainer: {
|
|
124
|
+
...commonStyles.imageContainer,
|
|
125
|
+
justifyContent: 'center',
|
|
126
|
+
},
|
|
127
|
+
textContainer: {
|
|
128
|
+
flex: 1,
|
|
129
|
+
justifyContent: 'center',
|
|
130
|
+
paddingHorizontal: SPACING_MEDIUM,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ModalMessageCommonProps } from '@aws-amplify/ui-react-core';
|
|
2
|
+
|
|
3
|
+
import { MessageDefaultStyle, MessageOverrideStyle } from '../../hooks';
|
|
4
|
+
|
|
5
|
+
export interface ModalMessageProps
|
|
6
|
+
extends ModalMessageCommonProps<MessageOverrideStyle | undefined> {}
|
|
7
|
+
|
|
8
|
+
export interface ModalMessageStyle extends MessageDefaultStyle {}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { BannerMessageProps } from './BannerMessage';
|
|
2
|
+
export { CarouselMessageProps } from './CarouselMessage';
|
|
3
|
+
export { FullScreenMessageProps } from './FullScreenMessage';
|
|
4
|
+
export { InAppMessageDisplay, MessageComponents } from './InAppMessageDisplay';
|
|
5
|
+
export { ModalMessageProps } from './ModalMessage';
|
|
6
|
+
export { withInAppMessaging } from './withInAppMessaging';
|
package/src/InAppMessaging/components/withInAppMessaging/__tests__/withInAppMessaging.spec.tsx
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import TestRenderer from 'react-test-renderer';
|
|
3
|
+
|
|
4
|
+
import withInAppMessaging from '../withInAppMessaging';
|
|
5
|
+
|
|
6
|
+
const TestComponent = ({ title }: { title: string }) => <>{title}</>;
|
|
7
|
+
|
|
8
|
+
describe('withInAppMessaging', () => {
|
|
9
|
+
it('renders as expected', () => {
|
|
10
|
+
const WrappedComponent = withInAppMessaging(TestComponent);
|
|
11
|
+
const output = TestRenderer.create(<WrappedComponent title="example" />);
|
|
12
|
+
|
|
13
|
+
expect(output.toJSON()).toMatchSnapshot();
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as withInAppMessaging } from './withInAppMessaging';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { InAppMessagingProvider } from '@aws-amplify/ui-react-core';
|
|
3
|
+
|
|
4
|
+
import { InAppMessageDisplay, MessageComponents } from '../InAppMessageDisplay';
|
|
5
|
+
|
|
6
|
+
export default function withInAppMessaging<Props>(
|
|
7
|
+
Component: (props: Props) => JSX.Element,
|
|
8
|
+
options?: { components?: MessageComponents }
|
|
9
|
+
): (props: Props) => JSX.Element {
|
|
10
|
+
return function WrappedWithInAppMessaging(props: Props) {
|
|
11
|
+
return (
|
|
12
|
+
<InAppMessagingProvider>
|
|
13
|
+
<InAppMessageDisplay {...options} />
|
|
14
|
+
<Component {...props} />
|
|
15
|
+
</InAppMessagingProvider>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { getLineHeight } from '../utils';
|
|
2
|
+
|
|
3
|
+
// color
|
|
4
|
+
export const COLOR_BLACK = '#000';
|
|
5
|
+
export const COLOR_GREY = '#a1a1a1';
|
|
6
|
+
export const COLOR_LIGHT_GREY = '#e8e8e8';
|
|
7
|
+
export const COLOR_LIGHT_GREY_2 = '#d8d8d8';
|
|
8
|
+
export const COLOR_WHITE = '#fff';
|
|
9
|
+
|
|
10
|
+
// spacing
|
|
11
|
+
export const SPACING_SMALL = 4;
|
|
12
|
+
export const SPACING_MEDIUM = 8;
|
|
13
|
+
export const SPACING_LARGE = 12;
|
|
14
|
+
export const SPACING_EXTRA_LARGE = 16;
|
|
15
|
+
|
|
16
|
+
// border radius
|
|
17
|
+
export const BORDER_RADIUS_BASE = 4;
|
|
18
|
+
|
|
19
|
+
// font
|
|
20
|
+
export const FONT_SIZE_BASE = 16;
|
|
21
|
+
export const FONT_SIZE_LARGE = 18;
|
|
22
|
+
|
|
23
|
+
export const LINE_HEIGHT_BASE = getLineHeight(FONT_SIZE_BASE);
|
|
24
|
+
export const LINE_HEIGHT_LARGE = getLineHeight(FONT_SIZE_LARGE);
|
|
25
|
+
|
|
26
|
+
export const FONT_WEIGHT_BASE = '400';
|
|
27
|
+
|
|
28
|
+
// icon
|
|
29
|
+
export const ICON_BUTTON_SIZE = 20;
|
|
30
|
+
export const ICON_BUTTON_HIT_SLOP = 10;
|
|
31
|
+
|
|
32
|
+
// shadow properties
|
|
33
|
+
|
|
34
|
+
// iOS shadow values
|
|
35
|
+
export const MESSAGE_SHADOW_HEIGHT = 2;
|
|
36
|
+
export const MESSAGE_SHADOW_WIDTH = 2;
|
|
37
|
+
export const MESSAGE_SHADOW_OPACITY = 0.1;
|
|
38
|
+
export const MESSAGE_SHADOW_RADIUS = 2;
|
|
39
|
+
|
|
40
|
+
// android shadow values
|
|
41
|
+
export const MESSAGE_ELEVATION = 3;
|
|
42
|
+
|
|
43
|
+
// Message UI Buttons
|
|
44
|
+
|
|
45
|
+
// default value applied in React Native TouchableOpacity
|
|
46
|
+
export const BUTTON_PRESSED_OPACITY = 0.8;
|
|
47
|
+
|
|
48
|
+
// Message Component Test IDs
|
|
49
|
+
export const IN_APP_MESSAGING_TEST_ID = {
|
|
50
|
+
BODY: 'in-app-messaging--body',
|
|
51
|
+
CLOSE_BUTTON: 'in-app-messaging--close-button',
|
|
52
|
+
HEADER: 'in-app-messaging--header',
|
|
53
|
+
IMAGE: 'in-app-messaging--image',
|
|
54
|
+
PRIMARY_BUTTON: 'in-app-messaging--primary-button',
|
|
55
|
+
SECONDARY_BUTTON: 'in-app-messaging--secondary-button',
|
|
56
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { Image } from 'react-native';
|
|
2
|
+
import { renderHook } from '@testing-library/react-hooks';
|
|
3
|
+
import { ConsoleLogger as Logger } from '@aws-amplify/core';
|
|
4
|
+
import { MessageImage } from '@aws-amplify/ui-react-core';
|
|
5
|
+
|
|
6
|
+
import { getLayoutImageDimensions, prefetchNetworkImage } from '../utils';
|
|
7
|
+
import useMessageImage from '../useMessageImage';
|
|
8
|
+
|
|
9
|
+
jest.mock('react-native', () => ({
|
|
10
|
+
Dimensions: { get: jest.fn(() => ({ height: 844, width: 400 })) },
|
|
11
|
+
Image: { getSize: jest.fn() },
|
|
12
|
+
}));
|
|
13
|
+
jest.mock('../utils');
|
|
14
|
+
|
|
15
|
+
// use empty mockImplementation to turn off console output
|
|
16
|
+
const errorSpy = jest.spyOn(Logger.prototype, 'error').mockImplementation();
|
|
17
|
+
|
|
18
|
+
const src = 'https://test.jpeg';
|
|
19
|
+
const image = { src };
|
|
20
|
+
|
|
21
|
+
describe('useMessageImage', () => {
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
jest.clearAllMocks();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('behaves as expected in the happy path', async () => {
|
|
27
|
+
const imageDimensions = { height: 100, width: 100 };
|
|
28
|
+
(prefetchNetworkImage as jest.Mock).mockResolvedValue('loaded');
|
|
29
|
+
(getLayoutImageDimensions as jest.Mock).mockReturnValueOnce(
|
|
30
|
+
imageDimensions
|
|
31
|
+
);
|
|
32
|
+
(Image.getSize as jest.Mock).mockImplementationOnce(
|
|
33
|
+
(_, onSuccess: () => void) => {
|
|
34
|
+
onSuccess();
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const { result, waitForNextUpdate } = renderHook(() =>
|
|
39
|
+
useMessageImage(image, 'TOP_BANNER')
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// first render
|
|
43
|
+
expect(result.current).toStrictEqual({
|
|
44
|
+
hasRenderableImage: false,
|
|
45
|
+
imageDimensions: { height: undefined, width: undefined },
|
|
46
|
+
isImageFetching: true,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
await waitForNextUpdate();
|
|
50
|
+
|
|
51
|
+
expect(result.current).toStrictEqual({
|
|
52
|
+
hasRenderableImage: true,
|
|
53
|
+
imageDimensions,
|
|
54
|
+
isImageFetching: false,
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('handles size retrieval errors as expected', async () => {
|
|
59
|
+
const error = 'ERROR';
|
|
60
|
+
|
|
61
|
+
(prefetchNetworkImage as jest.Mock).mockResolvedValue('loaded');
|
|
62
|
+
(Image.getSize as jest.Mock).mockImplementationOnce(
|
|
63
|
+
(_, __, onError: (error) => void) => {
|
|
64
|
+
onError(error);
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const { result, waitForNextUpdate } = renderHook(() =>
|
|
69
|
+
useMessageImage(image, 'TOP_BANNER')
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// first render
|
|
73
|
+
expect(result.current).toStrictEqual({
|
|
74
|
+
hasRenderableImage: false,
|
|
75
|
+
imageDimensions: { height: undefined, width: undefined },
|
|
76
|
+
isImageFetching: true,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
await waitForNextUpdate();
|
|
80
|
+
|
|
81
|
+
expect(errorSpy).toHaveBeenCalledWith(
|
|
82
|
+
`Unable to retrieve size for image: ${error}`
|
|
83
|
+
);
|
|
84
|
+
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
85
|
+
|
|
86
|
+
expect(result.current).toStrictEqual({
|
|
87
|
+
hasRenderableImage: false,
|
|
88
|
+
imageDimensions: { height: undefined, width: undefined },
|
|
89
|
+
isImageFetching: false,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('handles prefetching errors as expected', async () => {
|
|
94
|
+
(prefetchNetworkImage as jest.Mock).mockResolvedValue('failed');
|
|
95
|
+
|
|
96
|
+
const { result, waitForNextUpdate } = renderHook(() =>
|
|
97
|
+
useMessageImage(image, 'TOP_BANNER')
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// first render
|
|
101
|
+
expect(result.current).toStrictEqual({
|
|
102
|
+
hasRenderableImage: false,
|
|
103
|
+
imageDimensions: { height: undefined, width: undefined },
|
|
104
|
+
isImageFetching: true,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
await waitForNextUpdate();
|
|
108
|
+
|
|
109
|
+
expect(errorSpy).not.toHaveBeenCalled();
|
|
110
|
+
|
|
111
|
+
expect(result.current).toStrictEqual({
|
|
112
|
+
hasRenderableImage: false,
|
|
113
|
+
imageDimensions: { height: undefined, width: undefined },
|
|
114
|
+
isImageFetching: false,
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('returns the expected values when the image argument is an empty object', () => {
|
|
119
|
+
const { result } = renderHook(() =>
|
|
120
|
+
useMessageImage({} as MessageImage, 'TOP_BANNER')
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
expect(result.current).toStrictEqual({
|
|
124
|
+
hasRenderableImage: false,
|
|
125
|
+
imageDimensions: { height: undefined, width: undefined },
|
|
126
|
+
isImageFetching: false,
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('returns the expected values when the image argument is undefined', () => {
|
|
131
|
+
const { result } = renderHook(() =>
|
|
132
|
+
useMessageImage(undefined, 'TOP_BANNER')
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
expect(result.current).toStrictEqual({
|
|
136
|
+
hasRenderableImage: false,
|
|
137
|
+
imageDimensions: { height: undefined, width: undefined },
|
|
138
|
+
isImageFetching: false,
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Image } from 'react-native';
|
|
2
|
+
import { ConsoleLogger as Logger } from '@aws-amplify/core';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
BANNER_IMAGE_SCREEN_MULTIPLIER,
|
|
6
|
+
BANNER_IMAGE_SCREEN_SIZE,
|
|
7
|
+
} from '../constants';
|
|
8
|
+
import { getLayoutImageDimensions, prefetchNetworkImage } from '../utils';
|
|
9
|
+
|
|
10
|
+
jest.mock('react-native', () => ({
|
|
11
|
+
Dimensions: { get: jest.fn(() => ({ height: 844, width: 400 })) },
|
|
12
|
+
Image: { prefetch: jest.fn() },
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
// use empty mockImplementation to turn off console output
|
|
16
|
+
const errorSpy = jest.spyOn(Logger.prototype, 'error').mockImplementation();
|
|
17
|
+
|
|
18
|
+
const url = 'https://test.jpeg';
|
|
19
|
+
|
|
20
|
+
describe('prefetchNetworkImage', () => {
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
jest.clearAllMocks();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('behaves as expected in the happy path', async () => {
|
|
26
|
+
(Image.prefetch as jest.Mock).mockResolvedValueOnce(true);
|
|
27
|
+
|
|
28
|
+
const output = await prefetchNetworkImage(url);
|
|
29
|
+
|
|
30
|
+
expect(output).toBe('loaded');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('handles a false response from Image.prefetch as expected', async () => {
|
|
34
|
+
(Image.prefetch as jest.Mock).mockResolvedValueOnce(false);
|
|
35
|
+
|
|
36
|
+
const output = await prefetchNetworkImage(url);
|
|
37
|
+
|
|
38
|
+
expect(errorSpy).toHaveBeenLastCalledWith(`Image failed to load: ${url}`);
|
|
39
|
+
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
40
|
+
|
|
41
|
+
expect(output).toBe('failed');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('handles an error from Imaage.prefetch as expected', async () => {
|
|
45
|
+
const error = 'ERROR';
|
|
46
|
+
(Image.prefetch as jest.Mock).mockRejectedValueOnce(new Error(error));
|
|
47
|
+
|
|
48
|
+
const output = await prefetchNetworkImage(url);
|
|
49
|
+
|
|
50
|
+
expect(errorSpy).toHaveBeenLastCalledWith(
|
|
51
|
+
`Image.prefetch failed: Error: ${error}`
|
|
52
|
+
);
|
|
53
|
+
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
54
|
+
|
|
55
|
+
expect(output).toBe('failed');
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('getLayoutImageDimensions', () => {
|
|
60
|
+
it('returns the expected values for a square image', () => {
|
|
61
|
+
const imageHeight = 100;
|
|
62
|
+
const imageWidth = 100;
|
|
63
|
+
|
|
64
|
+
const output = getLayoutImageDimensions(
|
|
65
|
+
imageHeight,
|
|
66
|
+
imageWidth,
|
|
67
|
+
'TOP_BANNER'
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
expect(output).toStrictEqual({
|
|
71
|
+
height: BANNER_IMAGE_SCREEN_SIZE,
|
|
72
|
+
width: BANNER_IMAGE_SCREEN_SIZE,
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('returns the expected values for a portrait image', () => {
|
|
77
|
+
const imageHeight = 200;
|
|
78
|
+
const imageWidth = 100;
|
|
79
|
+
|
|
80
|
+
const output = getLayoutImageDimensions(
|
|
81
|
+
imageHeight,
|
|
82
|
+
imageWidth,
|
|
83
|
+
'TOP_BANNER'
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
expect(output).toStrictEqual({
|
|
87
|
+
height: BANNER_IMAGE_SCREEN_SIZE,
|
|
88
|
+
width: imageHeight * BANNER_IMAGE_SCREEN_MULTIPLIER,
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('returns the expected values for a landscape image', () => {
|
|
93
|
+
const imageHeight = 100;
|
|
94
|
+
const imageWidth = 200;
|
|
95
|
+
|
|
96
|
+
const output = getLayoutImageDimensions(
|
|
97
|
+
imageHeight,
|
|
98
|
+
imageWidth,
|
|
99
|
+
'TOP_BANNER'
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
expect(output).toStrictEqual({
|
|
103
|
+
height: imageWidth * BANNER_IMAGE_SCREEN_MULTIPLIER,
|
|
104
|
+
width: BANNER_IMAGE_SCREEN_SIZE,
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Dimensions } from 'react-native';
|
|
2
|
+
|
|
3
|
+
// as images are not expected to be responsive to orientation changes get screen dimensions at app start
|
|
4
|
+
const SCREEN_DIMENSIONS = Dimensions.get('screen');
|
|
5
|
+
|
|
6
|
+
// compare screen width and height and assign the lesser of the two as the base screen dimension
|
|
7
|
+
const BASE_SCREEN_DIMENSION =
|
|
8
|
+
SCREEN_DIMENSIONS.width < SCREEN_DIMENSIONS.height
|
|
9
|
+
? SCREEN_DIMENSIONS.width
|
|
10
|
+
: SCREEN_DIMENSIONS.height;
|
|
11
|
+
|
|
12
|
+
// base size that message images should fill
|
|
13
|
+
// - all banner message images should fill 20 percent of the base screen dimension
|
|
14
|
+
// - all other components should fill 60 percent of the base screen dimension
|
|
15
|
+
export const BANNER_IMAGE_SCREEN_MULTIPLIER = 0.2;
|
|
16
|
+
export const CAROUSEL_IMAGE_SCREEN_MULTIPLIER = 0.6;
|
|
17
|
+
export const FULL_SCREEN_IMAGE_SCREEN_MULTIPLIER = 0.6;
|
|
18
|
+
export const MODAL_IMAGE_SCREEN_MULTIPLIER = 0.6;
|
|
19
|
+
|
|
20
|
+
export const BANNER_IMAGE_SCREEN_SIZE =
|
|
21
|
+
BANNER_IMAGE_SCREEN_MULTIPLIER * BASE_SCREEN_DIMENSION;
|
|
22
|
+
export const CAROUSEL_IMAGE_SCREEN_SIZE =
|
|
23
|
+
CAROUSEL_IMAGE_SCREEN_MULTIPLIER * BASE_SCREEN_DIMENSION;
|
|
24
|
+
export const FULL_SCREEN_IMAGE_SCREEN_SIZE =
|
|
25
|
+
FULL_SCREEN_IMAGE_SCREEN_MULTIPLIER * BASE_SCREEN_DIMENSION;
|
|
26
|
+
export const MODAL_IMAGE_SCREEN_SIZE =
|
|
27
|
+
MODAL_IMAGE_SCREEN_MULTIPLIER * BASE_SCREEN_DIMENSION;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type ImageDimensions = {
|
|
2
|
+
height: number | undefined;
|
|
3
|
+
width: number | undefined;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export type ImageLoadingState = 'loaded' | 'failed';
|
|
7
|
+
|
|
8
|
+
export enum ImagePrefetchStatus {
|
|
9
|
+
Failure = 'FAILURE',
|
|
10
|
+
Fetching = 'FETCHING',
|
|
11
|
+
Success = 'SUCCESS',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type UseMessageImage = {
|
|
15
|
+
hasRenderableImage: boolean;
|
|
16
|
+
imageDimensions: ImageDimensions;
|
|
17
|
+
isImageFetching: boolean;
|
|
18
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { Image } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { ConsoleLogger as Logger } from '@aws-amplify/core';
|
|
5
|
+
import { MessageImage, MessageLayout } from '@aws-amplify/ui-react-core';
|
|
6
|
+
|
|
7
|
+
import { ImageDimensions, ImagePrefetchStatus, UseMessageImage } from './types';
|
|
8
|
+
import { getLayoutImageDimensions, prefetchNetworkImage } from './utils';
|
|
9
|
+
|
|
10
|
+
const logger = new Logger('Notifications.InAppMessaging');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Handles prefetching and dimension setting for message images
|
|
14
|
+
*
|
|
15
|
+
* @param image contains image source
|
|
16
|
+
* @param layout message layout
|
|
17
|
+
* @returns message image dimensions and rendering related booleans
|
|
18
|
+
*/
|
|
19
|
+
export default function useMessageImage(
|
|
20
|
+
image: MessageImage | undefined,
|
|
21
|
+
layout: MessageLayout
|
|
22
|
+
): UseMessageImage {
|
|
23
|
+
const { src } = image ?? {};
|
|
24
|
+
const shouldPrefetch = !!src;
|
|
25
|
+
|
|
26
|
+
// set initial status to fetching if prefetch is required
|
|
27
|
+
const [prefetchStatus, setPrefetchStatus] =
|
|
28
|
+
useState<ImagePrefetchStatus | null>(
|
|
29
|
+
shouldPrefetch ? ImagePrefetchStatus.Fetching : null
|
|
30
|
+
);
|
|
31
|
+
const imageDimensions = useRef<ImageDimensions>({
|
|
32
|
+
height: undefined,
|
|
33
|
+
width: undefined,
|
|
34
|
+
}).current;
|
|
35
|
+
|
|
36
|
+
const isImageFetching = prefetchStatus === ImagePrefetchStatus.Fetching;
|
|
37
|
+
const hasRenderableImage = prefetchStatus === ImagePrefetchStatus.Success;
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (!shouldPrefetch) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
prefetchNetworkImage(src).then((prefetchResult) => {
|
|
45
|
+
if (prefetchResult === 'loaded') {
|
|
46
|
+
// get image size once loaded
|
|
47
|
+
Image.getSize(
|
|
48
|
+
src,
|
|
49
|
+
(imageWidth, imageHeight) => {
|
|
50
|
+
const { height, width } = getLayoutImageDimensions(
|
|
51
|
+
imageHeight,
|
|
52
|
+
imageWidth,
|
|
53
|
+
layout
|
|
54
|
+
);
|
|
55
|
+
imageDimensions.height = height;
|
|
56
|
+
imageDimensions.width = width;
|
|
57
|
+
|
|
58
|
+
setPrefetchStatus(ImagePrefetchStatus.Success);
|
|
59
|
+
},
|
|
60
|
+
(error) => {
|
|
61
|
+
// handle size retrieval error
|
|
62
|
+
logger.error(`Unable to retrieve size for image: ${error}`);
|
|
63
|
+
setPrefetchStatus(ImagePrefetchStatus.Failure);
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
} else {
|
|
67
|
+
// handle prefetch failure
|
|
68
|
+
setPrefetchStatus(ImagePrefetchStatus.Failure);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}, [imageDimensions, layout, shouldPrefetch, src]);
|
|
72
|
+
|
|
73
|
+
return { hasRenderableImage, imageDimensions, isImageFetching };
|
|
74
|
+
}
|