fixing video playback layout

This commit is contained in:
balzack 2023-05-06 18:41:22 -07:00
parent a1b2d5230c
commit 520fc2cfc5
6 changed files with 74 additions and 55 deletions

View File

@ -6,7 +6,7 @@ export const styles = StyleSheet.create({
width: 8, width: 8,
height: 8, height: 8,
borderRadius: 4, borderRadius: 4,
backgroundColor: Colors.pending, backgroundColor: Colors.background,
position: 'absolute', position: 'absolute',
left: 0, left: 0,
bottom: 0, bottom: 0,

View File

@ -14,8 +14,9 @@ import { AudioAsset } from './audioAsset/AudioAsset';
import { VideoAsset } from './videoAsset/VideoAsset'; import { VideoAsset } from './videoAsset/VideoAsset';
import Carousel from 'react-native-reanimated-carousel'; import Carousel from 'react-native-reanimated-carousel';
import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { GestureHandlerRootView } from 'react-native-gesture-handler';
export function TopicItem({ item, focused, focus, hosting, remove, update, block, report, contentKey }) { import { SafeAreaView, SafeAreaProvider } from 'react-native-safe-area-context';
export function TopicItem({ item, focused, focus, hosting, remove, update, block, report, contentKey }) {
const { state, actions } = useTopicItem(item, hosting, remove, contentKey); const { state, actions } = useTopicItem(item, hosting, remove, contentKey);
const erase = () => { const erase = () => {
@ -211,7 +212,8 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block
supportedOrientations={['portrait', 'landscape']} supportedOrientations={['portrait', 'landscape']}
onRequestClose={actions.hideCarousel} onRequestClose={actions.hideCarousel}
> >
<View style={styles.modal}> <SafeAreaProvider>
<SafeAreaView style={styles.modal} edges={['top','bottom','left','right']}>
<GestureHandlerRootView> <GestureHandlerRootView>
<Carousel <Carousel
loop loop
@ -235,7 +237,8 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block
</View> </View>
)} /> )} />
</GestureHandlerRootView> </GestureHandlerRootView>
</View> </SafeAreaView>
</SafeAreaProvider>
</Modal> </Modal>
</View> </View>
); );

View File

@ -303,6 +303,9 @@ export function useTopicItem(item, hosting, remove, contentKey) {
} }
await RNFS.appendFile(path, decrypted, 'base64'); await RNFS.appendFile(path, decrypted, 'base64');
if (cancel.current) {
throw new Error("unseal assets cancelled");
}
assets[cur] = { ...asset, block: j+1, total: asset.parts.length }; assets[cur] = { ...asset, block: j+1, total: asset.parts.length };
updateState({ assets: [ ...assets ]}); updateState({ assets: [ ...assets ]});
}; };
@ -320,7 +323,8 @@ export function useTopicItem(item, hosting, remove, contentKey) {
} }
}, },
hideCarousel: () => { hideCarousel: () => {
updateState({ carousel: false }); const assets = state.assets.map((asset) => ({ ...asset, error: false, decrypted: null }));
updateState({ carousel: false, assets });
cancel.current = true; cancel.current = true;
}, },
setActive: (activeId) => { setActive: (activeId) => {

View File

@ -6,6 +6,7 @@ import { styles } from './VideoAsset.styled';
import Icons from 'react-native-vector-icons/MaterialCommunityIcons'; import Icons from 'react-native-vector-icons/MaterialCommunityIcons';
import { useKeepAwake } from '@sayem314/react-native-keep-awake'; import { useKeepAwake } from '@sayem314/react-native-keep-awake';
import FastImage from 'react-native-fast-image' import FastImage from 'react-native-fast-image'
import { SafeAreaView } from 'react-native-safe-area-context';
import { useEffect } from 'react'; import { useEffect } from 'react';
@ -16,36 +17,34 @@ export function VideoAsset({ asset, dismiss }) {
useKeepAwake(); useKeepAwake();
return ( return (
<View style={styles.container}> <View style={styles.base}>
<TouchableOpacity activeOpacity={1} style={styles.container} onPress={actions.showControls}> <TouchableOpacity activeOpacity={1} style={styles.container} onPress={actions.showControls}>
<FastImage source={{ uri: asset.thumb }} onLoad={actions.setRatio} <FastImage source={{ uri: asset.thumb }} onLoad={actions.setThumbSize}
style={{ ...styles.thumb, width: state.thumbWidth, height: state.thumbHeight }} style={styles.thumb} resizeMode={FastImage.resizeMode.contain} />
resizeMode={FastImage.resizeMode.contain} />
{ state.url && ( { state.url && (
<Video source={{ uri: state.url, type: 'video/mp4' }} style={{ ...styles.main, width: state.width, height: state.height }} <Video source={{ uri: state.url, type: 'video/mp4' }} style={styles.main}
resizeMode={'cover'} onReadyForDisplay={(e) => { console.log(e) }} onLoad={actions.setVideoSize} repeat={true} paused={!state.playing} resizeMode="contain" />
onLoad={actions.loaded} repeat={true} paused={!state.playing} resizeMode="contain" />
)} )}
{ (!state.playing || state.controls) && ( { (!state.playing || state.controls) && (
<View style={{ ...styles.overlay, width: state.width, height: state.height }} /> <View style={styles.overlay} />
)} )}
{ !state.playing && state.loaded && ( { !state.playing && state.videoLoaded && (
<TouchableOpacity style={styles.control} onPress={actions.play}> <TouchableOpacity style={styles.control} onPress={actions.play}>
<Icons name="play-circle-outline" size={92} color={Colors.white} /> <Icons name="play-circle-outline" size={92} color={Colors.white} />
</TouchableOpacity> </TouchableOpacity>
)} )}
{ state.controls && state.playing && state.loaded && ( { state.controls && state.playing && state.videoLoaded && (
<TouchableOpacity style={styles.control} onPress={actions.pause}> <TouchableOpacity style={styles.control} onPress={actions.pause}>
<Icons name="pause-circle-outline" size={92} color={Colors.white} /> <Icons name="pause-circle-outline" size={92} color={Colors.white} />
</TouchableOpacity> </TouchableOpacity>
)} )}
{ (state.controls || !state.playing) && state.loaded && ( { (state.controls || !state.playing) && state.videoLoaded && (
<TouchableOpacity style={styles.close} onPress={dismiss}> <TouchableOpacity style={styles.close} onPress={dismiss}>
<Icons name="window-close" size={32} color={Colors.white} /> <Icons name="window-close" size={32} color={Colors.white} />
</TouchableOpacity> </TouchableOpacity>
)} )}
</TouchableOpacity> </TouchableOpacity>
{ !state.loaded && ( { !state.videoLoaded && (
<TouchableOpacity style={styles.loading} onPress={dismiss}> <TouchableOpacity style={styles.loading} onPress={dismiss}>
<ActivityIndicator color={Colors.white} size="large" /> <ActivityIndicator color={Colors.white} size="large" />
{ asset.total > 0 && ( { asset.total > 0 && (

View File

@ -2,13 +2,26 @@ import { StyleSheet } from 'react-native';
import { Colors } from 'constants/Colors'; import { Colors } from 'constants/Colors';
export const styles = StyleSheet.create({ export const styles = StyleSheet.create({
container: { base: {
position: 'relative',
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
width: '100%',
height: '100%',
},
container: {
position: 'relative',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
}, },
overlay: { overlay: {
position: 'absolute', position: 'absolute',
height: '100%',
width: '100%',
backgroundColor: 'rgba(0, 0, 0, 0.4)', backgroundColor: 'rgba(0, 0, 0, 0.4)',
}, },
control: { control: {
@ -19,18 +32,20 @@ export const styles = StyleSheet.create({
thumb: { thumb: {
borderRadius: 4, borderRadius: 4,
opacity: 0.6, opacity: 0.6,
width: '100%',
height: '100%',
}, },
main: { main: {
position: 'absolute', position: 'absolute',
width: '100%',
height: '100%',
}, },
close: { close: {
position: 'absolute', position: 'absolute',
top: 0, top: 0,
right: 0, right: 0,
paddingTop: 4, paddingRight: 16,
paddingBottom: 4, paddingTop: 16,
paddingLeft: 8,
paddingRight: 8,
}, },
loading: { loading: {
position: 'absolute', position: 'absolute',

View File

@ -16,9 +16,9 @@ export function useVideoAsset(asset) {
thumbHeight: 64, thumbHeight: 64,
url: null, url: null,
playing: false, playing: false,
loaded: false, thumbLoaded: false,
videoLoaded: false,
controls: false, controls: false,
display: { display: 'none' },
}); });
const controls = useRef(null); const controls = useRef(null);
@ -71,15 +71,13 @@ export function useVideoAsset(asset) {
}, [asset]); }, [asset]);
const actions = { const actions = {
setRatio: (e) => { setThumbSize: (e) => {
const { width, height } = e.nativeEvent; const { width, height } = e.nativeEvent || {};
updateState({ thumbRatio: width / height }); updateState({ thumbLoaded: true, thumbRatio: width / height });
}, },
setResolution: (width, height) => { setVideoSize: (e) => {
updateState({ display: {}, videoRatio: width / height }); const { width, height } = e.naturalSize || {};
}, updateState({ videoLoaded: true, videoRatio: width / height });
loaded: () => {
updateState({ loaded: true });
}, },
play: () => { play: () => {
actions.showControls(); actions.showControls();