@quintype/native-components 2.21.0-beta.2 → 2.21.0-beta.3
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 +14 -0
- package/README.md +20 -1
- package/package.json +5 -3
- package/src/Icons/FallBackIcon/index.js +7 -15
- package/src/components/Html/index.js +26 -0
- package/src/components/Rating/index.js +50 -0
- package/src/components/Rating/styles.js +21 -0
- package/src/components/ResponsiveImage/index.js +1 -1
- package/src/components/Story/index.js +38 -8
- package/src/components/Story/styles.js +3 -0
- package/src/components/StoryHeader/index.js +14 -8
- package/src/components/StoryHeader/styles.js +0 -1
- package/src/components/StoryTitle/styles.js +3 -3
- package/src/components/YouTubePlayer/index.js +39 -1
- package/src/utils/colorUtils.js +0 -1
- package/src/utils/story.js +35 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
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.32](https://github.com/quintype/native-components/compare/v2.20.31...v2.20.32) (2024-06-05)
|
|
6
|
+
|
|
7
|
+
### [2.20.31](https://github.com/quintype/native-components/compare/v2.20.30...v2.20.31) (2024-06-04)
|
|
8
|
+
|
|
9
|
+
### [2.20.30](https://github.com/quintype/native-components/compare/v2.20.29...v2.20.30) (2024-06-04)
|
|
10
|
+
|
|
11
|
+
### [2.20.29](https://github.com/quintype/native-components/compare/v2.20.28...v2.20.29) (2024-06-04)
|
|
12
|
+
|
|
13
|
+
### [2.20.28](https://github.com/quintype/native-components/compare/v2.20.27...v2.20.28) (2024-05-17)
|
|
14
|
+
|
|
15
|
+
### [2.20.27](https://github.com/quintype/native-components/compare/v2.20.26...v2.20.27) (2024-05-17)
|
|
16
|
+
|
|
17
|
+
### [2.20.26](https://github.com/quintype/native-components/compare/v2.20.25...v2.20.26) (2024-05-17)
|
|
18
|
+
|
|
5
19
|
### [2.20.25](https://github.com/quintype/native-components/compare/v2.20.24...v2.20.25) (2024-03-14)
|
|
6
20
|
|
|
7
21
|
|
package/README.md
CHANGED
|
@@ -4,7 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
`$ npm install @quintype/native-components --save`
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Creating and installing a beta version
|
|
8
|
+
|
|
9
|
+
### Publishing a version with beta tag:
|
|
10
|
+
1. Add, commit and push beta changes on a new branch.
|
|
11
|
+
2. Run `npm i --legacy-peer-deps` (Using **node@16.19.0**, **npm@8.19.3**)
|
|
12
|
+
3. Run `npm cache clean --force` in case the above command fails.
|
|
13
|
+
4. Create a tag by running `npm version 2.21.0-beta.0` (add **\`-beta.*iteration*\`** (where ***iteration*** can just be incremented (+1) for subsequent beta-versions on the same development branch)
|
|
14
|
+
5. Publish the tag by running `npm publish --tag beta`
|
|
15
|
+
6. Make sure to commit and push the new beta versioning changes.
|
|
16
|
+
|
|
17
|
+
### Installing a version with beta tag on host app:
|
|
18
|
+
npm install @quintype/native-components@beta
|
|
19
|
+
|
|
20
|
+
### Note:
|
|
21
|
+
- `prePublishOnly` script that was in use before is incompatible with recent node/npm versions. Hence `standard-version-release.sh` is not used.
|
|
22
|
+
- Revert `"version"` changes from `package.json` before creating PR (for merging to `master`).
|
|
23
|
+
- Access all versions [here](https://www.npmjs.com/package/@quintype/native-components?activeTab=versions).
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
## Linking
|
|
8
27
|
|
|
9
28
|
This library has both js only as well as native components. Please check the instructions for the respective components for more details.
|
|
10
29
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quintype/native-components",
|
|
3
|
-
"version": "2.21.0-beta.
|
|
3
|
+
"version": "2.21.0-beta.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"react-native-image-pan-zoom": "^2.1.12",
|
|
21
21
|
"react-native-lightbox": "0.8.1",
|
|
22
22
|
"react-native-render-html": "^4.2.3",
|
|
23
|
-
"react-native-share": "^8.1.0"
|
|
23
|
+
"react-native-share": "^8.1.0",
|
|
24
|
+
"react-native-star-rating-widget": "^1.7.3"
|
|
24
25
|
},
|
|
25
26
|
"peerDependencies": {
|
|
26
27
|
"@react-navigation/native": ">=6.1.17",
|
|
@@ -31,7 +32,8 @@
|
|
|
31
32
|
"react-native-pdf": ">=6.7.4",
|
|
32
33
|
"react-native-blob-util": ">=6.7.4",
|
|
33
34
|
"react-native-webview": ">=11.0.0",
|
|
34
|
-
"react-native-vector-icons": "^10.0.0"
|
|
35
|
+
"react-native-vector-icons": "^10.0.0",
|
|
36
|
+
"react-native-linear-gradient": "^2.8.3"
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
39
|
"@babel/core": "^7.11.1",
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import Icon from "react-native-vector-icons/
|
|
3
|
-
import
|
|
1
|
+
import React, { useContext } from "react";
|
|
2
|
+
import Icon from "react-native-vector-icons/FontAwesome";
|
|
3
|
+
import { AppTheme } from "../../utils";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
export const FallbackIcon = () => {
|
|
6
|
+
const { theme } = useContext(AppTheme);
|
|
7
|
+
const { COLORS } = theme;
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
<Icon
|
|
9
|
-
name="images"
|
|
10
|
-
size={size}
|
|
11
|
-
color={color}
|
|
12
|
-
/>
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
FallbackIcon.propTypes = {
|
|
16
|
-
size: PropTypes.number,
|
|
17
|
-
color: PropTypes.string,
|
|
9
|
+
return <Icon name="image" size={25} color={COLORS.MONO4} />;
|
|
18
10
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { TouchableOpacity, View, I18nManager, StyleSheet, Linking } from "react-native";
|
|
2
|
+
import HTML from "react-native-render-html";
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
const CustomHtmlParser = ({ text, textStyle={}, containerStyle={} }) => {
|
|
6
|
+
const textStyles = StyleSheet.flatten([
|
|
7
|
+
textStyle,
|
|
8
|
+
{
|
|
9
|
+
writingDirection: I18nManager.isRTL ? "rtl" : "ltr",
|
|
10
|
+
},
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<HTML
|
|
15
|
+
html={text}
|
|
16
|
+
key={Math.random()}
|
|
17
|
+
baseFontStyle={textStyles}
|
|
18
|
+
onLinkPress={(evt, href) => {
|
|
19
|
+
Linking.openURL(href);
|
|
20
|
+
}}
|
|
21
|
+
containerStyle={containerStyle}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default CustomHtmlParser;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import React, { useContext } from 'react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { StarRatingDisplay } from 'react-native-star-rating-widget';
|
|
5
|
+
import { Text } from '../Text';
|
|
6
|
+
import { ratingStyles } from './styles';
|
|
7
|
+
import { AppTheme } from '../../utils';
|
|
8
|
+
|
|
9
|
+
export const RatingLayout = ({ reviewTitle, ratingValue, ratingLabel }) => {
|
|
10
|
+
const { theme } = useContext(AppTheme);
|
|
11
|
+
const {
|
|
12
|
+
COLORS, FONT_FAMILY, FONT_SIZE,
|
|
13
|
+
} = theme;
|
|
14
|
+
const styles = ratingStyles(COLORS, FONT_SIZE, FONT_FAMILY);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<View style={styles.container}>
|
|
18
|
+
{reviewTitle && (
|
|
19
|
+
<Text
|
|
20
|
+
style={styles.reviewTitle}
|
|
21
|
+
primary
|
|
22
|
+
>
|
|
23
|
+
{reviewTitle}
|
|
24
|
+
</Text>
|
|
25
|
+
)}
|
|
26
|
+
{ratingValue && (
|
|
27
|
+
<View style={styles.child}>
|
|
28
|
+
<Text
|
|
29
|
+
style={styles.ratingLabel}
|
|
30
|
+
>
|
|
31
|
+
{`${ratingLabel}/5`}
|
|
32
|
+
</Text>
|
|
33
|
+
<StarRatingDisplay
|
|
34
|
+
rating={ratingValue}
|
|
35
|
+
starSize={FONT_SIZE.title}
|
|
36
|
+
color={COLORS.REVIEW_STAR_COLOR ?? '#F5A623'}
|
|
37
|
+
style={styles.starContiner}
|
|
38
|
+
starStyle={styles.starStyle}
|
|
39
|
+
/>
|
|
40
|
+
</View>
|
|
41
|
+
)}
|
|
42
|
+
</View>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
RatingLayout.propTypes = {
|
|
47
|
+
reviewTitle: PropTypes.string.isRequired,
|
|
48
|
+
ratingValue: PropTypes.number.isRequired,
|
|
49
|
+
ratingLabel: PropTypes.string.isRequired,
|
|
50
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export const ratingStyles = (COLORS, FONT_SIZE, FONT_FAMILY) => StyleSheet.create({
|
|
4
|
+
container: { marginLeft: 10, marginTop: 10 },
|
|
5
|
+
reviewTitle: {
|
|
6
|
+
fontSize: FONT_SIZE.h2,
|
|
7
|
+
lineHeight: 24,
|
|
8
|
+
fontFamily: FONT_FAMILY.primary,
|
|
9
|
+
color: COLORS.BRAND_BLACK,
|
|
10
|
+
marginBottom: 7,
|
|
11
|
+
},
|
|
12
|
+
child: { display: 'flex', flexDirection: 'row', alignItems: 'center' },
|
|
13
|
+
ratingLabel: {
|
|
14
|
+
fontSize: FONT_SIZE.h2,
|
|
15
|
+
lineHeight: 24,
|
|
16
|
+
fontFamily: FONT_FAMILY.secondary,
|
|
17
|
+
color: COLORS.BRAND_BLACK,
|
|
18
|
+
},
|
|
19
|
+
starContainer: { marginLeft: 10 },
|
|
20
|
+
starStyle: { marginHorizontal: 0 },
|
|
21
|
+
});
|
|
@@ -33,7 +33,7 @@ const ResponsiveImageBase = (props) => {
|
|
|
33
33
|
|
|
34
34
|
const placeholderStyle = {
|
|
35
35
|
...StyleSheet.absoluteFillObject,
|
|
36
|
-
backgroundColor: CustomFallBackBackground
|
|
36
|
+
backgroundColor: (CustomFallBackIcon && CustomFallBackBackground) ?? COLORS.MONO6,
|
|
37
37
|
justifyContent: 'center',
|
|
38
38
|
alignItems: 'center',
|
|
39
39
|
};
|
|
@@ -13,6 +13,8 @@ import { ClockIcon } from '../../Icons/ClockIcon';
|
|
|
13
13
|
import { storyStyles } from './styles';
|
|
14
14
|
import { isStoryFree, mutateDataBeforeAccess, getFirstVideoElement } from '../../utils/story';
|
|
15
15
|
import { isMiddleIndexOfArray } from '../../utils/arrayUtils';
|
|
16
|
+
import LinearGradient from "react-native-linear-gradient";
|
|
17
|
+
import { hexToRgb } from '@quintype/native-components/src/utils/colorUtils';
|
|
16
18
|
|
|
17
19
|
const getLiveBlogTimeStamp = (card, DATE_FORMAT, share, styles, locale) => {
|
|
18
20
|
const slug = `?cardId=${card.id}`;
|
|
@@ -76,7 +78,7 @@ const getStoryCards = (
|
|
|
76
78
|
getAd,
|
|
77
79
|
locale,
|
|
78
80
|
) => cards.map((card, index, source) => (
|
|
79
|
-
|
|
81
|
+
<View key={card?.id}>
|
|
80
82
|
{isLiveBlog
|
|
81
83
|
&& getLiveBlogTimeStamp(card, DATE_FORMAT, share, styles, locale)}
|
|
82
84
|
|
|
@@ -106,7 +108,6 @@ const getStoryCards = (
|
|
|
106
108
|
{/* ^ In the case of a story having just 1 card,
|
|
107
109
|
requesting mid-content-Ad if there are > 1 story-elements in that card
|
|
108
110
|
(> 2 story-elements in case of video story since the 1st story-element gets rendered in header). */}
|
|
109
|
-
|
|
110
111
|
<StoryContent
|
|
111
112
|
testID={contentTestID}
|
|
112
113
|
key={storyElement?.id}
|
|
@@ -143,15 +144,16 @@ export const Story = ({
|
|
|
143
144
|
storyHasAccess = 'loading',
|
|
144
145
|
currentLayout,
|
|
145
146
|
getAd,
|
|
147
|
+
linkedStories,
|
|
148
|
+
showWall,
|
|
149
|
+
userObjectLength,
|
|
150
|
+
numberOfVisibleStoryCard
|
|
146
151
|
}) => {
|
|
147
152
|
const { theme } = useContext(AppTheme);
|
|
148
|
-
const { COLORS, FONT_SIZE, locale } = theme;
|
|
153
|
+
const { COLORS, FONT_SIZE, locale, DARK_MODE } = theme;
|
|
149
154
|
const styles = storyStyles(COLORS, FONT_SIZE);
|
|
155
|
+
const cards = story?.cards ?? [];
|
|
150
156
|
|
|
151
|
-
const {
|
|
152
|
-
cards = [],
|
|
153
|
-
'linked-stories': linkedStories,
|
|
154
|
-
} = mutateDataBeforeAccess(story, storyHasAccess);
|
|
155
157
|
|
|
156
158
|
const firstVideoElement = story['story-template'] === STORY_TYPES.VIDEO_STORY
|
|
157
159
|
? getFirstVideoElement(cards)
|
|
@@ -184,8 +186,28 @@ export const Story = ({
|
|
|
184
186
|
checkStoryAccess(story);
|
|
185
187
|
}, []);
|
|
186
188
|
|
|
189
|
+
useEffect(()=>{
|
|
190
|
+
if(userObjectLength){
|
|
191
|
+
checkStoryAccess(story);
|
|
192
|
+
}
|
|
193
|
+
},[userObjectLength])
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
const GradientView = () => {
|
|
197
|
+
return (
|
|
198
|
+
<LinearGradient
|
|
199
|
+
colors={[
|
|
200
|
+
DARK_MODE ? hexToRgb("#252525", 0) : hexToRgb(COLORS.BRAND_WHITE, 0),
|
|
201
|
+
DARK_MODE ? hexToRgb("#252525", 1) : hexToRgb(COLORS.BRAND_WHITE, 1),
|
|
202
|
+
]}
|
|
203
|
+
style={{ height: 200}}
|
|
204
|
+
></LinearGradient>
|
|
205
|
+
);
|
|
206
|
+
};
|
|
207
|
+
|
|
187
208
|
return (
|
|
188
209
|
<>
|
|
210
|
+
<View>
|
|
189
211
|
<StoryHeader
|
|
190
212
|
firstVideoElement={firstVideoElement}
|
|
191
213
|
testID={headerTestID}
|
|
@@ -195,6 +217,8 @@ export const Story = ({
|
|
|
195
217
|
onSectionPress={onSectionPress}
|
|
196
218
|
/>
|
|
197
219
|
|
|
220
|
+
|
|
221
|
+
|
|
198
222
|
{getAd()}
|
|
199
223
|
|
|
200
224
|
{getStoryCards(
|
|
@@ -218,7 +242,13 @@ export const Story = ({
|
|
|
218
242
|
locale,
|
|
219
243
|
)}
|
|
220
244
|
|
|
221
|
-
{
|
|
245
|
+
{(!(isStoryFree(story) === 0 || storyHasAccess === "granted") && showWall) && <View style={styles.overlay} >
|
|
246
|
+
<GradientView />
|
|
247
|
+
</View>
|
|
248
|
+
}
|
|
249
|
+
</View>
|
|
250
|
+
{accessComponent(story, storyHasAccess, showWall)}
|
|
251
|
+
|
|
222
252
|
|
|
223
253
|
{shouldShowComments()}
|
|
224
254
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import React, { useContext } from 'react';
|
|
4
|
-
import { TouchableOpacity, View } from 'react-native';
|
|
4
|
+
import { TouchableOpacity, View, I18nManager,StyleSheet } from 'react-native';
|
|
5
5
|
import {
|
|
6
6
|
getImageMetadata,
|
|
7
7
|
getScreenPercentageWidth,
|
|
@@ -11,13 +11,16 @@ import {
|
|
|
11
11
|
} from '../../utils';
|
|
12
12
|
import { STORY_TYPES } from '../../utils/story-types';
|
|
13
13
|
import {
|
|
14
|
-
AuthorRow, ResponsiveImage, StoryTitle, Text,
|
|
14
|
+
AuthorRow, ResponsiveImage, StoryText, StoryTitle, Text,
|
|
15
15
|
} from '../index';
|
|
16
16
|
import { YouTubePlayer } from '../YouTubePlayer';
|
|
17
17
|
import { storyHeaderStyles } from './styles';
|
|
18
18
|
import { COMP_CONTENT_CONSTANTS } from '../../constants/component-constants/content-constants/constants';
|
|
19
19
|
|
|
20
20
|
import { DailyMotionPlayer } from '../DailyMotionPlayer';
|
|
21
|
+
import { RatingLayout } from '../Rating';
|
|
22
|
+
import CustomHtmlParser from './../Html/index';
|
|
23
|
+
|
|
21
24
|
const getHeroImage = (cdn, story) => {
|
|
22
25
|
const imageSlug = story['hero-image-s3-key'];
|
|
23
26
|
if (!imageSlug) return null;
|
|
@@ -33,7 +36,8 @@ const getHeroImage = (cdn, story) => {
|
|
|
33
36
|
};
|
|
34
37
|
|
|
35
38
|
const getHeroComponent = (props) => {
|
|
36
|
-
const { story = {},
|
|
39
|
+
const { story = {},firstVideoElement, cdn } = props;
|
|
40
|
+
|
|
37
41
|
switch (story['story-template']) {
|
|
38
42
|
case STORY_TYPES.VIDEO_STORY: {
|
|
39
43
|
if (!firstVideoElement) return null;
|
|
@@ -60,12 +64,12 @@ const getHeroComponent = (props) => {
|
|
|
60
64
|
};
|
|
61
65
|
|
|
62
66
|
export const StoryHeader = (props) => {
|
|
63
|
-
const { story } = props;
|
|
67
|
+
const { story, firstVideoElement } = props;
|
|
64
68
|
const sectionData = get(story, ['sections', 0], {});
|
|
65
69
|
const { theme } = useContext(AppTheme);
|
|
66
70
|
|
|
67
71
|
const {
|
|
68
|
-
COLORS, locale, FONT_FAMILY, DATE_TIME_FORMAT,
|
|
72
|
+
COLORS, locale, FONT_FAMILY, DATE_TIME_FORMAT, FONT_SIZE
|
|
69
73
|
} = theme;
|
|
70
74
|
|
|
71
75
|
const DATE_FORMAT = `${DATE_TIME_FORMAT.dateFormat} ${DATE_TIME_FORMAT.timeFormat}`;
|
|
@@ -73,7 +77,8 @@ export const StoryHeader = (props) => {
|
|
|
73
77
|
const caption = story['hero-image-caption'];
|
|
74
78
|
const attribution = story['hero-image-attribution'];
|
|
75
79
|
const isPremiumStory = story['access'] === 'subscription';
|
|
76
|
-
|
|
80
|
+
const reviewTitle = story['metadata'] && story['metadata']['review-title'];
|
|
81
|
+
const reviewData = story['metadata'] && story['metadata']['review-rating'];
|
|
77
82
|
|
|
78
83
|
const showAttribution = () => {
|
|
79
84
|
if (!caption && !attribution) {
|
|
@@ -81,8 +86,8 @@ export const StoryHeader = (props) => {
|
|
|
81
86
|
}
|
|
82
87
|
return (
|
|
83
88
|
<View style={styles.captionContainerStyle}>
|
|
84
|
-
<
|
|
85
|
-
<
|
|
89
|
+
{caption && !firstVideoElement && <CustomHtmlParser text={caption} textStyle={styles.captionStyle}/>}
|
|
90
|
+
{attribution && !firstVideoElement && <CustomHtmlParser text={attribution} textStyle={styles.attributionStyle}/>}
|
|
86
91
|
</View>
|
|
87
92
|
);
|
|
88
93
|
};
|
|
@@ -128,6 +133,7 @@ export const StoryHeader = (props) => {
|
|
|
128
133
|
cdn={props.cdn}
|
|
129
134
|
readtime={story['read-time']}
|
|
130
135
|
/>
|
|
136
|
+
{reviewTitle && <RatingLayout reviewTitle={reviewTitle} ratingValue={reviewData?.value} ratingLabel={reviewData?.label}/>}
|
|
131
137
|
</View>
|
|
132
138
|
);
|
|
133
139
|
};
|
|
@@ -17,9 +17,9 @@ export const storyTitleStyles = ({ COLORS, FONT_SIZE }) => StyleSheet.create({
|
|
|
17
17
|
marginTop: 15,
|
|
18
18
|
paddingVertical: 5,
|
|
19
19
|
},
|
|
20
|
-
premiumIcon : {
|
|
21
|
-
paddingLeft:10,
|
|
22
|
-
marginRight:-5,
|
|
20
|
+
premiumIcon : {
|
|
21
|
+
paddingLeft:10,
|
|
22
|
+
marginRight:-5,
|
|
23
23
|
borderWidth:1
|
|
24
24
|
}
|
|
25
25
|
});
|
|
@@ -10,12 +10,50 @@ export const YouTubePlayer = ({ card = {} }) => {
|
|
|
10
10
|
const windowWidth = Dimensions.get("window").width;
|
|
11
11
|
const styles = webviewStyles(windowWidth);
|
|
12
12
|
|
|
13
|
+
const getYoutubeIframe = (ytEmbedURL) => {
|
|
14
|
+
const videoId = ytEmbedURL.split('/').pop();
|
|
15
|
+
const width = windowWidth - 20;
|
|
16
|
+
const height = (9/16)*(windowWidth - 20);
|
|
17
|
+
const htmlContent = `
|
|
18
|
+
<iframe
|
|
19
|
+
width="1280"
|
|
20
|
+
height="720"
|
|
21
|
+
src="https://www.youtube.com/embed/${videoId}"
|
|
22
|
+
frameborder="0"
|
|
23
|
+
allow="accelerometer;
|
|
24
|
+
autoplay;
|
|
25
|
+
clipboard-write;
|
|
26
|
+
encrypted-media;
|
|
27
|
+
gyroscope;
|
|
28
|
+
picture-in-picture;
|
|
29
|
+
web-share"
|
|
30
|
+
referrerpolicy="strict-origin-when-cross-origin"
|
|
31
|
+
allowfullscreen
|
|
32
|
+
></iframe>`;
|
|
33
|
+
|
|
34
|
+
return `
|
|
35
|
+
<html>
|
|
36
|
+
<head>
|
|
37
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
38
|
+
<style>
|
|
39
|
+
iframe{
|
|
40
|
+
width:${width}px;
|
|
41
|
+
height:${height}px;
|
|
42
|
+
}
|
|
43
|
+
</style>
|
|
44
|
+
</head>
|
|
45
|
+
<body>
|
|
46
|
+
${htmlContent}
|
|
47
|
+
</body>
|
|
48
|
+
</html>`;
|
|
49
|
+
}
|
|
50
|
+
|
|
13
51
|
return (
|
|
14
52
|
<View style={styles.container} testID="youtube-player-id">
|
|
15
53
|
<WebView
|
|
16
54
|
mediaPlaybackRequiresUserAction
|
|
17
55
|
style={styles.webViewContainer}
|
|
18
|
-
source={{
|
|
56
|
+
source={{ html: getYoutubeIframe(ytEmbedURL), baseUrl:'https://www.youtube.com'}}
|
|
19
57
|
javaScriptEnabled
|
|
20
58
|
domStorageEnabled
|
|
21
59
|
startInLoadingState
|
package/src/utils/colorUtils.js
CHANGED
|
@@ -2,7 +2,6 @@ export const hexToRgb = (hex, alpha=1) => {
|
|
|
2
2
|
let rgbCode = hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(m, r, g, b) => '#' + r + r + g + g + b + b)
|
|
3
3
|
.substring(1).match(/.{2}/g)
|
|
4
4
|
.map(x => parseInt(x, 16));
|
|
5
|
-
console.log('risi - color', `rgb(${rgbCode[0]}, ${rgbCode[1]}, ${rgbCode[2]}, ${alpha})`)
|
|
6
5
|
return `rgba(${rgbCode[0]}, ${rgbCode[1]}, ${rgbCode[2]}, ${alpha})`;
|
|
7
6
|
}
|
|
8
7
|
|
package/src/utils/story.js
CHANGED
|
@@ -38,25 +38,54 @@ export const getFirstVideoElement = (cards) => cards
|
|
|
38
38
|
return acc;
|
|
39
39
|
}, [])
|
|
40
40
|
.find(
|
|
41
|
-
(
|
|
42
|
-
|| (type === 'jsembed' && subtype === 'dailymotion-video'),
|
|
41
|
+
(ele) => ele?.type === 'youtube-video'
|
|
42
|
+
|| (ele?.type === 'jsembed' && ele?.subtype === 'dailymotion-video'),
|
|
43
43
|
) || {};
|
|
44
44
|
|
|
45
|
-
export const mutateDataBeforeAccess = (item, storyHasAccess) => {
|
|
45
|
+
export const mutateDataBeforeAccess = (item, storyHasAccess, visibleCardCountForBlockedStories) => {
|
|
46
46
|
if (isStoryFree(item) === 0 || storyHasAccess === 'granted') {
|
|
47
47
|
return item;
|
|
48
48
|
}
|
|
49
49
|
if (storyHasAccess !== 'loading' && storyHasAccess === 'granted') {
|
|
50
50
|
return item;
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
const firstCardObject = get(item, ['cards', 0], {});
|
|
52
|
+
const firstCardObject = get(item, ['cards', 2], {});
|
|
54
53
|
const firstCardElement = get(firstCardObject, !STORY_TYPES.VIDEO_STORY && ['story-elements', 0], {});
|
|
54
|
+
let visibleContentsForBlockedStory = [];
|
|
55
|
+
let showBlockingWall = false;
|
|
56
|
+
let visibleStoryCount = 0;
|
|
57
|
+
if(!visibleCardCountForBlockedStories){
|
|
58
|
+
return {
|
|
59
|
+
cards: visibleContentsForBlockedStory,
|
|
60
|
+
showBlockingWall: true
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if(item.cards && item.cards.length > 0){
|
|
65
|
+
for(let i = 0; i < item.cards.length; i++){
|
|
66
|
+
let storyElement = [];
|
|
67
|
+
for(let j=0; j<item.cards[i]['story-elements'].length; j++){
|
|
68
|
+
let tempStoryElement = item.cards[i]['story-elements'][j];
|
|
69
|
+
if(visibleStoryCount < visibleCardCountForBlockedStories-1){
|
|
70
|
+
storyElement.push(tempStoryElement);
|
|
71
|
+
visibleStoryCount++;
|
|
72
|
+
} else {
|
|
73
|
+
showBlockingWall = true;
|
|
74
|
+
storyElement.push(tempStoryElement);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
visibleContentsForBlockedStory.push({...item.cards[i],'story-elements' : storyElement});
|
|
80
|
+
if(showBlockingWall) break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
55
83
|
|
|
56
84
|
return {
|
|
57
85
|
...item,
|
|
58
86
|
...{
|
|
59
|
-
cards:
|
|
87
|
+
cards: visibleContentsForBlockedStory,
|
|
60
88
|
},
|
|
89
|
+
showBlockingWall
|
|
61
90
|
};
|
|
62
91
|
};
|