mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 12:39:17 +00:00
fixing video playback layout
This commit is contained in:
parent
a1b2d5230c
commit
520fc2cfc5
@ -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,
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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) => {
|
||||
|
@ -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 && (
|
||||
|
@ -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',
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user