-
-
Save johnwcassidy/f533ebb153c21a3260e1e3ff16da80b6 to your computer and use it in GitHub Desktop.
A basic implementation of recoil in You.i Engine One
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Basic You.i RN app demonstrating recoil | |
*/ | |
import React, { Component, useEffect, useRef, useState } from "react"; | |
import { AppRegistry, StyleSheet, Text, View } from "react-native"; | |
import { Slider, Video } from "@youi/react-native-youi"; | |
import { RecoilRoot, useRecoilState, atom } from "recoil"; | |
const VideoCurrentTimeState = atom({ | |
key: "videoPosition", | |
default: 0, | |
}); | |
const VideoDurationState = atom({ | |
key: "videoDuration", | |
default: 0, | |
}); | |
const VideoComponent = React.forwardRef((props, ref) => { | |
const [ready, setReady] = useState(false); | |
const [, setVideoPosition] = useRecoilState(VideoCurrentTimeState); | |
const [, setVideoDuration] = useRecoilState(VideoDurationState); | |
useEffect(() => { | |
if (ready) { | |
ref?.current?.play(); | |
} | |
}, [ready]); | |
const onDurationChanged = (duration) => { | |
setVideoDuration(duration); | |
}; | |
const onCurrentTimeUpdated = (time) => { | |
setVideoPosition(time); | |
}; | |
return ( | |
<Video | |
style={{ flex: 1 }} | |
ref={ref} | |
source={{ | |
type: "HLS", | |
uri: | |
"https://multiplatform-f.akamaihd.net/i/multi/april11/sintel/sintel-hd_,512x288_450_b,640x360_700_b,768x432_1000_b,1024x576_1400_m,.mp4.csmil/master.m3u8", | |
}} | |
onReady={() => setReady(true)} | |
onCurrentTimeUpdated={onCurrentTimeUpdated} | |
onDurationChanged={onDurationChanged} | |
/> | |
); | |
}); | |
const ControlContainer = ({ onSeek }) => { | |
return ( | |
<View style={styles.controls}> | |
<Text style={styles.headerText}>Sintel</Text> | |
<View style={styles.flexRow}> | |
<TimeElapsed /> | |
<View style={{ flex: 1 }}> | |
<ScrollBar onSeek={onSeek} /> | |
</View> | |
<TimeRemaining /> | |
</View> | |
</View> | |
); | |
}; | |
const ScrollBar = ({ onSeek }) => { | |
const [videoPosition] = useRecoilState(VideoCurrentTimeState); | |
const [videoDuration] = useRecoilState(VideoDurationState); | |
return ( | |
<Slider | |
style={{ flex: 1 }} | |
maximumValue={videoDuration} | |
value={videoPosition} | |
onSlidingComplete={onSeek} | |
/> | |
); | |
}; | |
const TimeElapsed = () => { | |
const [videoPosition] = useRecoilState(VideoCurrentTimeState); | |
function getTimestamp(videoPosition) { | |
const totalTimeInSeconds = videoPosition; | |
return `${new Date(totalTimeInSeconds).toISOString().substr(14, 5)}`; | |
} | |
return <Text style={styles.h1}>{getTimestamp(videoPosition)}</Text>; | |
}; | |
const TimeRemaining = () => { | |
const [videoPosition] = useRecoilState(VideoCurrentTimeState); | |
const [videoDuration] = useRecoilState(VideoDurationState); | |
function getTimestamp(videoPosition, videoDuration) { | |
const totalTimeInSeconds = videoDuration - videoPosition; | |
return `${new Date(totalTimeInSeconds).toISOString().substr(14, 5)}`; | |
} | |
return ( | |
<Text style={styles.h1}>{getTimestamp(videoPosition, videoDuration)}</Text> | |
); | |
}; | |
export default YiReactApp = () => { | |
const videoRef = useRef(null); | |
const onSeekRequest = (seekTo) => { | |
videoRef?.current?.seek(Math.round(seekTo)); | |
}; | |
return ( | |
<RecoilRoot> | |
<View style={styles.mainContainer}> | |
<VideoComponent ref={videoRef} /> | |
<ControlContainer onSeek={onSeekRequest} /> | |
</View> | |
</RecoilRoot> | |
); | |
}; | |
const styles = StyleSheet.create({ | |
mainContainer: { | |
backgroundColor: "#e6e7e7", | |
flex: 1, | |
}, | |
controls: { | |
width: "100%", | |
position: "absolute", | |
bottom: 0, | |
backgroundColor: "rgba(00, 00, 00, 0.3)", | |
padding: 5, | |
}, | |
headerText: { | |
fontSize: 48, | |
color: "#FFFFFF", | |
}, | |
h1: { | |
fontSize: 18, | |
color: "#FFFFFF", | |
}, | |
flexRow: { | |
flex: 1, | |
display: "flex", | |
flexDirection: "row", | |
alignItems: "center", | |
}, | |
}); | |
AppRegistry.registerComponent("YiReactApp", () => YiReactApp); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment