Merge branch 'master' into loewy/session-details

This commit is contained in:
Loewy 2024-02-21 17:58:56 -08:00
commit 608e784205
17 changed files with 481 additions and 255 deletions

View File

@ -155,7 +155,7 @@ export default function CameraScreen({
const onMediaCaptured = useCallback( const onMediaCaptured = useCallback(
(media: PhotoFile | VideoFile) => { (media: PhotoFile | VideoFile) => {
console.log(`Media captured! ${JSON.stringify(media)}`); console.log(`Media captured! ${JSON.stringify(media)}`);
navigation.push("SaveVideo", { navigation.push("SaveRecording", {
videoId: uploadManager?.videoId, videoId: uploadManager?.videoId,
...params, ...params,
}); });

View File

@ -54,7 +54,7 @@ function useDropdown<T>(
}; };
} }
export const useVideoDetails = ({ export const useRecordingDetails = ({
params: { params: {
mode, mode,
videoId, videoId,
@ -118,7 +118,7 @@ export const useVideoDetails = ({
} }
// Navigate if starting flow, terminateUploadStream if completing flow // Navigate if starting flow, terminateUploadStream if completing flow
if (mode === "start-video") { if (mode === "start-recording") {
const params: VideoFlowInputParams = { const params: VideoFlowInputParams = {
sessionName, sessionName,
gameType: gameType.value, gameType: gameType.value,

View File

@ -0,0 +1,26 @@
import React from "react";
import { StyleSheet, Text, View } from "react-native";
const VideoCardFooter = ({ videoName, lastPlayed }) => {
return (
<View>
<Text style={styles.videoName}>{videoName}</Text>
<Text style={styles.videoDatetime}>{lastPlayed}</Text>
</View>
);
};
const styles = StyleSheet.create({
videoName: {
fontSize: 18,
paddingTop: 5,
marginHorizontal: 16,
},
videoDatetime: {
fontSize: 10,
color: "#A3A3A3",
marginHorizontal: 16,
},
});
export default VideoCardFooter;

View File

@ -0,0 +1,68 @@
import React from "react";
import { Image, StyleSheet, Text, View } from "react-native";
const VideoCardHeader = ({
playerName,
location,
gameType,
locationIconURL,
profileImageURL,
}) => {
return (
<View style={styles.headerContainer}>
<Image
style={styles.headerProfileImage}
source={{ uri: profileImageURL }}
accessibilityLabel="Profile image"
/>
<View style={styles.headerText}>
<Text style={styles.playerName}>{playerName}</Text>
<View style={styles.locationContainer}>
<Image source={{ uri: locationIconURL }} style={styles.icon} />
<Text style={styles.locationText}>{location}</Text>
</View>
<Text style={styles.gameType}>{gameType}</Text>
</View>
</View>
);
};
const styles = StyleSheet.create({
headerContainer: {
flexDirection: "row",
alignItems: "center",
marginHorizontal: 16,
},
headerProfileImage: {
width: 60,
height: 60,
resizeMode: "contain",
},
headerText: {
flexDirection: "column",
padding: 10,
},
playerName: {
fontSize: 24,
fontWeight: "bold",
},
locationContainer: {
flexDirection: "row",
alignItems: "center",
},
locationText: {
fontSize: 13,
},
gameType: {
fontSize: 13,
},
icon: {
width: 18,
height: 18,
resizeMode: "contain",
},
});
export default VideoCardHeader;

View File

@ -0,0 +1,25 @@
import React from "react";
import { StyleSheet, Text, View } from "react-native";
const VideoCardStat = ({ videoStat, displayName }) => {
return (
<View>
<Text style={styles.statItem}>{displayName}</Text>
<Text style={styles.statValue}>{videoStat}</Text>
</View>
);
};
const styles = StyleSheet.create({
statItem: {
fontSize: 10,
textAlign: "center",
color: "#666",
},
statValue: {
fontSize: 22,
fontWeight: "400",
},
});
export default VideoCardStat;

View File

@ -0,0 +1,48 @@
import React from "react";
import { StyleSheet, View } from "react-native";
import VideoCardStat from "./video-card-stat";
const VideoCardStatsRowContainer = ({
makePercent,
medianRun,
duration,
shotPacing,
}) => {
const stats = [
{ displayName: "Make Percent", videoStat: makePercent },
{ displayName: "Median Run", videoStat: medianRun },
{ displayName: "Time Played", videoStat: duration },
{ displayName: "Shot Pacing", videoStat: shotPacing },
];
return (
<View style={styles.statsContainer}>
{stats.map((stat, index) => (
<React.Fragment key={index}>
<VideoCardStat
displayName={stat.displayName}
videoStat={stat.videoStat}
/>
{index < stats.length - 1 && <View style={styles.verticalSpacer} />}
</React.Fragment>
))}
</View>
);
};
const styles = StyleSheet.create({
statsContainer: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
margin: 16,
},
verticalSpacer: {
width: 1,
backgroundColor: "#A3A3A3",
height: "100%",
marginHorizontal: 12,
},
});
export default VideoCardStatsRowContainer;

View File

@ -0,0 +1,65 @@
import React from "react";
import { Image, StyleSheet, View } from "react-native";
import VideoCardFooter from "./video-card-footer";
import VideoCardHeader from "./video-card-header";
import VideoCardStatsRowContainer from "./video-card-stats-row-container";
const VideoCard = ({
playerName,
location,
gameType,
makePercent,
medianRun,
duration,
shotPacing,
videoName,
lastPlayed,
imageURL,
profileImageURL,
locationIconURL,
}) => {
return (
<View style={styles.card}>
<VideoCardHeader
playerName={playerName}
location={location}
gameType={gameType}
locationIconURL={locationIconURL}
profileImageURL={profileImageURL}
/>
<VideoCardStatsRowContainer
makePercent={makePercent}
medianRun={medianRun}
duration={duration}
shotPacing={shotPacing}
/>
<Image source={imageURL} style={styles.image} />
<VideoCardFooter videoName={videoName} lastPlayed={lastPlayed} />
</View>
);
};
const styles = StyleSheet.create({
card: {
backgroundColor: "white",
borderRadius: 8,
borderWidth: 1,
borderColor: "#ddd",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
margin: 10,
overflow: "hidden",
},
image: {
width: "100%",
height: "50%",
},
});
export default VideoCard;

View File

@ -1,11 +1,11 @@
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { Image } from "react-native"; import { Image } from "react-native";
import CameraScreen from "../component/video/camera"; import CameraScreen from "../component/recording/camera";
import Profile from "../screens/profile"; import Profile from "../screens/profile";
import Session from "../screens/session-stack/session"; import RecordingDetails from "../screens/recording-stack/recording-details";
import SessionFeed from "../screens/session-stack/session-feed"; import Video from "../screens/video-stack/video-details";
import VideoDetails from "../screens/video-stack/video-details"; import VideoFeed from "../screens/video-stack/video-feed";
import { tabIconColors } from "../styles"; import { tabIconColors } from "../styles";
import Icon from "../assets/icons/favicon.png"; import Icon from "../assets/icons/favicon.png";
@ -15,34 +15,34 @@ const RecordStack = createNativeStackNavigator();
// tabBarIcon configuration should live on separate file and contain all logic/icons/rendering for the Tabs // tabBarIcon configuration should live on separate file and contain all logic/icons/rendering for the Tabs
const tabIcons = { const tabIcons = {
SessionStack: <Image source={Icon} style={{ width: 20, height: 20 }} />,
VideoStack: <Image source={Icon} style={{ width: 20, height: 20 }} />, VideoStack: <Image source={Icon} style={{ width: 20, height: 20 }} />,
RecordingStack: <Image source={Icon} style={{ width: 20, height: 20 }} />,
Profile: <Image source={Icon} style={{ width: 20, height: 20 }} />, Profile: <Image source={Icon} style={{ width: 20, height: 20 }} />,
}; };
function VideoTabStack() { function RecordingTabStack() {
return ( return (
<RecordStack.Navigator screenOptions={{ headerShown: false }}> <RecordStack.Navigator screenOptions={{ headerShown: false }}>
<RecordStack.Screen <RecordStack.Screen
name="Record" name="Record"
component={VideoDetails} component={RecordingDetails}
initialParams={{ mode: "start-video" }} initialParams={{ mode: "start-recording" }}
/> />
<RecordStack.Screen name="Camera" component={CameraScreen} /> <RecordStack.Screen name="Camera" component={CameraScreen} />
<RecordStack.Screen <RecordStack.Screen
name="SaveVideo" name="SaveRecording"
component={VideoDetails} component={RecordingDetails}
initialParams={{ mode: "save-video" }} initialParams={{ mode: "save-recording" }}
/> />
</RecordStack.Navigator> </RecordStack.Navigator>
); );
} }
function SessionTabStack() { function VideoTabStack() {
return ( return (
<RecordStack.Navigator screenOptions={{ headerShown: false }}> <RecordStack.Navigator screenOptions={{ headerShown: false }}>
<RecordStack.Screen name="SessionFeed" component={SessionFeed} /> <RecordStack.Screen name="VideoFeed" component={VideoFeed} />
<RecordStack.Screen name="Session" component={Session} /> <RecordStack.Screen name="Video" component={Video} />
</RecordStack.Navigator> </RecordStack.Navigator>
); );
} }
@ -67,14 +67,14 @@ export default function Tabs(): React.JSX.Element {
}, },
})} })}
> >
<Tab.Screen
name="SessionStack"
component={SessionTabStack}
options={{ tabBarLabel: "Session" }}
/>
<Tab.Screen <Tab.Screen
name="VideoStack" name="VideoStack"
component={VideoTabStack} component={VideoTabStack}
options={{ tabBarLabel: "Feed" }}
/>
<Tab.Screen
name="RecordingStack"
component={RecordingTabStack}
options={{ tabBarLabel: "Record" }} options={{ tabBarLabel: "Record" }}
/> />
<Tab.Screen <Tab.Screen

View File

@ -0,0 +1,94 @@
import React from "react";
import {
ActivityIndicator,
Keyboard,
Text,
TextInput,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from "react-native";
import DropDownPicker from "react-native-dropdown-picker";
import { useRecordingDetails } from "../../component/recording/use-recording-details";
import { globalInputStyles } from "../../styles";
import { recordStyles as styles } from "./styles";
export default function VideoDetails({ navigation, route }): React.JSX.Element {
const { mode } = route.params;
const {
sessionName,
setSessionName,
gameType,
tableSize,
handleSubmit,
loading,
} = useRecordingDetails({ params: route.params, navigation });
const dropDownStyles = {
style: globalInputStyles.dropdownStyle,
};
return (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View style={styles.container}>
<Text style={styles.headerText}>
{mode === "start-recording" ? "Record Session" : "Save Session"}
</Text>
<View style={globalInputStyles.dropdownContainer}>
<Text style={globalInputStyles.dropdownTitle}>Session Name</Text>
<TextInput
style={globalInputStyles.input}
placeholder="Session name"
autoCapitalize="none"
value={sessionName}
onChangeText={setSessionName}
/>
<Text style={globalInputStyles.dropdownTitle}>Game Type</Text>
<DropDownPicker
zIndex={3000}
zIndexInverse={1000}
open={gameType.isDropdownOpen}
value={gameType.value}
items={gameType.optionsList}
setOpen={gameType.toggleOpen}
setValue={gameType.setValue}
setItems={gameType.setOptionsList}
{...dropDownStyles}
/>
<Text style={globalInputStyles.dropdownTitle}>Table Size</Text>
<DropDownPicker
zIndex={2000}
zIndexInverse={2000}
open={tableSize.isDropdownOpen}
value={tableSize.value}
items={tableSize.optionsList}
setOpen={tableSize.toggleOpen}
setValue={tableSize.setValue}
setItems={tableSize.setOptionsList}
{...dropDownStyles}
/>
</View>
<View style={styles.buttonContainer}>
{mode === "start-recording" && (
<TouchableOpacity
style={styles.buttonStyle}
onPress={() => navigation.goBack()}
>
<Text style={styles.buttonText}>Back</Text>
</TouchableOpacity>
)}
<TouchableOpacity style={styles.buttonStyle} onPress={handleSubmit}>
{loading ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.buttonText}>
{mode === "start-recording" ? "Next" : "Save"}
</Text>
)}
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
);
}

View File

@ -1,6 +0,0 @@
import React from "react";
import VideoDetails from "./video-details";
export default function SessionScreen({ navigation }) {
return <VideoDetails navigation={navigation} />;
}

View File

@ -1,129 +0,0 @@
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 { 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}
>
<View style={styles.headerSection}>
<Text style={styles.header}>{sessionTitle}</Text>
<Text>{date}</Text>
</View>
<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
},
headerSection: {
paddingHorizontal: 38,
paddingTop: 17,
paddingBottom: 14,
},
header: {
fontSize: 24,
fontWeight: "bold",
},
image: {
width: "100%",
height: 248,
},
statsContainer: {
flexDirection: "row",
justifyContent: "space-between",
paddingLeft: 45,
paddingVertical: 42,
},
statColumn: {
flex: 1,
padding: 5,
},
horizontalDivider: {
width: "95%",
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",
},
});

View File

@ -1,94 +1,129 @@
import React from "react"; import React from "react";
import { ScrollView, StyleSheet, Text, View } from "react-native";
import { import {
ActivityIndicator, graph_data_two_measures,
Keyboard, mock_session_details,
Text, } from "../../../test/mock/charts/mock-data";
TextInput, import BarGraph from "../../component/charts/bar-graph/bar-graph";
TouchableOpacity, import ChartContainer from "../../component/charts/container/chart-container";
TouchableWithoutFeedback, import ImageWithFallback from "../../component/image/image-with-fallback";
View, import StatList from "../../component/video-details/video-stat-list";
} from "react-native";
import DropDownPicker from "react-native-dropdown-picker";
import { useVideoDetails } from "../../component/video/use-video-details";
import { globalInputStyles } from "../../styles";
import { recordStyles as styles } from "./styles";
export default function VideoDetails({ navigation, route }): React.JSX.Element { // TODO: #134 remove Session when data piped through
const { mode } = route.params; // 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 { borders, colors } from "../../styles";
export default function VideoDetails({ navigation }) {
// TODO: #134 Remove mock destructure block when data is piped through from BE
const { const {
sessionName, sessionTitle,
setSessionName, date,
timePlayed,
medianRun,
makeRate,
shotPacing,
gameType, gameType,
tableSize, notes,
handleSubmit, } = mock_session_details;
loading,
} = useVideoDetails({ params: route.params, navigation });
const dropDownStyles = { const leftColumnStats = [
style: globalInputStyles.dropdownStyle, { 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 ( return (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}> <>
<View style={styles.container}> <BackHeader navigation={navigation} title="Go Back" />
<Text style={styles.headerText}> <ScrollView
{mode === "start-video" ? "Record Session" : "Save Session"} showsVerticalScrollIndicator={false}
</Text> contentContainerStyle={styles.scrollContainer}
<View style={globalInputStyles.dropdownContainer}> >
<Text style={globalInputStyles.dropdownTitle}>Session Name</Text> <View style={styles.headerSection}>
<TextInput <Text style={styles.header}>{sessionTitle}</Text>
style={globalInputStyles.input} <Text>{date}</Text>
placeholder="Session name"
autoCapitalize="none"
value={sessionName}
onChangeText={setSessionName}
/>
<Text style={globalInputStyles.dropdownTitle}>Game Type</Text>
<DropDownPicker
zIndex={3000}
zIndexInverse={1000}
open={gameType.isDropdownOpen}
value={gameType.value}
items={gameType.optionsList}
setOpen={gameType.toggleOpen}
setValue={gameType.setValue}
setItems={gameType.setOptionsList}
{...dropDownStyles}
/>
<Text style={globalInputStyles.dropdownTitle}>Table Size</Text>
<DropDownPicker
zIndex={2000}
zIndexInverse={2000}
open={tableSize.isDropdownOpen}
value={tableSize.value}
items={tableSize.optionsList}
setOpen={tableSize.toggleOpen}
setValue={tableSize.setValue}
setItems={tableSize.setOptionsList}
{...dropDownStyles}
/>
</View> </View>
<ImageWithFallback
<View style={styles.buttonContainer}> // TODO: #134 when data comes from be needs to be passed as source={{ uri: image }}
{mode === "start-video" && ( source={Session}
<TouchableOpacity fallbackSource={Splash}
style={styles.buttonStyle} style={styles.image}
onPress={() => navigation.goBack()} />
> <View style={styles.statsContainer}>
<Text style={styles.buttonText}>Back</Text> <StatList items={leftColumnStats} style={styles.statColumn} />
</TouchableOpacity> <StatList items={rightColumnStats} style={styles.statColumn} />
)}
<TouchableOpacity style={styles.buttonStyle} onPress={handleSubmit}>
{loading ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.buttonText}>
{mode === "start-video" ? "Next" : "Save"}
</Text>
)}
</TouchableOpacity>
</View> </View>
</View> <View style={styles.horizontalDivider} />
</TouchableWithoutFeedback> <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
},
headerSection: {
paddingHorizontal: 38,
paddingTop: 17,
paddingBottom: 14,
},
header: {
fontSize: 24,
fontWeight: "bold",
},
image: {
width: "100%",
height: 248,
},
statsContainer: {
flexDirection: "row",
justifyContent: "space-between",
paddingLeft: 45,
paddingVertical: 42,
},
statColumn: {
flex: 1,
padding: 5,
},
horizontalDivider: {
width: "95%",
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",
},
});

View File

@ -1,28 +1,28 @@
import { StackNavigationProp } from "@react-navigation/stack"; import { StackNavigationProp } from "@react-navigation/stack";
import React from "react"; import React from "react";
import { StyleSheet, TouchableOpacity, View } from "react-native"; import { StyleSheet, TouchableOpacity, View } from "react-native";
import sampleSessionImage from "../../assets/sample_session.png"; import sampleVideoImage from "../../assets/sample_session.png";
import SessionCard from "../../component/session-card/session-card"; import VideoCard from "../../component/video-card/video-card";
// Define the types for your navigation stack // Define the types for your navigation stack
type SessionStackParamList = { type VideoStackParamList = {
Session: undefined; // Add other screens as needed Video: undefined; // Add other screens as needed
}; };
type SessionFeedNavigationProp = StackNavigationProp< type VideoFeedNavigationProp = StackNavigationProp<
SessionStackParamList, VideoStackParamList,
"Session" "Video"
>; >;
// Define the props for SessionFeed component // Define the props for VideoFeed component
interface SessionFeedProps { interface VideoFeedProps {
navigation: SessionFeedNavigationProp; navigation: VideoFeedNavigationProp;
} }
const SessionFeed: React.FC<SessionFeedProps> = ({ navigation }) => { const VideoFeed: React.FC<VideoFeedProps> = ({ navigation }) => {
return ( return (
<View style={styles.container}> <View style={styles.container}>
<TouchableOpacity onPress={() => navigation.push("Session")}> <TouchableOpacity onPress={() => navigation.push("Video")}>
<SessionCard <VideoCard
playerName="Dean Machine" playerName="Dean Machine"
location="Family Billiards, San Francisco" location="Family Billiards, San Francisco"
gameType="Straight Pool" gameType="Straight Pool"
@ -30,8 +30,8 @@ const SessionFeed: React.FC<SessionFeedProps> = ({ navigation }) => {
medianRun="7.3" medianRun="7.3"
duration="5:03:10" duration="5:03:10"
shotPacing="0:00:26" shotPacing="0:00:26"
imageURL={sampleSessionImage} imageURL={sampleVideoImage}
sessionName="Dusting off the chalk" videoName="Dusting off the chalk"
lastPlayed="Today at 2:37pm" lastPlayed="Today at 2:37pm"
profileImageURL="https://www.pngall.com/wp-content/uploads/5/Profile-PNG-File.png" profileImageURL="https://www.pngall.com/wp-content/uploads/5/Profile-PNG-File.png"
locationIconURL="https://www.shutterstock.com/image-vector/blank-map-marker-vector-illustration-260nw-1150566347.jpg" locationIconURL="https://www.shutterstock.com/image-vector/blank-map-marker-vector-illustration-260nw-1150566347.jpg"
@ -49,4 +49,4 @@ const styles = StyleSheet.create({
}, },
}); });
export default SessionFeed; export default VideoFeed;