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') { if (asset.type === 'image') {
return <ImageFile key={index} path={asset.path} disabled={sending} remove={()=>actions.removeAsset(index)} /> return <ImageFile key={index} path={asset.path} disabled={sending} remove={()=>actions.removeAsset(index)} />
} else if (asset.type === 'video') { } 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') { } else if (asset.type === 'audio') {
return <AudioFile key={index} path={asset.path} disabled={sending} remove={()=>actions.removeAsset(index)} /> return <AudioFile key={index} path={asset.path} disabled={sending} remove={()=>actions.removeAsset(index)} />
} else { } else {

View File

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

View File

@ -1,13 +1,23 @@
import React, { useEffect } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { View, Animated, useAnimatedValue } from 'react-native' import { Pressable, View, Animated, useAnimatedValue } from 'react-native'
import { IconButton, Text } from 'react-native-paper'; import { Icon, IconButton, Text } from 'react-native-paper';
import { useVideoFile } from './useVideoFile.hook'; import { useVideoFile } from './useVideoFile.hook';
import {styles} from './VideoFile.styled' 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 { state, actions } = useVideoFile();
const opacity = useAnimatedValue(0); 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(() => { useEffect(() => {
if (state.loaded) { if (state.loaded) {
@ -22,7 +32,12 @@ export function VideoFile({ path, disabled, remove }: {path: string, disabled: b
return ( return (
<View style={styles.video}> <View style={styles.video}>
<Animated.View style={[{...styles.thumb, width: 72 * state.ratio},{opacity},]}> <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} /> <IconButton style={styles.icon} mode="contained" icon="close" disabled={disabled} size={20} onPress={remove} />
</Animated.View> </Animated.View>
</View> </View>

View File

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