Merge pull request 'Video Details -- UI w/ mocked data' (#136) from loewy/session-details into master
Reviewed-on: railbird/railbird-mobile#136
This commit is contained in:
commit
a47fb5fed7
@ -19,7 +19,7 @@
|
|||||||
"jest": {
|
"jest": {
|
||||||
"preset": "jest-expo",
|
"preset": "jest-expo",
|
||||||
"transformIgnorePatterns": [
|
"transformIgnorePatterns": [
|
||||||
"node_modules/(?!((jest-)?react-native|@react-native(-community)?|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|react-native-svg-charts|d3-path)/)"
|
"node_modules/(?!((jest-)?react-native|@react-native(-community)?|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|react-native-svg-charts|d3-path|expo-constants|expo-modules-core)/)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -57,6 +57,7 @@
|
|||||||
"react-native-dotenv": "^3.4.9",
|
"react-native-dotenv": "^3.4.9",
|
||||||
"react-native-dropdown-picker": "^5.4.6",
|
"react-native-dropdown-picker": "^5.4.6",
|
||||||
"react-native-fs": "^2.20.0",
|
"react-native-fs": "^2.20.0",
|
||||||
|
"react-native-modal": "^13.0.1",
|
||||||
"react-native-reanimated": "^3.6.2",
|
"react-native-reanimated": "^3.6.2",
|
||||||
"react-native-safe-area-context": "^4.8.2",
|
"react-native-safe-area-context": "^4.8.2",
|
||||||
"react-native-screens": "~3.22.0",
|
"react-native-screens": "~3.22.0",
|
||||||
|
42
src/component/headers/back-header.tsx
Normal file
42
src/component/headers/back-header.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { NavigationProp } from "@react-navigation/native";
|
||||||
|
import React from "react";
|
||||||
|
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
||||||
|
import { shadows } from "../../styles";
|
||||||
|
|
||||||
|
type BackHeaderProps = {
|
||||||
|
navigation: NavigationProp<any>; // TODO: #135 should use a RootStackParamList
|
||||||
|
title: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const BackHeader: React.FC<BackHeaderProps> = ({ navigation, title }) => {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
accessibilityLabel="Go back"
|
||||||
|
accessibilityRole="button"
|
||||||
|
>
|
||||||
|
<Text style={styles.text}>{`< ${title}`}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
backgroundColor: "white",
|
||||||
|
zIndex: 100,
|
||||||
|
...shadows.standard,
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
padding: 10,
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "500",
|
||||||
|
color: "black",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BackHeader;
|
34
src/component/image/image-with-fallback.tsx
Normal file
34
src/component/image/image-with-fallback.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React, { memo, useState } from "react";
|
||||||
|
import { Image, ImageStyle, StyleProp } from "react-native";
|
||||||
|
|
||||||
|
type ImageWithFallbackProps = {
|
||||||
|
source: { uri: string };
|
||||||
|
fallbackSource: { uri: string };
|
||||||
|
style?: StyleProp<ImageStyle>;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* A React component that displays an image with a fallback option.
|
||||||
|
* If the primary image fails to load, it will display a fallback image instead.
|
||||||
|
*
|
||||||
|
* @param {Object} source - The source of the primary image.
|
||||||
|
* @param {Object} fallbackSource - The source of the fallback image. Should be an asset rather than loaded from an endpoint.
|
||||||
|
* @param {StyleProp<ImageStyle>} style - Optional. The style to apply to the image. It can be any valid React Native style object.
|
||||||
|
* @returns {React.ReactElement} A React element representing the image with fallback.
|
||||||
|
*/
|
||||||
|
const ImageWithFallback: React.FC<ImageWithFallbackProps> = memo(
|
||||||
|
({ source, fallbackSource, style }) => {
|
||||||
|
const [imageSource, setImageSource] = useState(source);
|
||||||
|
|
||||||
|
const handleError = () => {
|
||||||
|
if (fallbackSource) {
|
||||||
|
setImageSource(fallbackSource);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return <Image source={imageSource} style={style} onError={handleError} />;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
ImageWithFallback.displayName = "ImageWithFallback";
|
||||||
|
|
||||||
|
export default ImageWithFallback;
|
34
src/component/video-details/video-details-header.tsx
Normal file
34
src/component/video-details/video-details-header.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { StyleSheet, Text, View } from "react-native";
|
||||||
|
|
||||||
|
// Type assumes preformatted date
|
||||||
|
type SessionHeaderProps = {
|
||||||
|
sessionTitle: string;
|
||||||
|
date: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SessionHeader: React.FC<SessionHeaderProps> = ({
|
||||||
|
sessionTitle,
|
||||||
|
date,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<View style={styles.headerSection}>
|
||||||
|
<Text style={styles.header}>{sessionTitle}</Text>
|
||||||
|
<Text>{date}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
headerSection: {
|
||||||
|
paddingHorizontal: 38,
|
||||||
|
paddingTop: 17,
|
||||||
|
paddingBottom: 14,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default SessionHeader;
|
49
src/component/video-details/video-stat-list.tsx
Normal file
49
src/component/video-details/video-stat-list.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { StyleProp, StyleSheet, Text, View, ViewStyle } from "react-native";
|
||||||
|
import { borders } from "../../styles";
|
||||||
|
|
||||||
|
type StatItem = {
|
||||||
|
title: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type StatListProps = {
|
||||||
|
items: StatItem[];
|
||||||
|
style?: StyleProp<ViewStyle>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const StatList: React.FC<StatListProps> = ({ items, style }) => {
|
||||||
|
return (
|
||||||
|
<View style={[styles.container, style]}>
|
||||||
|
{items.map((item, index) => (
|
||||||
|
<View key={`${item.title}-${index}`} style={styles.item}>
|
||||||
|
<Text style={styles.title}>{item.title}</Text>
|
||||||
|
<Text style={styles.value}>{item.value}</Text>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 5,
|
||||||
|
},
|
||||||
|
item: {
|
||||||
|
marginBottom: 10,
|
||||||
|
...borders.dottedLeftBorder,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 15,
|
||||||
|
color: "grey",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
fontSize: 28,
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default StatList;
|
@ -4,7 +4,7 @@ import { Image } from "react-native";
|
|||||||
import CameraScreen from "../component/recording/camera";
|
import CameraScreen from "../component/recording/camera";
|
||||||
import Profile from "../screens/profile";
|
import Profile from "../screens/profile";
|
||||||
import RecordingDetails from "../screens/recording-stack/recording-details";
|
import RecordingDetails from "../screens/recording-stack/recording-details";
|
||||||
import Video from "../screens/video-stack/video-detail";
|
import Video from "../screens/video-stack/video-details";
|
||||||
import VideoFeed from "../screens/video-stack/video-feed";
|
import VideoFeed from "../screens/video-stack/video-feed";
|
||||||
import { tabIconColors } from "../styles";
|
import { tabIconColors } from "../styles";
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ export default function Tabs(): React.JSX.Element {
|
|||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="VideoStack"
|
name="VideoStack"
|
||||||
component={VideoTabStack}
|
component={VideoTabStack}
|
||||||
options={{ tabBarLabel: "Video" }}
|
options={{ tabBarLabel: "Feed" }}
|
||||||
/>
|
/>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="RecordingStack"
|
name="RecordingStack"
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import { StyleSheet, View } from "react-native";
|
|
||||||
import {
|
|
||||||
graph_data_two_measures,
|
|
||||||
line_chart_two_y_data,
|
|
||||||
} from "../../../test/mock/charts/mock-data";
|
|
||||||
import BarGraph from "../../component/charts/bar-graph/bar-graph";
|
|
||||||
import ChartContainer from "../../component/charts/container/chart-container";
|
|
||||||
import LineGraph from "../../component/charts/line-graph/line-graph";
|
|
||||||
|
|
||||||
export default function VideoScreen() {
|
|
||||||
return (
|
|
||||||
<View style={StyleSheet.absoluteFill}>
|
|
||||||
<ChartContainer data={line_chart_two_y_data} ChartComponent={LineGraph} />
|
|
||||||
<ChartContainer
|
|
||||||
data={graph_data_two_measures}
|
|
||||||
ChartComponent={BarGraph}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
119
src/screens/video-stack/video-details.tsx
Normal file
119
src/screens/video-stack/video-details.tsx
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { ScrollView, StyleSheet, Text, View } from "react-native";
|
||||||
|
import {
|
||||||
|
graph_data_two_measures,
|
||||||
|
mock_session_details,
|
||||||
|
} from "../../../test/mock/charts/mock-data";
|
||||||
|
import BarGraph from "../../component/charts/bar-graph/bar-graph";
|
||||||
|
import ChartContainer from "../../component/charts/container/chart-container";
|
||||||
|
import ImageWithFallback from "../../component/image/image-with-fallback";
|
||||||
|
import StatList from "../../component/video-details/video-stat-list";
|
||||||
|
|
||||||
|
// TODO: #134 remove Session when data piped through
|
||||||
|
// Splash should be an asset we use if an Image failed to load
|
||||||
|
import Session from "../../assets/sample_session.png";
|
||||||
|
import Splash from "../../assets/splash.png";
|
||||||
|
import BackHeader from "../../component/headers/back-header";
|
||||||
|
import SessionHeader from "../../component/video-details/video-details-header";
|
||||||
|
import { borders, colors } from "../../styles";
|
||||||
|
|
||||||
|
export default function VideoDetails({ navigation }) {
|
||||||
|
// TODO: #134 Remove mock destructure block when data is piped through from BE
|
||||||
|
const {
|
||||||
|
sessionTitle,
|
||||||
|
date,
|
||||||
|
timePlayed,
|
||||||
|
medianRun,
|
||||||
|
makeRate,
|
||||||
|
shotPacing,
|
||||||
|
gameType,
|
||||||
|
notes,
|
||||||
|
} = mock_session_details;
|
||||||
|
|
||||||
|
const leftColumnStats = [
|
||||||
|
{ title: "TIME PLAYED", value: timePlayed },
|
||||||
|
{ title: "MAKE RATE", value: makeRate },
|
||||||
|
];
|
||||||
|
|
||||||
|
const rightColumnStats = [
|
||||||
|
{ title: "MEDIAN RUN", value: medianRun },
|
||||||
|
{ title: "SHOT PACING", value: shotPacing },
|
||||||
|
];
|
||||||
|
// End mock destructure
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<BackHeader navigation={navigation} title="Go Back" />
|
||||||
|
<ScrollView
|
||||||
|
showsVerticalScrollIndicator={false}
|
||||||
|
contentContainerStyle={styles.scrollContainer}
|
||||||
|
>
|
||||||
|
<SessionHeader sessionTitle={sessionTitle} date={date} />
|
||||||
|
<ImageWithFallback
|
||||||
|
// TODO: #134 when data comes from be needs to be passed as source={{ uri: image }}
|
||||||
|
source={Session}
|
||||||
|
fallbackSource={Splash}
|
||||||
|
style={styles.image}
|
||||||
|
/>
|
||||||
|
<View style={styles.statsContainer}>
|
||||||
|
<StatList items={leftColumnStats} style={styles.statColumn} />
|
||||||
|
<StatList items={rightColumnStats} style={styles.statColumn} />
|
||||||
|
</View>
|
||||||
|
<View style={styles.horizontalDivider} />
|
||||||
|
<View style={styles.textContainer}>
|
||||||
|
<Text style={styles.title}>Game Type</Text>
|
||||||
|
<Text style={styles.text}>{gameType}</Text>
|
||||||
|
<Text style={styles.title}>Notes</Text>
|
||||||
|
<Text style={styles.text}>{notes}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[styles.horizontalDivider, { marginVertical: 21 }]} />
|
||||||
|
<ChartContainer
|
||||||
|
data={graph_data_two_measures}
|
||||||
|
ChartComponent={BarGraph}
|
||||||
|
/>
|
||||||
|
</ScrollView>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: #130 scaled styles + maintain consistency with video-feed styles
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
scrollContainer: {
|
||||||
|
backgroundColor: "white", // TODO #125 -- this color should not be set but implicitly inherit from theme
|
||||||
|
paddingBottom: 20, // guarantees some space at bottom of scrollable views
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
width: "100%",
|
||||||
|
height: 248,
|
||||||
|
},
|
||||||
|
statsContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
paddingLeft: 45,
|
||||||
|
paddingTop: 42,
|
||||||
|
paddingBottom: 38,
|
||||||
|
},
|
||||||
|
statColumn: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 5,
|
||||||
|
},
|
||||||
|
horizontalDivider: {
|
||||||
|
width: "92%",
|
||||||
|
alignSelf: "center",
|
||||||
|
...borders.dottedBottomBorder,
|
||||||
|
},
|
||||||
|
textContainer: {
|
||||||
|
paddingHorizontal: 38,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: colors.text.greyText,
|
||||||
|
paddingTop: 16,
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontSize: 18,
|
||||||
|
textAlign: "left",
|
||||||
|
paddingTop: 6,
|
||||||
|
fontWeight: "400",
|
||||||
|
},
|
||||||
|
});
|
@ -1,6 +1,14 @@
|
|||||||
// GLOBAL STYLES
|
import Constants from "expo-constants";
|
||||||
import { StyleSheet } from "react-native";
|
import { Platform, StyleSheet } from "react-native";
|
||||||
|
|
||||||
|
// STYLE CONSTS
|
||||||
|
let STATUS_BAR_HEIGHT: number;
|
||||||
|
|
||||||
|
Platform.OS === "android"
|
||||||
|
? (STATUS_BAR_HEIGHT = 24)
|
||||||
|
: (STATUS_BAR_HEIGHT = Constants.statusBarHeight || 24);
|
||||||
|
|
||||||
|
// GLOBALLY STYLED
|
||||||
export const globalInputStyles = StyleSheet.create({
|
export const globalInputStyles = StyleSheet.create({
|
||||||
input: {
|
input: {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
@ -28,18 +36,21 @@ export const globalInputStyles = StyleSheet.create({
|
|||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// COLORS:
|
// COLORS:
|
||||||
// can be made more granular to specify utility (ex: fontColors vs backgroundColors)
|
// can be made more granular to specify utility (ex: fontColors vs backgroundColors)
|
||||||
export const colors = {
|
export const colors = {
|
||||||
bgBlack: "#121212",
|
bgBlack: "#121212",
|
||||||
lightGrey: "#BFC2C8",
|
lightGrey: "#BFC2C8",
|
||||||
darkGrey: "#767577",
|
darkGrey: "#767577",
|
||||||
themeBrown: "#D9AA84",
|
|
||||||
panelWhite: "#F2FBFE",
|
panelWhite: "#F2FBFE",
|
||||||
tournamentBlue: "#50a6c2",
|
|
||||||
blueCloth: "#539dc2",
|
|
||||||
buttonBlue: "#1987ff",
|
buttonBlue: "#1987ff",
|
||||||
textWhite: "#ffffff",
|
border: {
|
||||||
|
grey: "#8F8E94",
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
greyText: "#848580",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const tabIconColors = {
|
export const tabIconColors = {
|
||||||
@ -47,7 +58,8 @@ export const tabIconColors = {
|
|||||||
selected: "#598EBB",
|
selected: "#598EBB",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const shadows = {
|
// SHADOWS
|
||||||
|
export const shadows = StyleSheet.create({
|
||||||
standard: {
|
standard: {
|
||||||
shadowColor: "#000000",
|
shadowColor: "#000000",
|
||||||
shadowOffset: {
|
shadowOffset: {
|
||||||
@ -58,4 +70,47 @@ export const shadows = {
|
|||||||
shadowRadius: 4.65,
|
shadowRadius: 4.65,
|
||||||
elevation: 3,
|
elevation: 3,
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
|
// BORDER
|
||||||
|
export const borders = StyleSheet.create({
|
||||||
|
dottedBottomBorder: {
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderStyle: "dotted",
|
||||||
|
color: colors.border.grey,
|
||||||
|
},
|
||||||
|
dottedLeftBorder: {
|
||||||
|
borderLeftWidth: 1,
|
||||||
|
borderStyle: "dotted",
|
||||||
|
color: colors.border.grey,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// MODAL
|
||||||
|
const MODAL_TOP_PADDING = 20;
|
||||||
|
const MODAL_TOP_RADIUS = 20;
|
||||||
|
|
||||||
|
export const modal = StyleSheet.create({
|
||||||
|
alignModalContainer: {
|
||||||
|
flex: 1,
|
||||||
|
marginTop: STATUS_BAR_HEIGHT + MODAL_TOP_PADDING ?? 54 + MODAL_TOP_PADDING,
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderTopLeftRadius: MODAL_TOP_RADIUS,
|
||||||
|
borderTopRightRadius: MODAL_TOP_RADIUS,
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
contentStyles: {
|
||||||
|
paddingBottom: 20,
|
||||||
|
},
|
||||||
|
grabber: {
|
||||||
|
alignSelf: "center",
|
||||||
|
width: 40,
|
||||||
|
height: 5,
|
||||||
|
backgroundColor: "#ccc",
|
||||||
|
borderRadius: 2.5,
|
||||||
|
marginVertical: 15,
|
||||||
|
},
|
||||||
|
noMargin: {
|
||||||
|
margin: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
@ -97,3 +97,14 @@ export const mockYData = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const mockXValues = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
export const mockXValues = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||||
|
|
||||||
|
export const mock_session_details = {
|
||||||
|
sessionTitle: "Afternoon Session",
|
||||||
|
date: "Today at 2:37pm",
|
||||||
|
timePlayed: "5:03:10",
|
||||||
|
medianRun: "7.3",
|
||||||
|
makeRate: "34%",
|
||||||
|
shotPacing: "0:00:26",
|
||||||
|
gameType: "Free Play",
|
||||||
|
notes: "Lorem ipsum dolor sit amet, consectetur adipiscing elit...",
|
||||||
|
};
|
||||||
|
17
yarn.lock
17
yarn.lock
@ -9889,7 +9889,7 @@ prompts@^2.0.1, prompts@^2.2.1, prompts@^2.3.2, prompts@^2.4.0, prompts@^2.4.2:
|
|||||||
kleur "^3.0.3"
|
kleur "^3.0.3"
|
||||||
sisteransi "^1.0.5"
|
sisteransi "^1.0.5"
|
||||||
|
|
||||||
prop-types@*, prop-types@^15.6.0, prop-types@^15.7.2, prop-types@^15.8.1:
|
prop-types@*, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||||
version "15.8.1"
|
version "15.8.1"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||||
@ -10041,6 +10041,13 @@ react-is@^17.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||||
|
|
||||||
|
react-native-animatable@1.3.3:
|
||||||
|
version "1.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-native-animatable/-/react-native-animatable-1.3.3.tgz#a13a4af8258e3bb14d0a9d839917e9bb9274ec8a"
|
||||||
|
integrity sha512-2ckIxZQAsvWn25Ho+DK3d1mXIgj7tITkrS4pYDvx96WyOttSvzzFeQnM2od0+FUMzILbdHDsDEqZvnz1DYNQ1w==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
react-native-dotenv@^3.4.9:
|
react-native-dotenv@^3.4.9:
|
||||||
version "3.4.9"
|
version "3.4.9"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-dotenv/-/react-native-dotenv-3.4.9.tgz#621c5b0c1d0c5c7f569bfe5a1d804bec7885c010"
|
resolved "https://registry.yarnpkg.com/react-native-dotenv/-/react-native-dotenv-3.4.9.tgz#621c5b0c1d0c5c7f569bfe5a1d804bec7885c010"
|
||||||
@ -10061,6 +10068,14 @@ react-native-fs@^2.20.0:
|
|||||||
base-64 "^0.1.0"
|
base-64 "^0.1.0"
|
||||||
utf8 "^3.0.0"
|
utf8 "^3.0.0"
|
||||||
|
|
||||||
|
react-native-modal@^13.0.1:
|
||||||
|
version "13.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-native-modal/-/react-native-modal-13.0.1.tgz#691f1e646abb96fa82c1788bf18a16d585da37cd"
|
||||||
|
integrity sha512-UB+mjmUtf+miaG/sDhOikRfBOv0gJdBU2ZE1HtFWp6UixW9jCk/bhGdHUgmZljbPpp0RaO/6YiMmQSSK3kkMaw==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.6.2"
|
||||||
|
react-native-animatable "1.3.3"
|
||||||
|
|
||||||
react-native-reanimated@^3.6.2:
|
react-native-reanimated@^3.6.2:
|
||||||
version "3.6.2"
|
version "3.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.6.2.tgz#8a48c37251cbd3b665a659444fa9778f5b510356"
|
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.6.2.tgz#8a48c37251cbd3b665a659444fa9778f5b510356"
|
||||||
|
Loading…
Reference in New Issue
Block a user