@quintype/native-components 2.20.6 → 2.20.7
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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/components/JSEmbedElement/index.js +25 -15
- package/src/components/LightBoxImage/index.js +14 -8
- package/src/components/ResponsiveImage/index.js +10 -15
- package/src/components/SlideshowStoryCard/index.js +24 -13
- package/src/components/SlideshowStoryCard/styles.js +23 -25
- package/src/components/StoryGallery/index.js +133 -76
- package/src/components/StoryGallery/styles.js +125 -122
- package/src/components/StoryHeader/index.js +0 -1
- package/src/components/StorySlideshow/index.js +29 -25
- package/src/components/StorySlideshow/styles.js +35 -39
- package/src/utils/imageUtils.js +7 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [2.20.7](https://github.com/quintype/native-components/compare/v2.20.6...v2.20.7) (2023-06-16)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **images:** Fixes crop issues and adds rich-text support for attribution ([#201](https://github.com/quintype/native-components/issues/201)) ([c0a5ca0](https://github.com/quintype/native-components/commit/c0a5ca0f593f1ce3459ae0fcc2aba3f06f21e053))
|
|
11
|
+
|
|
5
12
|
### [2.20.6](https://github.com/quintype/native-components/compare/v2.20.5...v2.20.6) (2023-06-15)
|
|
6
13
|
|
|
7
14
|
### [2.20.5](https://github.com/quintype/native-components/compare/v2.20.4...v2.20.5) (2023-03-21)
|
package/package.json
CHANGED
|
@@ -18,26 +18,29 @@ const replaceDefaultProtocol = (content) => {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
const removeWidthnHeight = (htmlContent) => {
|
|
21
|
-
|
|
21
|
+
const temp = htmlContent.split(' ');
|
|
22
22
|
let finalHtml = '';
|
|
23
|
-
if(temp[0]==='<iframe'){
|
|
24
|
-
for(let i=0; i<temp.length; i++){
|
|
25
|
-
if
|
|
23
|
+
if (temp[0] === '<iframe') {
|
|
24
|
+
for (let i = 0; i < temp.length; i++) {
|
|
25
|
+
if (
|
|
26
|
+
(temp[i].includes('width') || temp[i].includes('height'))
|
|
27
|
+
&& !temp[i].includes('/')
|
|
28
|
+
) {
|
|
26
29
|
continue;
|
|
27
30
|
}
|
|
28
|
-
finalHtml = finalHtml + temp[i]
|
|
31
|
+
finalHtml = `${finalHtml + temp[i]} `;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
return finalHtml;
|
|
32
35
|
}
|
|
33
36
|
return htmlContent;
|
|
34
|
-
}
|
|
37
|
+
};
|
|
35
38
|
|
|
36
39
|
const getHTMLContent = (embedJs) => {
|
|
37
|
-
const width =
|
|
40
|
+
const { width } = Dimensions.get('window');
|
|
38
41
|
const decodedContent = getDecodedContent(embedJs);
|
|
39
|
-
let htmlContent = replaceDefaultProtocol(decodedContent)
|
|
40
|
-
htmlContent = removeWidthnHeight(htmlContent)
|
|
42
|
+
let htmlContent = replaceDefaultProtocol(decodedContent);
|
|
43
|
+
htmlContent = removeWidthnHeight(htmlContent);
|
|
41
44
|
const webViewScript = `
|
|
42
45
|
<script type="application/javascript">
|
|
43
46
|
var interValId;
|
|
@@ -60,8 +63,8 @@ const getHTMLContent = (embedJs) => {
|
|
|
60
63
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
61
64
|
<style>
|
|
62
65
|
iframe{
|
|
63
|
-
width:${width-20}px;
|
|
64
|
-
height:${width-20}px;
|
|
66
|
+
width:${width - 20}px;
|
|
67
|
+
height:${width - 20}px;
|
|
65
68
|
}
|
|
66
69
|
</style>
|
|
67
70
|
</head>
|
|
@@ -75,7 +78,11 @@ const getHTMLContent = (embedJs) => {
|
|
|
75
78
|
export const JSEmbedElement = (props) => {
|
|
76
79
|
const [height, setHeight] = useState(300);
|
|
77
80
|
const webViewRef = useRef(null);
|
|
78
|
-
const width = get(
|
|
81
|
+
const width = get(
|
|
82
|
+
props,
|
|
83
|
+
['currentLayout', 'width'],
|
|
84
|
+
Dimensions.get('window').width,
|
|
85
|
+
);
|
|
79
86
|
|
|
80
87
|
useEffect(() => {
|
|
81
88
|
webViewRef?.current?.reload();
|
|
@@ -94,10 +101,10 @@ export const JSEmbedElement = (props) => {
|
|
|
94
101
|
|
|
95
102
|
const baseUrl = urlMapper[props.element.subtype] || 'https://twitter.com';
|
|
96
103
|
|
|
97
|
-
return
|
|
104
|
+
return {
|
|
98
105
|
html: getHTMLContent(props.element['embed-js']),
|
|
99
106
|
baseUrl,
|
|
100
|
-
}
|
|
107
|
+
};
|
|
101
108
|
};
|
|
102
109
|
|
|
103
110
|
return (
|
|
@@ -105,7 +112,10 @@ export const JSEmbedElement = (props) => {
|
|
|
105
112
|
<WebView
|
|
106
113
|
ref={webViewRef}
|
|
107
114
|
style={{
|
|
108
|
-
width,
|
|
115
|
+
width,
|
|
116
|
+
height,
|
|
117
|
+
flex: 0,
|
|
118
|
+
opacity: 0.99,
|
|
109
119
|
}}
|
|
110
120
|
automaticallyAdjustContentInsets={false}
|
|
111
121
|
scrollEnabled={false}
|
|
@@ -6,20 +6,23 @@ import { LightBox } from '../LightBox';
|
|
|
6
6
|
import { getImageHeight } from '../../utils';
|
|
7
7
|
|
|
8
8
|
export const LightBoxImage = ({
|
|
9
|
-
data, hero, currentLayout, additionalStyles, elementType, onClickHandler = ()=>{}, index
|
|
9
|
+
data, hero, currentLayout, additionalStyles, elementType, onClickHandler = () => {}, index,
|
|
10
10
|
}) => {
|
|
11
|
-
const {
|
|
11
|
+
const {
|
|
12
|
+
cdn, slug, metaData, imageWidth: previewWidth,
|
|
13
|
+
} = data;
|
|
12
14
|
const { width, height } = metaData || {};
|
|
13
15
|
const imageHeight = getImageHeight(width, height);
|
|
14
16
|
const imageUri = `${data?.cdn}/${data?.slug}`;
|
|
15
17
|
const [showModal, setShowModal] = useState(false);
|
|
16
18
|
|
|
17
19
|
const toggleModal = () => {
|
|
18
|
-
if(elementType === 'gallery'){
|
|
20
|
+
if (elementType === 'gallery') {
|
|
19
21
|
onClickHandler(index);
|
|
20
|
-
} else{
|
|
21
|
-
setShowModal(!showModal)
|
|
22
|
-
}
|
|
22
|
+
} else {
|
|
23
|
+
setShowModal(!showModal);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
23
26
|
|
|
24
27
|
const styles = {
|
|
25
28
|
image: {
|
|
@@ -39,7 +42,8 @@ export const LightBoxImage = ({
|
|
|
39
42
|
metaData={metaData}
|
|
40
43
|
hero={hero || false}
|
|
41
44
|
styles={cumulativeStyles}
|
|
42
|
-
|
|
45
|
+
imageWidth={previewWidth}
|
|
46
|
+
elementType={elementType || null}
|
|
43
47
|
/>
|
|
44
48
|
</TouchableOpacity>
|
|
45
49
|
</>
|
|
@@ -47,9 +51,11 @@ export const LightBoxImage = ({
|
|
|
47
51
|
};
|
|
48
52
|
|
|
49
53
|
LightBoxImage.propTypes = {
|
|
50
|
-
children: PropTypes.element,
|
|
51
54
|
data: PropTypes.object,
|
|
52
55
|
hero: PropTypes.bool,
|
|
53
56
|
currentLayout: PropTypes.object,
|
|
54
57
|
additionalStyles: PropTypes.object,
|
|
58
|
+
elementType: PropTypes.string,
|
|
59
|
+
onClickHandler: PropTypes.func,
|
|
60
|
+
index: PropTypes.number,
|
|
55
61
|
};
|
|
@@ -5,18 +5,18 @@ import React, {
|
|
|
5
5
|
import { StyleSheet, View } from 'react-native';
|
|
6
6
|
import FastImage from 'react-native-fast-image';
|
|
7
7
|
import Icon from 'react-native-vector-icons/FontAwesome';
|
|
8
|
-
import { isTablet } from 'react-native-device-info';
|
|
9
8
|
import { FallbackIcon } from '../../Icons/FallBackIcon';
|
|
10
9
|
import { AppTheme } from '../../utils';
|
|
11
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
getImageURL,
|
|
12
|
+
getCustomResolutionImageURL,
|
|
13
|
+
} from '../../utils/imageUtils';
|
|
12
14
|
|
|
13
15
|
const ResponsiveImageBase = (props) => {
|
|
14
16
|
const [placeholder, setPlaceholder] = useState(true);
|
|
15
17
|
const { theme } = useContext(AppTheme);
|
|
16
18
|
const { COLORS, CustomFallBackIcon, CustomFallBackBackground } = theme;
|
|
17
19
|
|
|
18
|
-
const HERO_IMAGE_HEIGHT = isTablet() ? 300 : 232;
|
|
19
|
-
|
|
20
20
|
const flattenedImageStyle = StyleSheet.flatten([
|
|
21
21
|
styles.defaultImage,
|
|
22
22
|
props.styles,
|
|
@@ -24,15 +24,9 @@ const ResponsiveImageBase = (props) => {
|
|
|
24
24
|
width: props.imageWidth,
|
|
25
25
|
height: (props.imageWidth * 9) / 16,
|
|
26
26
|
},
|
|
27
|
-
(props.hero && props?.elementType !== 'gallery' ) && {
|
|
28
|
-
width: '100%',
|
|
29
|
-
height: HERO_IMAGE_HEIGHT,
|
|
30
|
-
alignSelf: 'stretch',
|
|
31
|
-
},
|
|
32
27
|
props?.elementType === 'gallery' && {
|
|
33
|
-
backgroundColor: COLORS.BRAND_BLACK
|
|
34
|
-
}
|
|
35
|
-
|
|
28
|
+
backgroundColor: COLORS.BRAND_BLACK,
|
|
29
|
+
},
|
|
36
30
|
]);
|
|
37
31
|
|
|
38
32
|
const placeholderStyle = {
|
|
@@ -48,9 +42,9 @@ const ResponsiveImageBase = (props) => {
|
|
|
48
42
|
<FallbackIcon />
|
|
49
43
|
);
|
|
50
44
|
|
|
51
|
-
let imageUrl = ''
|
|
45
|
+
let imageUrl = '';
|
|
52
46
|
|
|
53
|
-
if(props?.elementType === 'gallery'){
|
|
47
|
+
if (props?.elementType === 'gallery') {
|
|
54
48
|
imageUrl = getCustomResolutionImageURL(props, [1, 1]);
|
|
55
49
|
} else {
|
|
56
50
|
imageUrl = getImageURL(props);
|
|
@@ -82,7 +76,7 @@ const ResponsiveImageBase = (props) => {
|
|
|
82
76
|
style={flattenedImageStyle}
|
|
83
77
|
source={sourceURI}
|
|
84
78
|
onLoad={onLoadHandler}
|
|
85
|
-
resizeMode={props.hero ? FastImage.resizeMode.
|
|
79
|
+
resizeMode={props?.elementType === 'gallery' && !(props.hero) ? FastImage.resizeMode.contain : FastImage.resizeMode.cover}
|
|
86
80
|
{...props}
|
|
87
81
|
/>
|
|
88
82
|
{placeholder && (
|
|
@@ -105,6 +99,7 @@ ResponsiveImageBase.propTypes = {
|
|
|
105
99
|
testID: PropTypes.string,
|
|
106
100
|
containerTestID: PropTypes.string,
|
|
107
101
|
imageWidth: PropTypes.number,
|
|
102
|
+
elementType: PropTypes.string,
|
|
108
103
|
};
|
|
109
104
|
|
|
110
105
|
ResponsiveImageBase.defaultProps = {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
import React, { useContext } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { View, Linking } from 'react-native';
|
|
4
|
+
import HTML from 'react-native-render-html';
|
|
4
5
|
import { AppTheme, getScreenPercentageWidth } from '../../utils/index';
|
|
5
6
|
import { LightBoxImage } from '../LightBoxImage';
|
|
6
7
|
import { slideshowStoryCardStyles } from './styles';
|
|
@@ -9,26 +10,37 @@ export const SlideshowStoryCard = ({ card, cdn }) => {
|
|
|
9
10
|
const attribution = card['image-attribution'];
|
|
10
11
|
const { title } = card;
|
|
11
12
|
const { theme } = useContext(AppTheme);
|
|
12
|
-
const
|
|
13
|
-
const styles = slideshowStoryCardStyles(theme)
|
|
13
|
+
const { CAN_COPY_TEXT } = theme;
|
|
14
|
+
const styles = slideshowStoryCardStyles(theme);
|
|
14
15
|
const imgData = {
|
|
15
16
|
cdn,
|
|
16
17
|
slug: card['image-s3-key'],
|
|
17
|
-
imageWidth: getScreenPercentageWidth(
|
|
18
|
+
imageWidth: getScreenPercentageWidth(100),
|
|
18
19
|
metaData: card['image-metadata'],
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
return (
|
|
22
23
|
<View style={styles.container}>
|
|
23
|
-
<
|
|
24
|
-
<LightBoxImage data={imgData} hero />
|
|
25
|
-
</View>
|
|
26
|
-
|
|
24
|
+
<LightBoxImage data={imgData} />
|
|
27
25
|
<View style={styles.textContainer}>
|
|
28
|
-
<
|
|
29
|
-
{
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
<HTML
|
|
27
|
+
html={title}
|
|
28
|
+
textSelectable={CAN_COPY_TEXT}
|
|
29
|
+
key={Math.random()}
|
|
30
|
+
baseFontStyle={styles.cardTitleText}
|
|
31
|
+
onLinkPress={(e, href) => {
|
|
32
|
+
Linking.openURL(href);
|
|
33
|
+
}}
|
|
34
|
+
/>
|
|
35
|
+
<HTML
|
|
36
|
+
html={attribution}
|
|
37
|
+
textSelectable={CAN_COPY_TEXT}
|
|
38
|
+
key={Math.random()}
|
|
39
|
+
baseFontStyle={styles.attributionText}
|
|
40
|
+
onLinkPress={(e, href) => {
|
|
41
|
+
Linking.openURL(href);
|
|
42
|
+
}}
|
|
43
|
+
/>
|
|
32
44
|
</View>
|
|
33
45
|
</View>
|
|
34
46
|
);
|
|
@@ -37,5 +49,4 @@ export const SlideshowStoryCard = ({ card, cdn }) => {
|
|
|
37
49
|
SlideshowStoryCard.propTypes = {
|
|
38
50
|
cdn: PropTypes.string.isRequired,
|
|
39
51
|
card: PropTypes.object,
|
|
40
|
-
imageSize: PropTypes.object,
|
|
41
52
|
};
|
|
@@ -1,28 +1,26 @@
|
|
|
1
1
|
import { StyleSheet, Dimensions } from 'react-native';
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
const { width } = Dimensions.get('window');
|
|
4
4
|
|
|
5
|
-
export const slideshowStoryCardStyles = ({ COLORS }) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
})
|
|
28
|
-
}
|
|
5
|
+
export const slideshowStoryCardStyles = ({ COLORS, FONT_FAMILY }) => StyleSheet.create({
|
|
6
|
+
textContainer: {
|
|
7
|
+
paddingHorizontal: 10,
|
|
8
|
+
flexDirection: 'column',
|
|
9
|
+
flexWrap: 'wrap',
|
|
10
|
+
marginTop: 10,
|
|
11
|
+
},
|
|
12
|
+
cardTitleText: {
|
|
13
|
+
opacity: 0.7,
|
|
14
|
+
color: COLORS.BRAND_BLACK,
|
|
15
|
+
fontFamily: FONT_FAMILY.secondary,
|
|
16
|
+
},
|
|
17
|
+
container: {
|
|
18
|
+
flexDirection: 'column',
|
|
19
|
+
width,
|
|
20
|
+
},
|
|
21
|
+
attributionText: {
|
|
22
|
+
color: COLORS.BRAND_BLACK,
|
|
23
|
+
fontFamily: FONT_FAMILY.secondary,
|
|
24
|
+
opacity: 0.8,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
import React, { useContext, useState, useRef } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
View,
|
|
5
|
+
Modal,
|
|
6
|
+
Linking,
|
|
7
|
+
SafeAreaView,
|
|
8
|
+
FlatList,
|
|
9
|
+
TouchableOpacity,
|
|
10
|
+
} from 'react-native';
|
|
11
|
+
import Icon from 'react-native-vector-icons/FontAwesome';
|
|
12
|
+
import FastImage from 'react-native-fast-image';
|
|
13
|
+
import HTML from 'react-native-render-html';
|
|
4
14
|
import { styles } from './styles';
|
|
5
15
|
import { Text } from '../index';
|
|
6
|
-
import {
|
|
16
|
+
import { AppTheme } from '../../utils/index';
|
|
7
17
|
import { LightBoxImage } from '../LightBoxImage';
|
|
8
|
-
import Icon from 'react-native-vector-icons/FontAwesome';
|
|
9
|
-
import FastImage from 'react-native-fast-image';
|
|
10
|
-
import { resolve } from 'path-browserify';
|
|
11
18
|
|
|
12
19
|
export const StoryGallery = ({ cdn, card }) => {
|
|
13
20
|
const { theme } = useContext(AppTheme);
|
|
14
|
-
const { COLORS, DARK_MODE } = theme;
|
|
21
|
+
const { COLORS, DARK_MODE, CAN_COPY_TEXT } = theme;
|
|
15
22
|
const galleryStyles = styles(theme);
|
|
16
23
|
const storyElements = card['story-elements'];
|
|
17
24
|
const [showModal, setShowModal] = useState(false);
|
|
@@ -20,34 +27,38 @@ export const StoryGallery = ({ cdn, card }) => {
|
|
|
20
27
|
|
|
21
28
|
const flatlistRef = useRef();
|
|
22
29
|
const [index, setIndex] = useState(0);
|
|
23
|
-
const totalSlides = card[
|
|
30
|
+
const totalSlides = card['story-elements']?.length;
|
|
24
31
|
const lastSlide = currentIndex + 1 === totalSlides;
|
|
25
32
|
const firstSlide = currentIndex === 0;
|
|
26
33
|
const [galleryLastImgUrl, setGalleryLastImageUrl] = useState('');
|
|
27
34
|
|
|
28
35
|
const onPressHandler = (index = 5) => {
|
|
29
|
-
setIndex(index)
|
|
36
|
+
setIndex(index);
|
|
30
37
|
setShowModal(true);
|
|
31
|
-
}
|
|
38
|
+
};
|
|
32
39
|
|
|
33
40
|
const moveNext = () => {
|
|
34
41
|
if (!lastSlide) {
|
|
35
|
-
flatlistRef.current.scrollToIndex({
|
|
42
|
+
flatlistRef.current.scrollToIndex({
|
|
43
|
+
index: Math.floor(Math.min(currentIndex + 1, totalSlides - 1)),
|
|
44
|
+
});
|
|
36
45
|
setCurrentTabIndex(currentIndex + 1);
|
|
37
46
|
}
|
|
38
47
|
};
|
|
39
48
|
|
|
40
49
|
const movePrev = () => {
|
|
41
50
|
if (!firstSlide) {
|
|
42
|
-
flatlistRef.current.scrollToIndex({
|
|
51
|
+
flatlistRef.current.scrollToIndex({
|
|
52
|
+
index: Math.ceil(Math.max(currentIndex - 1, 0)),
|
|
53
|
+
});
|
|
43
54
|
setCurrentTabIndex(Math.max(currentIndex - 1, 0));
|
|
44
55
|
}
|
|
45
56
|
};
|
|
46
57
|
|
|
47
58
|
const showArrow = (direction) => {
|
|
48
|
-
const arrowStyles = direction ===
|
|
49
|
-
const onPressHandler = direction ===
|
|
50
|
-
const iconName = direction ===
|
|
59
|
+
const arrowStyles = direction === 'left' ? galleryStyles.leftArrow : galleryStyles.rightArrow;
|
|
60
|
+
const onPressHandler = direction === 'left' ? movePrev : moveNext;
|
|
61
|
+
const iconName = direction === 'left' ? 'chevron-left' : 'chevron-right';
|
|
51
62
|
return (
|
|
52
63
|
<View style={arrowStyles}>
|
|
53
64
|
<TouchableOpacity onPress={onPressHandler}>
|
|
@@ -61,23 +72,26 @@ export const StoryGallery = ({ cdn, card }) => {
|
|
|
61
72
|
const xOffset = event.nativeEvent?.contentOffset?.x;
|
|
62
73
|
const contentWidth = event.nativeEvent?.contentSize?.width;
|
|
63
74
|
const layoutWidth = event.nativeEvent?.layoutMeasurement?.width;
|
|
64
|
-
const value =
|
|
65
|
-
const leftThreshold = contentWidth / (
|
|
66
|
-
const rightThreshold = contentWidth -
|
|
67
|
-
|
|
68
|
-
if
|
|
75
|
+
const value = xOffset / contentWidth;
|
|
76
|
+
const leftThreshold = contentWidth / (2 * totalSlides);
|
|
77
|
+
const rightThreshold = contentWidth - 1.5 * layoutWidth;
|
|
78
|
+
|
|
79
|
+
if (
|
|
80
|
+
leftThreshold <= xOffset
|
|
81
|
+
&& (layoutWidth > xOffset || rightThreshold > xOffset)
|
|
82
|
+
) {
|
|
69
83
|
setCurrentTabIndex(value * totalSlides);
|
|
70
|
-
} else if(xOffset < leftThreshold){
|
|
84
|
+
} else if (xOffset < leftThreshold) {
|
|
71
85
|
setCurrentTabIndex(0);
|
|
72
|
-
} else if(xOffset >= rightThreshold){
|
|
73
|
-
setCurrentTabIndex(totalSlides-1);
|
|
86
|
+
} else if (xOffset >= rightThreshold) {
|
|
87
|
+
setCurrentTabIndex(totalSlides - 1);
|
|
74
88
|
}
|
|
75
|
-
}
|
|
89
|
+
};
|
|
76
90
|
|
|
77
91
|
const closeModalHandler = () => {
|
|
78
92
|
setShowModal(false);
|
|
79
93
|
setCurrentTabIndex(0);
|
|
80
|
-
}
|
|
94
|
+
};
|
|
81
95
|
|
|
82
96
|
const renderItem = (item) => {
|
|
83
97
|
const data = {
|
|
@@ -85,20 +99,38 @@ export const StoryGallery = ({ cdn, card }) => {
|
|
|
85
99
|
slug: item.item['image-s3-key'],
|
|
86
100
|
metaData: item.item['image-metadata'],
|
|
87
101
|
};
|
|
88
|
-
|
|
102
|
+
const { title } = item.item;
|
|
103
|
+
const attribution = item.item['image-attribution'];
|
|
89
104
|
const imageUri = `${data?.cdn}/${data?.slug}`;
|
|
90
105
|
|
|
91
|
-
return
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
return (
|
|
107
|
+
<View style={galleryStyles.carouselContainer}>
|
|
108
|
+
<FastImage
|
|
109
|
+
source={{ uri: imageUri }}
|
|
110
|
+
resizeMode={FastImage.resizeMode.contain}
|
|
111
|
+
style={galleryStyles.carouselImage}
|
|
112
|
+
/>
|
|
113
|
+
<HTML
|
|
114
|
+
html={title}
|
|
115
|
+
textSelectable={CAN_COPY_TEXT}
|
|
116
|
+
key={Math.random()}
|
|
117
|
+
baseFontStyle={galleryStyles.titleText}
|
|
118
|
+
onLinkPress={(e, href) => {
|
|
119
|
+
Linking.openURL(href);
|
|
120
|
+
}}
|
|
121
|
+
/>
|
|
122
|
+
<HTML
|
|
123
|
+
html={attribution}
|
|
124
|
+
textSelectable={CAN_COPY_TEXT}
|
|
125
|
+
key={Math.random()}
|
|
126
|
+
baseFontStyle={galleryStyles.attributionText}
|
|
127
|
+
onLinkPress={(e, href) => {
|
|
128
|
+
Linking.openURL(href);
|
|
129
|
+
}}
|
|
130
|
+
/>
|
|
131
|
+
</View>
|
|
132
|
+
);
|
|
133
|
+
};
|
|
102
134
|
|
|
103
135
|
return (
|
|
104
136
|
<>
|
|
@@ -107,35 +139,54 @@ export const StoryGallery = ({ cdn, card }) => {
|
|
|
107
139
|
|
|
108
140
|
<View style={galleryStyles.imgContainer}>
|
|
109
141
|
{storyElements.map((element, index) => {
|
|
110
|
-
|
|
111
142
|
const data = {
|
|
112
143
|
cdn,
|
|
113
144
|
slug: element['image-s3-key'],
|
|
114
145
|
metaData: element['image-metadata'],
|
|
115
|
-
imageWidth: getScreenPercentageWidth(100),
|
|
116
146
|
};
|
|
117
147
|
|
|
118
|
-
if(storyElements.length >6 && index >= 5){
|
|
148
|
+
if (storyElements.length > 6 && index >= 5) {
|
|
119
149
|
const imageUri = `${data?.cdn}/${data?.slug}`;
|
|
120
|
-
if(galleryLastImgUrl === ''){
|
|
150
|
+
if (galleryLastImgUrl === '') {
|
|
121
151
|
setGalleryLastImageUrl(imageUri);
|
|
122
152
|
}
|
|
123
153
|
return null;
|
|
124
154
|
}
|
|
125
155
|
|
|
126
156
|
const style = galleryStyles.fullWidth;
|
|
127
|
-
return
|
|
128
|
-
|
|
129
|
-
|
|
157
|
+
return (
|
|
158
|
+
<TouchableOpacity>
|
|
159
|
+
<LightBoxImage
|
|
160
|
+
onClickHandler={onPressHandler}
|
|
161
|
+
hero={!!data.metaData['focus-point']}
|
|
162
|
+
key={Math.random()}
|
|
163
|
+
data={data}
|
|
164
|
+
additionalStyles={style}
|
|
165
|
+
elementType={card?.metadata?.type}
|
|
166
|
+
index={index}
|
|
167
|
+
/>
|
|
168
|
+
</TouchableOpacity>
|
|
169
|
+
);
|
|
130
170
|
})}
|
|
131
|
-
{storyElements && storyElements.length > 6 &&
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
171
|
+
{storyElements && storyElements.length > 6 && (
|
|
172
|
+
<TouchableOpacity
|
|
173
|
+
onPress={() => onPressHandler(5)}
|
|
174
|
+
style={[
|
|
175
|
+
galleryStyles.fullWidth,
|
|
176
|
+
galleryStyles.showMoreImageContainer,
|
|
177
|
+
]}
|
|
178
|
+
>
|
|
179
|
+
<FastImage
|
|
180
|
+
source={{ uri: galleryLastImgUrl }}
|
|
181
|
+
resizeMode={FastImage.resizeMode.cover}
|
|
182
|
+
style={galleryStyles.showMoreImage}
|
|
183
|
+
/>
|
|
184
|
+
<Text style={galleryStyles.showMoreText}>
|
|
185
|
+
+
|
|
186
|
+
{storyElements.length - 5}
|
|
187
|
+
</Text>
|
|
188
|
+
</TouchableOpacity>
|
|
189
|
+
)}
|
|
139
190
|
</View>
|
|
140
191
|
<Text style={galleryStyles.descText} lato>
|
|
141
192
|
{card.description}
|
|
@@ -151,34 +202,40 @@ export const StoryGallery = ({ cdn, card }) => {
|
|
|
151
202
|
>
|
|
152
203
|
<SafeAreaView style={galleryStyles.safeAreaView}>
|
|
153
204
|
<View style={galleryStyles.modalContainer}>
|
|
154
|
-
<TouchableOpacity onPress={closeModalHandler}>
|
|
205
|
+
<TouchableOpacity onPress={closeModalHandler}>
|
|
155
206
|
<View style={galleryStyles.close}>
|
|
156
|
-
<Icon
|
|
207
|
+
<Icon
|
|
208
|
+
name="times"
|
|
209
|
+
size={20}
|
|
210
|
+
color={DARK_MODE ? COLORS.BRAND_BLACK : COLORS.BRAND_WHITE}
|
|
211
|
+
/>
|
|
157
212
|
</View>
|
|
158
213
|
</TouchableOpacity>
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
214
|
+
<View style={galleryStyles.wrapper}>
|
|
215
|
+
<FlatList
|
|
216
|
+
ref={flatlistRef}
|
|
217
|
+
data={card['story-elements']}
|
|
218
|
+
renderItem={renderItem}
|
|
219
|
+
keyExtractor={(item) => item.id}
|
|
220
|
+
horizontal
|
|
221
|
+
extraData={currentIndex}
|
|
222
|
+
onScroll={handleScroll}
|
|
223
|
+
initialScrollIndex={index}
|
|
224
|
+
onScrollToIndexFailed={(info) => {
|
|
225
|
+
const wait = new Promise((resolve) => setTimeout(resolve, 500));
|
|
226
|
+
wait.then(() => {
|
|
227
|
+
flatlistRef.current?.scrollToIndex({
|
|
228
|
+
index: info.index,
|
|
229
|
+
animated: true,
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
}}
|
|
233
|
+
/>
|
|
234
|
+
|
|
235
|
+
{!firstSlide && showArrow('left')}
|
|
236
|
+
|
|
237
|
+
{!lastSlide && showArrow('right')}
|
|
238
|
+
</View>
|
|
182
239
|
</View>
|
|
183
240
|
</SafeAreaView>
|
|
184
241
|
</Modal>
|
|
@@ -1,131 +1,134 @@
|
|
|
1
1
|
import { StyleSheet, Dimensions } from 'react-native';
|
|
2
2
|
import { useContext } from 'react';
|
|
3
|
-
import { isTablet } from 'react-native-device-info';
|
|
4
3
|
import { AppTheme } from '../../utils';
|
|
5
4
|
|
|
6
|
-
|
|
7
5
|
export const styles = ({ FONT_SIZE }) => {
|
|
8
6
|
const { width: deviceWidth } = Dimensions.get('window');
|
|
9
7
|
const { theme } = useContext(AppTheme);
|
|
10
|
-
const { COLORS, DARK_MODE } = theme;
|
|
8
|
+
const { COLORS, DARK_MODE, FONT_FAMILY } = theme;
|
|
11
9
|
|
|
12
10
|
return StyleSheet.create({
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
11
|
+
container: {
|
|
12
|
+
width: '100%',
|
|
13
|
+
paddingHorizontal: 10,
|
|
14
|
+
},
|
|
15
|
+
imgContainer: {
|
|
16
|
+
width: '100%',
|
|
17
|
+
flexDirection: 'row',
|
|
18
|
+
flexWrap: 'wrap',
|
|
19
|
+
justifyContent: 'space-between',
|
|
20
|
+
},
|
|
21
|
+
halfWidth: {
|
|
22
|
+
width: (deviceWidth - 30) / 2,
|
|
23
|
+
height: 124,
|
|
24
|
+
},
|
|
25
|
+
fullWidth: {
|
|
26
|
+
width: (deviceWidth - 30) / 3,
|
|
27
|
+
height: (deviceWidth - 30) / 3,
|
|
28
|
+
marginVertical: 2.5,
|
|
29
|
+
},
|
|
30
|
+
descText: {
|
|
31
|
+
fontSize: FONT_SIZE.h2,
|
|
32
|
+
opacity: 0.8,
|
|
33
|
+
paddingTop: 10,
|
|
34
|
+
},
|
|
35
|
+
modalContainer: {
|
|
36
|
+
backgroundColor: DARK_MODE ? COLORS.MONO6 : COLORS.BRAND_BLACK,
|
|
37
|
+
flex: 1,
|
|
38
|
+
justifyContent: 'center',
|
|
39
|
+
},
|
|
40
|
+
safeAreaView: {
|
|
41
|
+
flex: 1,
|
|
42
|
+
backgroundColor: 'transparent',
|
|
43
|
+
},
|
|
44
|
+
close: {
|
|
45
|
+
justifyContent: 'flex-start',
|
|
46
|
+
padding: 10,
|
|
47
|
+
height: 40,
|
|
48
|
+
zIndex: 1,
|
|
49
|
+
marginTop: 25,
|
|
50
|
+
},
|
|
51
|
+
imageContainer: {
|
|
52
|
+
justifyContent: 'center',
|
|
53
|
+
alignItems: 'center',
|
|
54
|
+
width: '100%',
|
|
55
|
+
height: '100%',
|
|
56
|
+
},
|
|
57
|
+
portrait: {
|
|
58
|
+
width: '100%',
|
|
59
|
+
height: '80%',
|
|
60
|
+
},
|
|
61
|
+
wrapper: {
|
|
62
|
+
paddingHorizontal: 10,
|
|
63
|
+
flex: 1,
|
|
64
|
+
backgroundColor: 'black',
|
|
65
|
+
width: '100%',
|
|
66
|
+
},
|
|
67
|
+
titleText: {
|
|
68
|
+
fontWeight: 'normal',
|
|
69
|
+
fontSize: FONT_SIZE.h3,
|
|
70
|
+
opacity: 0.8,
|
|
71
|
+
color: 'white',
|
|
72
|
+
marginTop: 10,
|
|
73
|
+
marginHorizontal: 10,
|
|
74
|
+
fontFamily: FONT_FAMILY.secondary,
|
|
75
|
+
},
|
|
76
|
+
attributionText: {
|
|
77
|
+
fontWeight: 'normal',
|
|
78
|
+
marginBottom: 10,
|
|
79
|
+
fontSize: FONT_SIZE.h3,
|
|
80
|
+
opacity: 0.8,
|
|
81
|
+
color: 'white',
|
|
82
|
+
marginHorizontal: 10,
|
|
83
|
+
fontFamily: FONT_FAMILY.secondary,
|
|
84
|
+
},
|
|
85
|
+
leftArrow: {
|
|
86
|
+
position: 'absolute',
|
|
87
|
+
top: '46%',
|
|
88
|
+
right: '95%',
|
|
89
|
+
left: 20,
|
|
90
|
+
zIndex: 999,
|
|
91
|
+
width: 30,
|
|
92
|
+
height: 40,
|
|
93
|
+
backgroundColor: COLORS.TRANSPARENT_BLACK,
|
|
94
|
+
display: 'flex',
|
|
95
|
+
alignItems: 'center',
|
|
96
|
+
justifyContent: 'center',
|
|
97
|
+
},
|
|
98
|
+
rightArrow: {
|
|
99
|
+
position: 'absolute',
|
|
100
|
+
top: '46%',
|
|
101
|
+
left: '93%',
|
|
102
|
+
right: 20,
|
|
103
|
+
zIndex: 999,
|
|
104
|
+
width: 30,
|
|
105
|
+
height: 40,
|
|
106
|
+
backgroundColor: COLORS.TRANSPARENT_BLACK,
|
|
107
|
+
display: 'flex',
|
|
108
|
+
alignItems: 'center',
|
|
109
|
+
justifyContent: 'center',
|
|
110
|
+
},
|
|
111
|
+
carouselImage: {
|
|
112
|
+
width: '100%',
|
|
113
|
+
height: '80%',
|
|
114
|
+
},
|
|
115
|
+
carouselContainer: {
|
|
116
|
+
width: deviceWidth - 10,
|
|
117
|
+
margin: 10,
|
|
118
|
+
},
|
|
119
|
+
showMoreImageContainer: {
|
|
120
|
+
justifyContent: 'center',
|
|
121
|
+
alignItems: 'center',
|
|
122
|
+
},
|
|
123
|
+
showMoreImage: {
|
|
124
|
+
width: '100%',
|
|
125
|
+
height: '100%',
|
|
126
|
+
opacity: 0.5,
|
|
127
|
+
},
|
|
128
|
+
showMoreText: {
|
|
129
|
+
fontSize: 30,
|
|
130
|
+
position: 'absolute',
|
|
131
|
+
color: COLORS.BRAND_WHITE,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import PropTypes from
|
|
2
|
-
import React, { useContext, useRef, useState } from
|
|
3
|
-
import { TouchableOpacity, View } from
|
|
4
|
-
import { FlatList } from
|
|
5
|
-
import Icon from
|
|
6
|
-
import { AppTheme } from
|
|
7
|
-
import { Text } from
|
|
8
|
-
import { SlideshowStoryCard } from
|
|
9
|
-
import { storySlideshowStyles } from
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import React, { useContext, useRef, useState } from 'react';
|
|
3
|
+
import { TouchableOpacity, View } from 'react-native';
|
|
4
|
+
import { FlatList } from 'react-native-gesture-handler';
|
|
5
|
+
import Icon from 'react-native-vector-icons/AntDesign';
|
|
6
|
+
import { AppTheme } from '../../utils';
|
|
7
|
+
import { Text } from '../index';
|
|
8
|
+
import { SlideshowStoryCard } from '../SlideshowStoryCard';
|
|
9
|
+
import { storySlideshowStyles } from './styles';
|
|
10
10
|
|
|
11
11
|
export const StorySlideshow = ({ card, cdn }) => {
|
|
12
12
|
const { theme } = useContext(AppTheme);
|
|
@@ -16,13 +16,13 @@ export const StorySlideshow = ({ card, cdn }) => {
|
|
|
16
16
|
|
|
17
17
|
const flatlistRef = useRef();
|
|
18
18
|
|
|
19
|
-
const totalSlides = card[
|
|
19
|
+
const totalSlides = card['story-elements']?.length;
|
|
20
20
|
const lastSlide = currentIndex + 1 === totalSlides;
|
|
21
21
|
const firstSlide = currentIndex === 0;
|
|
22
22
|
|
|
23
23
|
const moveNext = () => {
|
|
24
24
|
if (!lastSlide) {
|
|
25
|
-
flatlistRef.current.scrollToIndex({ index: Math.floor(Math.min(currentIndex + 1, totalSlides - 1))});
|
|
25
|
+
flatlistRef.current.scrollToIndex({ index: Math.floor(Math.min(currentIndex + 1, totalSlides - 1)) });
|
|
26
26
|
setCurrentTabIndex(currentIndex + 1);
|
|
27
27
|
}
|
|
28
28
|
};
|
|
@@ -35,9 +35,8 @@ export const StorySlideshow = ({ card, cdn }) => {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
const showArrow = (direction) => {
|
|
38
|
-
const arrowStyles =
|
|
39
|
-
|
|
40
|
-
const onPressHandler = direction === "left" ? movePrev : moveNext;
|
|
38
|
+
const arrowStyles = direction === 'left' ? styles.leftArrow : styles.rightArrow;
|
|
39
|
+
const onPressHandler = direction === 'left' ? movePrev : moveNext;
|
|
41
40
|
|
|
42
41
|
return (
|
|
43
42
|
<View style={arrowStyles}>
|
|
@@ -53,27 +52,27 @@ export const StorySlideshow = ({ card, cdn }) => {
|
|
|
53
52
|
const contentWidth = event.nativeEvent?.contentSize?.width;
|
|
54
53
|
const layoutWidth = event.nativeEvent?.layoutMeasurement?.width;
|
|
55
54
|
const value = (xOffset / contentWidth);
|
|
56
|
-
const leftThreshold = contentWidth / (
|
|
57
|
-
const rightThreshold = contentWidth - (
|
|
55
|
+
const leftThreshold = contentWidth / (2 * totalSlides);
|
|
56
|
+
const rightThreshold = contentWidth - (1.5) * layoutWidth;
|
|
58
57
|
|
|
59
|
-
if((leftThreshold <= xOffset && (layoutWidth > xOffset || rightThreshold > xOffset
|
|
58
|
+
if ((leftThreshold <= xOffset && (layoutWidth > xOffset || rightThreshold > xOffset))) {
|
|
60
59
|
setCurrentTabIndex(value * totalSlides);
|
|
61
|
-
} else if(xOffset < leftThreshold){
|
|
60
|
+
} else if (xOffset < leftThreshold) {
|
|
62
61
|
setCurrentTabIndex(0);
|
|
63
|
-
} else if(xOffset >= rightThreshold){
|
|
64
|
-
setCurrentTabIndex(totalSlides-1);
|
|
62
|
+
} else if (xOffset >= rightThreshold) {
|
|
63
|
+
setCurrentTabIndex(totalSlides - 1);
|
|
65
64
|
}
|
|
66
|
-
}
|
|
65
|
+
};
|
|
67
66
|
|
|
68
67
|
return (
|
|
69
|
-
<View
|
|
68
|
+
<View>
|
|
70
69
|
<Text primary style={styles.titleText}>
|
|
71
70
|
{card.title}
|
|
72
71
|
</Text>
|
|
73
72
|
|
|
74
73
|
<FlatList
|
|
75
74
|
ref={flatlistRef}
|
|
76
|
-
data={card[
|
|
75
|
+
data={card['story-elements']}
|
|
77
76
|
renderItem={({ item }) => <SlideshowStoryCard card={item} cdn={cdn} />}
|
|
78
77
|
keyExtractor={(item) => item.id}
|
|
79
78
|
horizontal
|
|
@@ -81,9 +80,14 @@ export const StorySlideshow = ({ card, cdn }) => {
|
|
|
81
80
|
onScroll={handleScroll}
|
|
82
81
|
/>
|
|
83
82
|
|
|
84
|
-
{!firstSlide && showArrow(
|
|
83
|
+
{!firstSlide && showArrow('left')}
|
|
85
84
|
|
|
86
|
-
{!lastSlide && showArrow(
|
|
85
|
+
{!lastSlide && showArrow('right')}
|
|
87
86
|
</View>
|
|
88
87
|
);
|
|
89
88
|
};
|
|
89
|
+
|
|
90
|
+
StorySlideshow.propTypes = {
|
|
91
|
+
cdn: PropTypes.string,
|
|
92
|
+
card: PropTypes.object,
|
|
93
|
+
};
|
|
@@ -1,40 +1,36 @@
|
|
|
1
|
-
import { StyleSheet } from
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
2
|
|
|
3
|
-
export const storySlideshowStyles = ({ FONT_SIZE, COLORS }) =>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
alignItems: "center",
|
|
38
|
-
justifyContent: "center",
|
|
39
|
-
},
|
|
40
|
-
});
|
|
3
|
+
export const storySlideshowStyles = ({ FONT_SIZE, COLORS }) => StyleSheet.create({
|
|
4
|
+
titleText: {
|
|
5
|
+
fontWeight: 'normal',
|
|
6
|
+
marginBottom: 10,
|
|
7
|
+
fontSize: FONT_SIZE.h1,
|
|
8
|
+
opacity: 0.8,
|
|
9
|
+
},
|
|
10
|
+
leftArrow: {
|
|
11
|
+
position: 'absolute',
|
|
12
|
+
top: '46%',
|
|
13
|
+
right: '95%',
|
|
14
|
+
left: 20,
|
|
15
|
+
zIndex: 999,
|
|
16
|
+
width: 30,
|
|
17
|
+
height: 40,
|
|
18
|
+
backgroundColor: COLORS.TRANSPARENT_BLACK,
|
|
19
|
+
display: 'flex',
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
},
|
|
23
|
+
rightArrow: {
|
|
24
|
+
position: 'absolute',
|
|
25
|
+
top: '46%',
|
|
26
|
+
left: '93%',
|
|
27
|
+
right: 20,
|
|
28
|
+
zIndex: 999,
|
|
29
|
+
width: 30,
|
|
30
|
+
height: 40,
|
|
31
|
+
backgroundColor: COLORS.TRANSPARENT_BLACK,
|
|
32
|
+
display: 'flex',
|
|
33
|
+
alignItems: 'center',
|
|
34
|
+
justifyContent: 'center',
|
|
35
|
+
},
|
|
36
|
+
});
|
package/src/utils/imageUtils.js
CHANGED
|
@@ -29,9 +29,11 @@ export function getImageQuality() {
|
|
|
29
29
|
if (NETWORK_TYPE) {
|
|
30
30
|
if (NETWORK_TYPE === 'wifi') {
|
|
31
31
|
return 100;
|
|
32
|
-
}
|
|
32
|
+
}
|
|
33
|
+
if (NETWORK_TYPE === '4g') {
|
|
33
34
|
return 85;
|
|
34
|
-
}
|
|
35
|
+
}
|
|
36
|
+
if (NETWORK_TYPE === '3g') {
|
|
35
37
|
return 50;
|
|
36
38
|
}
|
|
37
39
|
}
|
|
@@ -124,13 +126,13 @@ export const getCustomResolutionImageURL = (props, customAspectRatio) => {
|
|
|
124
126
|
const { IMAGE_QUALITY } = theme;
|
|
125
127
|
|
|
126
128
|
const {
|
|
127
|
-
|
|
129
|
+
metaData, slug, imageWidth, cdn,
|
|
128
130
|
} = props;
|
|
129
131
|
const image = new FocusedImage(slug, metaData);
|
|
130
132
|
|
|
131
133
|
const imageCdn = cdn || 'https://www.quintype.com';
|
|
132
|
-
return `${imageCdn}/${image.path(customAspectRatio
|
|
134
|
+
return `${imageCdn}/${image.path(customAspectRatio, {
|
|
133
135
|
w: getPixelRatioForDevice(imageWidth) || Math.round(deviceWidth),
|
|
134
136
|
q: IMAGE_QUALITY,
|
|
135
137
|
})}`;
|
|
136
|
-
}
|
|
138
|
+
};
|