* DRY up video service auth code * throw error if over upload limits * use token * xmark on toast * errors with nice translatable error messages * Update src/state/queries/video/video.ts --------- Co-authored-by: Hailey <me@haileyok.com>
91 lines
2.2 KiB
TypeScript
91 lines
2.2 KiB
TypeScript
import React, {useEffect, useRef} from 'react'
|
|
import {View} from 'react-native'
|
|
import {ImagePickerAsset} from 'expo-image-picker'
|
|
import {msg} from '@lingui/macro'
|
|
import {useLingui} from '@lingui/react'
|
|
|
|
import {CompressedVideo} from '#/lib/media/video/types'
|
|
import {clamp} from '#/lib/numbers'
|
|
import {useAutoplayDisabled} from '#/state/preferences'
|
|
import * as Toast from '#/view/com/util/Toast'
|
|
import {ExternalEmbedRemoveBtn} from 'view/com/composer/ExternalEmbedRemoveBtn'
|
|
import {atoms as a} from '#/alf'
|
|
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
|
|
|
|
export function VideoPreview({
|
|
asset,
|
|
video,
|
|
setDimensions,
|
|
clear,
|
|
}: {
|
|
asset: ImagePickerAsset
|
|
video: CompressedVideo
|
|
setDimensions: (width: number, height: number) => void
|
|
clear: () => void
|
|
}) {
|
|
const ref = useRef<HTMLVideoElement>(null)
|
|
const {_} = useLingui()
|
|
const autoplayDisabled = useAutoplayDisabled()
|
|
|
|
useEffect(() => {
|
|
if (!ref.current) return
|
|
|
|
const abortController = new AbortController()
|
|
const {signal} = abortController
|
|
ref.current.addEventListener(
|
|
'loadedmetadata',
|
|
function () {
|
|
setDimensions(this.videoWidth, this.videoHeight)
|
|
},
|
|
{signal},
|
|
)
|
|
ref.current.addEventListener(
|
|
'error',
|
|
() => {
|
|
Toast.show(_(msg`Could not process your video`), 'xmark')
|
|
clear()
|
|
},
|
|
{signal},
|
|
)
|
|
|
|
return () => {
|
|
abortController.abort()
|
|
}
|
|
}, [setDimensions, _, clear])
|
|
|
|
let aspectRatio = asset.width / asset.height
|
|
|
|
if (isNaN(aspectRatio)) {
|
|
aspectRatio = 16 / 9
|
|
}
|
|
|
|
aspectRatio = clamp(aspectRatio, 1 / 1, 3 / 1)
|
|
|
|
return (
|
|
<View
|
|
style={[
|
|
a.w_full,
|
|
a.rounded_sm,
|
|
{aspectRatio},
|
|
a.overflow_hidden,
|
|
{backgroundColor: 'black'},
|
|
a.relative,
|
|
]}>
|
|
<ExternalEmbedRemoveBtn onRemove={clear} />
|
|
<video
|
|
ref={ref}
|
|
src={video.uri}
|
|
style={{width: '100%', height: '100%', objectFit: 'cover'}}
|
|
autoPlay={!autoplayDisabled}
|
|
loop
|
|
muted
|
|
playsInline
|
|
/>
|
|
{autoplayDisabled && (
|
|
<View style={[a.absolute, a.inset_0, a.justify_center, a.align_center]}>
|
|
<PlayButtonIcon />
|
|
</View>
|
|
)}
|
|
</View>
|
|
)
|
|
}
|