bsky-app/src/view/com/composer/videos/VideoPreview.web.tsx
Samuel Newman 45a719b256
[Video] Check upload limits before uploading (#5153)
* 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>
2024-09-07 19:27:32 +01:00

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>
)
}