From 7ce133001eb90303b1f5e7160120a8351d934265 Mon Sep 17 00:00:00 2001 From: Billy Jacoby Date: Fri, 13 Oct 2023 19:45:36 -0400 Subject: [PATCH] cleanup: remove extra screen from events --- README.md | 2 +- src/components/VideoPlayer.tsx | 5 +- src/components/snapshotCard.tsx | 56 ++++++++++++++---- .../EventsScreen/components/CameraEvent.tsx | 58 +++++-------------- src/screens/FullscreenVideo.tsx | 23 ++++++-- 5 files changed, 82 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 0a54bca..34561ea 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Though this is built in React Native, the immediate focus is to build an iOS nat Though this project is still in the very early stages, it is maturing quickly. The items below are what is next on the roadmap for feature implementation: - [x] Event viewing -- [ ] Recording viewing +- [x] Recording viewing - [ ] View & update config - [ ] Local user settings - [ ] User onboarding diff --git a/src/components/VideoPlayer.tsx b/src/components/VideoPlayer.tsx index c209c68..41378cd 100644 --- a/src/components/VideoPlayer.tsx +++ b/src/components/VideoPlayer.tsx @@ -7,11 +7,13 @@ export const VideoPlayer = ({ isPaused = true, snapshotURL, isForcedFullscreen, + onError, }: { videoURI: string; isPaused?: boolean; snapshotURL?: string; isForcedFullscreen?: boolean; + onError?: Video['props']['onError']; }) => { React.useEffect(() => {}, []); return ( @@ -24,8 +26,9 @@ export const VideoPlayer = ({ paused={isPaused} pictureInPicture={true} controls - source={{uri: videoURI}} + source={{uri: videoURI, type: 'm3u8'}} fullscreen={isForcedFullscreen} + onError={onError || console.error} /> ); }; diff --git a/src/components/snapshotCard.tsx b/src/components/snapshotCard.tsx index ca043cc..46ff4a3 100644 --- a/src/components/snapshotCard.tsx +++ b/src/components/snapshotCard.tsx @@ -1,26 +1,40 @@ -import {Image, ImageURISource, useWindowDimensions, View} from 'react-native'; +import { + Image, + ImageURISource, + TouchableOpacity, + useColorScheme, + useWindowDimensions, + View, +} from 'react-native'; import clsx from 'clsx'; import {BaseText} from './baseText'; import {Label} from './label'; import {FrigateEvent} from '@api'; +import {PlayRect} from '@icons'; + +import {colors, hslFunction} from '../../themeColors'; export const SnapshotCard = ({ imageSource, camEvent, imageOverlay, addtlClasses, + onPlayPress, }: { imageSource: ImageURISource['uri']; camEvent?: FrigateEvent & {lastEventEnded: string}; imageOverlay?: React.ReactNode; addtlClasses?: string; + onPlayPress?: () => void; }) => { const {width} = useWindowDimensions(); const imageWidth = width; const imageHeight = imageWidth * 0.75; + const isDarkMode = useColorScheme() === 'dark'; + return ( {!!imageOverlay && imageOverlay} {!!camEvent && ( - - - {!!camEvent.lastEventEnded && ( + + + {!!camEvent.lastEventEnded && ( + + )} + + {!!onPlayPress && ( + + + )} )} diff --git a/src/screens/CameraScreens/EventsScreen/components/CameraEvent.tsx b/src/screens/CameraScreens/EventsScreen/components/CameraEvent.tsx index d2f9589..64378df 100644 --- a/src/screens/CameraScreens/EventsScreen/components/CameraEvent.tsx +++ b/src/screens/CameraScreens/EventsScreen/components/CameraEvent.tsx @@ -1,17 +1,12 @@ import React from 'react'; -import { - NativeScrollEvent, - NativeSyntheticEvent, - Pressable, - ScrollView, - useWindowDimensions, -} from 'react-native'; +import {ScrollView, useWindowDimensions} from 'react-native'; +import {useNavigation} from '@react-navigation/native'; import clsx from 'clsx'; import {EventDetails} from './EventDetails'; import {FrigateEvent} from '@api'; -import {BaseView, SnapshotCard, VideoPlayer} from '@components'; +import {BaseView, SnapshotCard} from '@components'; export const CameraEvent = ({ camEvent, @@ -24,9 +19,9 @@ export const CameraEvent = ({ const imageWidth = width * 0.97; const imageHeight = imageWidth * 0.75; - const scrollviewRef = React.useRef(null); + const navigation = useNavigation(); - const [videoIsPaused, setVideoIsPaused] = React.useState(true); + const scrollviewRef = React.useRef(null); const getDateString = (date: Date) => { return ( @@ -40,21 +35,12 @@ export const CameraEvent = ({ ); }; - const onEventPress = () => { - scrollviewRef?.current?.scrollToEnd(); - setVideoIsPaused(false); - }; - - const onScrollEnd = (event: NativeSyntheticEvent) => { - if (scrollviewRef.current) { - const xOffset = event.nativeEvent.contentOffset.x; - const scrollIndex = Math.round(xOffset / width); - if (scrollIndex === 2) { - setVideoIsPaused(false); - } else { - setVideoIsPaused(true); - } - } + const onPlayPress = () => { + // Open fullscreen player + navigation.navigate('Fullscreen Video', { + videoURI: camEvent.vodURL, + title: 'Event', + }); }; const lastEventEnded = getDateString(new Date(camEvent?.end_time * 1000)); @@ -65,7 +51,6 @@ export const CameraEvent = ({ return ( {(lastEventImage || lastThumbnail) && ( - - - + )} - - {/* //? if there's a video, show that to the right */} - - - ); }; diff --git a/src/screens/FullscreenVideo.tsx b/src/screens/FullscreenVideo.tsx index 31651bc..cd60453 100644 --- a/src/screens/FullscreenVideo.tsx +++ b/src/screens/FullscreenVideo.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {NativeStackScreenProps} from '@react-navigation/native-stack'; -import {BaseView, VideoPlayer} from '@components'; +import {BaseText, BaseView, VideoPlayer} from '@components'; import {MainStackParamList} from '@navigation'; type FullscreenVideoProps = NativeStackScreenProps< @@ -15,6 +15,7 @@ export const FullscreenVideoPlayer = ({ navigation, }: FullscreenVideoProps) => { const title = route.params.title || ''; + const [hasError, setHasError] = React.useState(false); React.useEffect(() => { navigation.setOptions({title}); @@ -22,11 +23,21 @@ export const FullscreenVideoPlayer = ({ return ( - + {hasError ? ( + + Error loading video. + + ) : ( + { + setHasError(true); + console.error(data, route.params.videoURI); + }} + /> + )} ); };