@quintype/native-components 2.28.5-beta.1 → 2.28.5-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quintype/native-components",
3
- "version": "2.28.5-beta.1",
3
+ "version": "2.28.5-beta.2",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -0,0 +1,141 @@
1
+ import React, { memo } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { useProgress, usePlaybackState, State } from "react-native-track-player";
4
+ import { TouchableOpacity, ActivityIndicator, View, ViewPropTypes } from "react-native";
5
+ import Icon from "react-native-vector-icons/AntDesign";
6
+ import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
7
+ import { playerStyles } from "./styles";
8
+ import Slider from "@react-native-community/slider";
9
+ import { AppTheme } from "../../utils";
10
+ import { useContext } from "react";
11
+ import {ResponsiveHeight, ResponsiveWidth} from '../../utils/screenUtils'
12
+ import { Text } from '../index';
13
+
14
+ const ProgressBar = (props) => {
15
+ const progress = useProgress();
16
+ const { theme } = useContext(AppTheme);
17
+ const { COLORS} = theme;
18
+ const {progressCompleted, progressBar } = playerStyles();
19
+ const stylesWithFlexValue = (flex, styles) => ({ flex: flex, ...styles });
20
+
21
+ return (
22
+ <View style={progressBar}>
23
+ <Slider
24
+ style={stylesWithFlexValue(progress.position, progressCompleted)}
25
+ minimumValue={0}
26
+ maximumValue={progress.duration}
27
+ minimumTrackTintColor={COLORS.BRAND_BLACK}
28
+ maximumTrackTintColor={COLORS.MONO_6}
29
+ value={progress.position}
30
+ onValueChange={(val) => props.seekTo(val)}
31
+ thumbTintColor={COLORS.BRAND_BLACK}
32
+ thumbStyle={{size:50}}
33
+ />
34
+ </View>
35
+ );
36
+ };
37
+
38
+ export const ControlButton = ({ iconName, onPress, FONT_SIZE }) => {
39
+ const { controlButtonContainer, controlButton } = playerStyles();
40
+
41
+ return (
42
+ <TouchableOpacity style={controlButtonContainer} onPress={onPress} >
43
+ <Icon name={iconName} size={FONT_SIZE.title} style={controlButton} />
44
+ </TouchableOpacity>
45
+ );
46
+ };
47
+
48
+ const PlayerBase = (props) => {
49
+ const { theme } = useContext(AppTheme);
50
+ const { COLORS,translate, FONT_SIZE, DARK_MODE } = theme;
51
+ const { card, container, subContainer, playerControlStyle, playbackSpeedText, playerContainer } = playerStyles();
52
+ const { style, onTogglePlayback, testID, seekTo, rewindOrForward, isFinishedPlaying, restart, closeButtonHandler } = props;
53
+
54
+ const playbackState = usePlaybackState();
55
+
56
+ const getControlButton = (state) => {
57
+ switch (state?.state) {
58
+ case State.Buffering:
59
+ return <ActivityIndicator size="large" />;
60
+ case State.Playing:
61
+ return (
62
+ <ControlButton
63
+ iconName={"pausecircleo"}
64
+ onPress={() => {
65
+ onTogglePlayback();
66
+ }}
67
+ FONT_SIZE={FONT_SIZE}
68
+ />
69
+ );
70
+ default:
71
+ return <ControlButton iconName={"playcircleo"} onPress={onTogglePlayback} FONT_SIZE={FONT_SIZE}/>;
72
+ }
73
+ };
74
+
75
+ function formatNumber(num) {
76
+ return num % 1 === 0 ? num.toFixed(1) : num.toString();
77
+ }
78
+
79
+ return (
80
+ <View testID={testID}>
81
+ <View
82
+ style={container}
83
+ >
84
+ <Text
85
+ style={subContainer}
86
+ >
87
+ {translate("Listen to this article")}
88
+ </Text>
89
+ <View style={playerControlStyle}>
90
+ <TouchableOpacity style={{ marginHorizontal: 10 }} onPress={() => rewindOrForward("rewind")}>
91
+ <MaterialCommunityIcons color={COLORS.BRAND_BLACK} name={"rewind-10"} size={FONT_SIZE.title} />
92
+ </TouchableOpacity>
93
+ <TouchableOpacity style={{ marginHorizontal: 10 }} onPress={() => rewindOrForward("forward")}>
94
+ <MaterialCommunityIcons color={COLORS.BRAND_BLACK} name={"fast-forward-10"} size={FONT_SIZE.title} />
95
+ </TouchableOpacity>
96
+ <TouchableOpacity
97
+ style={playbackSpeedText}
98
+ onPress={() => props.setShowModal(true)}
99
+ >
100
+ <Text style={{ fontSize: FONT_SIZE.h3, color: DARK_MODE ? COLORS.BRAND_WHITE : COLORS.BRAND_BLACK}}>{`${formatNumber(props.audioRate)}x`}</Text>
101
+ </TouchableOpacity>
102
+ </View>
103
+ </View>
104
+
105
+ <View
106
+ style={[card,style]}
107
+ >
108
+ <View style={playerContainer}>
109
+ { isFinishedPlaying ?
110
+ <ControlButton iconName={"reload1"} onPress={() => restart()} FONT_SIZE={FONT_SIZE} /> :
111
+ getControlButton(playbackState)}
112
+ </View>
113
+ <ProgressBar seekTo={seekTo} />
114
+ <MaterialCommunityIcons
115
+ color={COLORS.BRAND_BLACK}
116
+ onPress={()=>closeButtonHandler()}
117
+ size={FONT_SIZE.title}
118
+ name="close"
119
+ />
120
+ </View>
121
+ </View>
122
+ );
123
+ };
124
+
125
+ ControlButton.propTypes = {
126
+ iconName: PropTypes.string.isRequired,
127
+ onPress: PropTypes.func.isRequired,
128
+ testID: PropTypes.string,
129
+ };
130
+
131
+ PlayerBase.propTypes = {
132
+ style: ViewPropTypes.style,
133
+ onTogglePlayback: PropTypes.func.isRequired,
134
+ testID: PropTypes.string,
135
+ };
136
+
137
+ PlayerBase.defaultProps = {
138
+ style: {},
139
+ };
140
+
141
+ export const Player = memo(PlayerBase);
@@ -0,0 +1,70 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { AppTheme } from "../../utils";
3
+ import { useContext } from "react";
4
+ import { ResponsiveHeight, ResponsiveWidth } from "../../utils/screenUtils";
5
+ export const playerStyles = () => {
6
+ const { theme } = useContext(AppTheme);
7
+ const { COLORS, DARK_MODE,FONT_SIZE } = theme;
8
+
9
+ return StyleSheet.create({
10
+ container:{
11
+ display: "flex",
12
+ flexDirection: "row",
13
+ justifyContent: "space-between",
14
+ marginHorizontal: 10,
15
+ alignItems: "flex-start",
16
+ marginTop: 15,
17
+ marginBottom: 16,
18
+ },
19
+ subContainer:{
20
+ fontSize: FONT_SIZE.h2,
21
+ color: COLORS.BRAND_BLACK,
22
+ },
23
+ playerControlStyle:{ display: "flex", flexDirection: "row", alignItems: "center" },
24
+ playbackSpeedText:{
25
+ backgroundColor: COLORS.MONO5,
26
+ minWidth: ResponsiveWidth(13),
27
+ height: ResponsiveHeight(3),
28
+ borderRadius: 5,
29
+ alignItems: "center",
30
+ justifyContent: "center",
31
+ marginHorizontal: 10,
32
+ },
33
+ card: {
34
+ backgroundColor: DARK_MODE ? COLORS.MONO6 : COLORS.BRAND_WHITE,
35
+ elevation: 10,
36
+ shadowColor: COLORS.BRAND_BLACK,
37
+ shadowOffset: { width: 0, height: -1 },
38
+ shadowOpacity: 0.1,
39
+ shadowRadius: 1,
40
+ width: "95%",
41
+ minHeight: 70,
42
+ borderBottomWidth: 2,
43
+ borderColor: COLORS.MONO6,
44
+ marginBottom: 7,
45
+ display: "flex",
46
+ flexDirection: "row",
47
+ alignItems: "center",
48
+ marginHorizontal: ResponsiveWidth(2.5),
49
+ borderRadius:5
50
+ },
51
+ playerContainer:{width:ResponsiveWidth(12),display:'flex', flexDirection:'row',alignItems:'center',justifyContent:'center'},
52
+ controlButton: {
53
+ alignItems: "center",
54
+ color: COLORS.BRAND_BLACK,
55
+ },
56
+ controlButtonContainer: {
57
+ alignItems: "center",
58
+ flex: 1,
59
+ },
60
+ controls: {},
61
+ progressBar: { width: ResponsiveWidth(70), marginHorizontal: ResponsiveWidth(1) },
62
+ progressCompleted: {
63
+ backgroundColor: DARK_MODE ? COLORS.MONO6 : COLORS.BRAND_WHITE,
64
+ },
65
+ progressRemaining: {
66
+ backgroundColor: COLORS.BRAND_BLACK,
67
+ opacity: 0.1,
68
+ },
69
+ });
70
+ };
@@ -1,19 +1,27 @@
1
1
  import { hexToRgb } from '@quintype/native-components/src/utils/colorUtils';
2
2
  import PropTypes from 'prop-types';
3
- import React, { useContext, useEffect } from 'react';
4
- import { I18nManager, View } from 'react-native';
3
+ import React, { useContext, useEffect, useState, useFocusEffect } from 'react';
4
+ import { I18nManager, TouchableOpacity, View, StyleSheet, AppState } from 'react-native';
5
5
  import LinearGradient from "react-native-linear-gradient";
6
6
  import { ClockIcon } from '../../Icons/ClockIcon';
7
7
  import { AppTheme, getTimeInFormat } from '../../utils';
8
8
  import { isMiddleIndexOfArray } from '../../utils/arrayUtils';
9
- import { getFirstVideoElement, isStoryFree } from '../../utils/story';
9
+ import { getFirstVideoElement, isStoryFree, getStoryHeadline } from '../../utils/story';
10
+ import { getImageSlug } from '../../utils';
10
11
  import { STORY_TYPES } from '../../utils/story-types';
11
12
  import { FBCommentsRow } from '../FBCommentsRow';
12
13
  import { StoryContent } from '../StoryContent';
13
14
  import { StoryHeader } from '../StoryHeader';
14
15
  import { TagsRow } from '../TagsRow/TagsRow';
15
16
  import { ShareButton, Text } from '../index';
16
- import { storyStyles } from './styles';
17
+ import { storyStyles, modalStyles } from './styles';
18
+ import { Player } from '../AudioPlayer';
19
+ import Icon from 'react-native-vector-icons/AntDesign';
20
+ import TrackPlayer, { usePlaybackState, Capability, State, AppKilledPlaybackBehavior, useProgress } from "react-native-track-player";
21
+ import MaterialIcon from "react-native-vector-icons/MaterialCommunityIcons";
22
+ import FontAwesomeIcon from "react-native-vector-icons/FontAwesome";
23
+
24
+ import Modal from 'react-native-modal';
17
25
 
18
26
  const getLiveBlogTimeStamp = (card, DATE_FORMAT, story, styles, locale) => {
19
27
  const slug = `?cardId=${card.id}`;
@@ -140,12 +148,151 @@ export const Story = ({
140
148
  linkedStories,
141
149
  showWall,
142
150
  userObjectLength,
143
- numberOfVisibleStoryCard
151
+ numberOfVisibleStoryCard,
152
+ audioS3Key,
153
+ ttsButtonState,
154
+ setShowTTSPlayer,
155
+ gaTrigerredTTS
144
156
  }) => {
145
157
  const { theme } = useContext(AppTheme);
146
- const { COLORS, FONT_SIZE, locale, DARK_MODE } = theme;
147
- const styles = storyStyles(COLORS, FONT_SIZE);
158
+ const { COLORS, FONT_SIZE, locale, DARK_MODE,translate } = theme;
159
+ const styles = storyStyles(COLORS, FONT_SIZE, DARK_MODE);
160
+ const Modalstyles = modalStyles(COLORS, FONT_SIZE, DARK_MODE);
148
161
  const cards = story?.cards ?? [];
162
+ const [showModal, setShowModal] = useState(false);
163
+ const [audioRate, setAudioRate] = useState(1);
164
+ const playbackState = usePlaybackState();
165
+ const progress = useProgress();
166
+ const [isFinishedPlaying, setFinishedPlaying] = useState(false);
167
+
168
+
169
+ const setup = async () => {
170
+ //If TrackPlayer is not initialized, initialize it
171
+ try{
172
+ let activeTrack = await TrackPlayer.getActiveTrack();
173
+ } catch(err){
174
+ await TrackPlayer.setupPlayer({});
175
+ }
176
+
177
+ await TrackPlayer.updateOptions({
178
+ capabilities: [Capability.Play, Capability.Pause, Capability.Stop],
179
+ compactCapabilities: [Capability.Play, Capability.Pause],
180
+ notificationCapabilities: [Capability.Play, Capability.Pause, Capability.Stop],
181
+ });
182
+ };
183
+
184
+ const addTrack = async () => {
185
+ setFinishedPlaying(false)
186
+ let activeTrack = await TrackPlayer.getActiveTrack();
187
+ const storyAudioURL = `${cdn}/${audioS3Key}`;
188
+
189
+ if (!activeTrack || activeTrack?.id !== audioS3Key) {
190
+ await TrackPlayer.reset();
191
+ const headline = getStoryHeadline(story);
192
+
193
+ await TrackPlayer.add({
194
+ id: audioS3Key,
195
+ url: storyAudioURL,
196
+ title: headline,
197
+ album: cdn + "/" + getImageSlug(story),
198
+ artwork: cdn + "/" + getImageSlug(story),
199
+ });
200
+ }
201
+ };
202
+
203
+ const initialSetup = async () => {
204
+ await setup();
205
+ await addTrack();
206
+ };
207
+
208
+ React.useEffect(() => {
209
+ const unsubscribe = navigation.addListener('blur', async() => {
210
+ await TrackPlayer.pause();
211
+ });
212
+
213
+ const unsubscribe2 = navigation.addListener('focus', async() => {
214
+ addTrack();
215
+ })
216
+
217
+ const appStateListener = AppState.addEventListener('change', async (nextAppState) => {
218
+ if (nextAppState !== 'active') {
219
+ await TrackPlayer.pause();
220
+ }
221
+
222
+ });
223
+
224
+ return () => {
225
+ unsubscribe();
226
+ unsubscribe2();
227
+ };
228
+ }, [navigation]);
229
+
230
+
231
+
232
+ const resetPlayer = async () => {
233
+ setAudioRate(1);
234
+ setShowTTSPlayer(false);
235
+
236
+ await TrackPlayer.stop();
237
+ await TrackPlayer.setRate(1);
238
+ };
239
+
240
+ useEffect(() => {
241
+ return async() => await TrackPlayer.pause();
242
+ }, []);
243
+
244
+ useEffect(()=>{
245
+ if(progress?.duration < progress.position + 1 && progress.position !== 0){
246
+ setFinishedPlaying(true);
247
+ }
248
+ },[progress])
249
+
250
+
251
+
252
+ useEffect(() => {
253
+ if (audioS3Key) {
254
+ initialSetup();
255
+ }
256
+ }, [audioS3Key]);
257
+
258
+
259
+ const restartPlayer = async () => {
260
+ setFinishedPlaying(false);
261
+ await TrackPlayer.seekTo(0);
262
+ await TrackPlayer.play();
263
+ }
264
+
265
+ const togglePlayback = async () => {
266
+ console.log('risi - tts toggle playback', playbackState.state, TrackPlayer)
267
+ if (playbackState?.state === State.Playing) {
268
+ await TrackPlayer.pause();
269
+ } else {
270
+ await TrackPlayer.play();
271
+ }
272
+ };
273
+ const rewindOrForward = async (type) => {
274
+ const duration = await TrackPlayer.getProgress();
275
+
276
+ if (type === "rewind") {
277
+ await TrackPlayer.seekTo(duration.position - 10);
278
+ } else {
279
+ await TrackPlayer.seekTo(duration.position + 10);
280
+ }
281
+ };
282
+
283
+ const updateSpeedRate = async (rate) => {
284
+ await TrackPlayer.setRate(rate);
285
+ setAudioRate(rate);
286
+ setShowModal(false);
287
+ };
288
+
289
+ useEffect(()=>{
290
+ if(ttsButtonState && storyHasAccess === 'granted' && !showPlayer){
291
+ setShowPlayer(true)
292
+ togglePlayback()
293
+
294
+ }
295
+ },[ttsButtonState])
149
296
 
150
297
 
151
298
  const firstVideoElement = story['story-template'] === STORY_TYPES.VIDEO_STORY
@@ -198,6 +345,28 @@ export const Story = ({
198
345
  );
199
346
  };
200
347
 
348
+ const [showPlayer, setShowPlayer] = useState(false);
349
+ const closeButtonHandler = async() =>{
350
+ setFinishedPlaying(false);
351
+ setShowTTSPlayer(false);
352
+ setShowPlayer(false);
353
+ try{
354
+ await TrackPlayer.seekTo(0);
355
+ await resetPlayer();
356
+ }catch(err) {
357
+ console.log(err)
358
+ }
359
+ }
360
+
361
+ const ModalContent = ({rate, updateSpeedRate}) => {
362
+ return <Text
363
+ onPress={() => updateSpeedRate(rate)}
364
+ style={styles.textStyle}
365
+ >
366
+ {rate}
367
+ </Text>
368
+ }
369
+
201
370
  return (
202
371
  <>
203
372
  <View>
@@ -209,7 +378,33 @@ export const Story = ({
209
378
  onAuthorPress={onAuthorPress}
210
379
  onSectionPress={onSectionPress}
211
380
  />
212
-
381
+ { storyHasAccess === 'granted' && audioS3Key && (!showPlayer ?
382
+ (<TouchableOpacity onPress={async()=>{
383
+ gaTrigerredTTS({ slug: story.slug });
384
+ setShowPlayer(true)
385
+ await togglePlayback()
386
+ }}
387
+ style={styles.ttsStoryButtonStyle}
388
+ >
389
+ <MaterialIcon name='account-voice' size={FONT_SIZE.h2} color={COLORS.BRAND_BLACK}/>
390
+ <Text style={styles.ttsTextStyle}>{translate('Listen to this article')}</Text>
391
+ </TouchableOpacity>) :
392
+ (<View
393
+ style={styles.ttsPlayerContainer}
394
+ >
395
+ <Player
396
+ onTogglePlayback={togglePlayback}
397
+ seekTo={TrackPlayer.seekTo}
398
+ rewindOrForward={rewindOrForward}
399
+ setShowTTSPlayer={setShowPlayer}
400
+ setShowModal={setShowModal}
401
+ audioRate={audioRate}
402
+ resetPlayer={resetPlayer}
403
+ isFinishedPlaying={isFinishedPlaying}
404
+ closeButtonHandler={closeButtonHandler}
405
+ restart={restartPlayer}
406
+ />
407
+ </View>))}
213
408
 
214
409
 
215
410
  {getAd()}
@@ -247,10 +442,39 @@ export const Story = ({
247
442
  <View>
248
443
  <TagsRow tags={story.tags} onPress={onTagsPress} />
249
444
  </View>
445
+ <Modal
446
+ isVisible={showModal}
447
+ transparent={true}
448
+ onBackdropPress={() => setShowModal(false)}
449
+ style={Modalstyles.modalContainer}
450
+ swipeDirection="down"
451
+ onSwipeComplete={() => setShowModal(false)}
452
+ >
453
+ <View style={[Modalstyles.modalContent, styles.modalBackgound]}>
454
+ <View style={Modalstyles.header}>
455
+ <Text style={[Modalstyles.title, styles.textStyle]}>{translate("Playback Speed")}</Text>
456
+ <TouchableOpacity onPress={() => setShowModal(false)}>
457
+ <MaterialIcon name="close" size={25} color={styles?.textStyle?.color} />
458
+ </TouchableOpacity>
459
+ </View>
460
+ <View style={Modalstyles.modalBody}>
461
+ <ModalContent rate={0.25} updateSpeedRate={updateSpeedRate}/>
462
+ <ModalContent rate={0.5} updateSpeedRate={updateSpeedRate}/>
463
+ <ModalContent rate={0.75} updateSpeedRate={updateSpeedRate}/>
464
+ <ModalContent rate={1} updateSpeedRate={updateSpeedRate}/>
465
+ <ModalContent rate={1.25} updateSpeedRate={updateSpeedRate}/>
466
+ <ModalContent rate={1.55} updateSpeedRate={updateSpeedRate}/>
467
+ <ModalContent rate={1.75} updateSpeedRate={updateSpeedRate}/>
468
+ <ModalContent rate={2} updateSpeedRate={updateSpeedRate}/>
469
+ </View>
470
+ </View>
471
+ </Modal>
250
472
  </>
251
473
  );
252
474
  };
253
475
 
476
+
477
+
254
478
  Story.propTypes = {
255
479
  story: PropTypes.any.isRequired,
256
480
  cdn: PropTypes.string.isRequired,
@@ -1,6 +1,6 @@
1
1
  import { StyleSheet } from 'react-native';
2
2
 
3
- export const storyStyles = (COLORS, FONT_SIZE) => StyleSheet.create({
3
+ export const storyStyles = (COLORS, FONT_SIZE, DARK_MODE) => StyleSheet.create({
4
4
  container: {
5
5
  padding: 10,
6
6
  flexDirection: 'row',
@@ -39,5 +39,81 @@ export const storyStyles = (COLORS, FONT_SIZE) => StyleSheet.create({
39
39
  },
40
40
  overlay:{
41
41
  marginTop:-220
42
- }
42
+ },
43
+ modalBackgound: {
44
+ backgroundColor: COLORS.BRAND_WHITE,
45
+ position:'absolute',
46
+ bottom:0,
47
+ width:'100%',
48
+
49
+ },
50
+ textStyle: {
51
+ color: COLORS.BRAND_BLACK,
52
+ marginVertical: 10,
53
+ fontSize: FONT_SIZE.h3
54
+ },
55
+ ttsStoryButtonStyle:{
56
+ flexDirection:'row',
57
+ marginLeft:10,
58
+ alignItems:'center',
59
+ padding:10,
60
+ borderRadius:35,
61
+ paddingLeft:15,
62
+ alignSelf:'flex-start',
63
+ backgroundColor:COLORS.MONO6,
64
+ backgroundColor: DARK_MODE ? COLORS.MONO6 : COLORS.BRAND_WHITE,
65
+ elevation: 5,
66
+ shadowColor: COLORS.BRAND_BLACK,
67
+ shadowOffset: { width: 0, height: -1 },
68
+ shadowOpacity: 0.1,
69
+ shadowRadius: 1,
70
+ borderWidth:1,
71
+ borderColor: COLORS.MONO6,
72
+ marginBottom: 7},
73
+ ttsTextStyle:{marginLeft:10, fontSize:FONT_SIZE.h3, color:COLORS.BRAND_BLACK},
74
+ ttsPlayerContainer:{
75
+ width: "100%",
76
+ alignSelf: "center",
77
+ zIndex: 1,
78
+ marginBottom: 5,
79
+ marginVertical:10,
80
+
81
+ }
43
82
  });
83
+
84
+ export const modalStyles = (COLORS, FONT_SIZE, DARK_MODE) => StyleSheet.create({
85
+ container: {
86
+ flex: 1,
87
+ justifyContent: "center",
88
+ alignItems: "center",
89
+ backgroundColor:'green'
90
+ },
91
+ modalContainer: {
92
+ justifyContent: "flex-end",
93
+ margin: 0,
94
+ position:'absolute',
95
+ bottom:0,
96
+ width:'100%',
97
+ },
98
+ modalContent: {
99
+ borderTopLeftRadius: 15,
100
+ borderTopRightRadius: 15,
101
+ padding: 32,
102
+ },
103
+ header: {
104
+ flexDirection: "row",
105
+ justifyContent: "space-between",
106
+ alignItems: "center",
107
+ borderBottomWidth: 1,
108
+ borderBottomColor: COLORS.MONO5,
109
+ paddingBottom: 10,
110
+ },
111
+ title: {
112
+ fontSize: 18,
113
+ fontWeight: "bold",
114
+ },
115
+ modalBody: {
116
+ marginTop: 15,
117
+ fontSize: 16,
118
+ },
119
+ })
@@ -0,0 +1,26 @@
1
+ import get from "lodash/get";
2
+ import { useNavigationState } from "@react-navigation/native";
3
+ import { Dimensions } from "react-native";
4
+
5
+ export const getScreenCount = (screenName) => {
6
+ /* Note: To figure out if there are screen instances in the stack */
7
+ const navigationState = useNavigationState((state) => state) || {};
8
+ return get(navigationState, ["routes"], []).reduce((acc, route) => {
9
+ if (route.name === screenName) {
10
+ acc = acc + 1;
11
+ }
12
+ return acc;
13
+ }, 0);
14
+ };
15
+
16
+ export const ResponsiveHeight = (height) => {
17
+ const deviceHeight = Dimensions.get("window").height;
18
+ const responsiveHeight = (deviceHeight * height) / 1000;
19
+ return responsiveHeight;
20
+ };
21
+
22
+ export const ResponsiveWidth = (width) => {
23
+ const deviceWidth = Dimensions.get("window").width;
24
+ const responsiveWidth = (deviceWidth * width) / 1000;
25
+ return responsiveWidth;
26
+ };