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,
height: 8,
borderRadius: 4,
backgroundColor: Colors.pending,
backgroundColor: Colors.background,
position: 'absolute',
left: 0,
bottom: 0,

View File

@ -14,8 +14,9 @@ import { AudioAsset } from './audioAsset/AudioAsset';
import { VideoAsset } from './videoAsset/VideoAsset';
import Carousel from 'react-native-reanimated-carousel';
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 erase = () => {
@ -211,31 +212,33 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block
supportedOrientations={['portrait', 'landscape']}
onRequestClose={actions.hideCarousel}
>
<View style={styles.modal}>
<GestureHandlerRootView>
<Carousel
loop
width={state.width}
autoPlay={false}
data={state.assets}
defaultIndex={state.carouselIndex}
scrollAnimationDuration={1000}
onSnapToItem={(index) => console.log('current index:', index)}
renderItem={({ index }) => (
<View style={styles.frame}>
{ state.assets[index].type === 'image' && (
<ImageAsset asset={state.assets[index]} dismiss={actions.hideCarousel} />
)}
{ state.assets[index].type === 'video' && (
<VideoAsset asset={state.assets[index]} dismiss={actions.hideCarousel} />
)}
{ state.assets[index].type === 'audio' && (
<AudioAsset asset={state.assets[index]} dismiss={actions.hideCarousel} />
)}
</View>
)} />
</GestureHandlerRootView>
</View>
<SafeAreaProvider>
<SafeAreaView style={styles.modal} edges={['top','bottom','left','right']}>
<GestureHandlerRootView>
<Carousel
loop
width={state.width}
autoPlay={false}
data={state.assets}
defaultIndex={state.carouselIndex}
scrollAnimationDuration={1000}
onSnapToItem={(index) => console.log('current index:', index)}
renderItem={({ index }) => (
<View style={styles.frame}>
{ state.assets[index].type === 'image' && (
<ImageAsset asset={state.assets[index]} dismiss={actions.hideCarousel} />
)}
{ state.assets[index].type === 'video' && (
<VideoAsset asset={state.assets[index]} dismiss={actions.hideCarousel} />
)}
{ state.assets[index].type === 'audio' && (
<AudioAsset asset={state.assets[index]} dismiss={actions.hideCarousel} />
)}
</View>
)} />
</GestureHandlerRootView>
</SafeAreaView>
</SafeAreaProvider>
</Modal>
</View>
);

View File

@ -303,6 +303,9 @@ export function useTopicItem(item, hosting, remove, contentKey) {
}
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 };
updateState({ assets: [ ...assets ]});
};
@ -320,7 +323,8 @@ export function useTopicItem(item, hosting, remove, contentKey) {
}
},
hideCarousel: () => {
updateState({ carousel: false });
const assets = state.assets.map((asset) => ({ ...asset, error: false, decrypted: null }));
updateState({ carousel: false, assets });
cancel.current = true;
},
setActive: (activeId) => {

View File

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

View File

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

View File

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