selecting video thumb

This commit is contained in:
balzack 2025-01-06 10:46:45 -08:00
parent c46c927324
commit bbe089d05a
4 changed files with 29 additions and 8 deletions

View File

@ -175,7 +175,7 @@ export function Conversation({close}: {close: ()=>void}) {
if (asset.type === 'image') {
return <ImageFile key={index} path={asset.path} disabled={sending} remove={()=>actions.removeAsset(index)} />
} else if (asset.type === 'video') {
return <VideoFile key={index} path={asset.path} disabled={sending} remove={()=>actions.removeAsset(index)} />
return <VideoFile key={index} path={asset.path} thumbPosition={(position: number) => actions.setThumbPosition(index, position)} disabled={sending} remove={()=>actions.removeAsset(index)} />
} else if (asset.type === 'audio') {
return <AudioFile key={index} path={asset.path} disabled={sending} remove={()=>actions.removeAsset(index)} />
} else {

View File

@ -14,4 +14,9 @@ export const styles = StyleSheet.create({
right: 0,
borderRadius: 4,
},
next: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
}
});

View File

@ -1,13 +1,23 @@
import React, { useEffect } from 'react';
import { View, Animated, useAnimatedValue } from 'react-native'
import { IconButton, Text } from 'react-native-paper';
import React, { useEffect, useRef, useState } from 'react';
import { Pressable, View, Animated, useAnimatedValue } from 'react-native'
import { Icon, IconButton, Text } from 'react-native-paper';
import { useVideoFile } from './useVideoFile.hook';
import {styles} from './VideoFile.styled'
import Video from 'react-native-video'
import Video, { VideoRef } from 'react-native-video'
export function VideoFile({ path, disabled, remove }: {path: string, disabled: boolean, remove: ()=>void}) {
export function VideoFile({ path, thumbPosition, disabled, remove }: {path: string, thumbPosition: (position: number)=>void, disabled: boolean, remove: ()=>void}) {
const { state, actions } = useVideoFile();
const opacity = useAnimatedValue(0);
const videoRef = useRef<VideoRef>(null as null | VideoRef);
const [seek, setSeek] = useState(0);
const next = () => {
const step = state.duration / 10;
const pos = seek + step > state.duration ? 0 : seek + step;
thumbPosition(pos);
videoRef.current.seek(pos);
setSeek(pos);
}
useEffect(() => {
if (state.loaded) {
@ -22,7 +32,12 @@ export function VideoFile({ path, disabled, remove }: {path: string, disabled: b
return (
<View style={styles.video}>
<Animated.View style={[{...styles.thumb, width: 72 * state.ratio},{opacity},]}>
<Video source={{ uri: path }} height={72} width={72 * state.ratio} paused={true} controls={false} resizeMode="contain" onLoad={actions.loaded} />
<Video ref={videoRef} source={{ uri: path }} height={72} width={72 * state.ratio} paused={true} controls={false} resizeMode="contain" onLoad={actions.loaded} />
{ !disabled && (
<Pressable style={styles.next} height={72} width={72 * state.ratio} onPress={next}>
<Icon size={28} source="chevron-right" />
</Pressable>
)}
<IconButton style={styles.icon} mode="contained" icon="close" disabled={disabled} size={20} onPress={remove} />
</Animated.View>
</View>

View File

@ -4,6 +4,7 @@ export function useVideoFile(source: any) {
const [state, setState] = useState({
loaded: false,
ratio: 1,
duration: 0,
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -14,7 +15,7 @@ export function useVideoFile(source: any) {
const actions = {
loaded: (e) => {
const { width, height } = e.naturalSize;
updateState({ loaded: true, ratio: width / height });
updateState({ loaded: true, ratio: width / height, duration: e.duration });
},
}