Polish video upload progress completion
This commit is contained in:
committed by
Samuel Newman
parent
4cbd643964
commit
d289c329e2
@@ -125,6 +125,7 @@ import {atoms as a, native, useBreakpoints, useTheme, web} from '#/alf'
|
||||
import {Admonition} from '#/components/Admonition'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import * as EmojiPicker from '#/components/EmojiPicker'
|
||||
import {CircleCheck_Stroke2_Corner0_Rounded as CircleCheckIcon} from '#/components/icons/CircleCheck'
|
||||
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfoIcon} from '#/components/icons/CircleInfo'
|
||||
import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmileIcon} from '#/components/icons/Emoji'
|
||||
import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus'
|
||||
@@ -2717,17 +2718,25 @@ function VideoUploadToolbar({state}: {state: VideoState}) {
|
||||
|
||||
return (
|
||||
<ToolbarWrapper style={[a.flex_row, a.align_center, {paddingVertical: 5}]}>
|
||||
<ProgressCircle
|
||||
size={30}
|
||||
borderWidth={1}
|
||||
borderColor={t.atoms.border_contrast_low.borderColor}
|
||||
color={
|
||||
state.status === 'error'
|
||||
? t.palette.negative_500
|
||||
: t.palette.primary_500
|
||||
}
|
||||
progress={wheelProgress}
|
||||
/>
|
||||
{state.status === 'done' ? (
|
||||
<Animated.View
|
||||
entering={ZoomIn.duration(300)}
|
||||
style={[a.align_center, a.justify_center, {height: 30, width: 30}]}>
|
||||
<CircleCheckIcon size="lg" fill={t.palette.primary_500} />
|
||||
</Animated.View>
|
||||
) : (
|
||||
<ProgressCircle
|
||||
size={30}
|
||||
borderWidth={1}
|
||||
borderColor={t.atoms.border_contrast_low.borderColor}
|
||||
color={
|
||||
state.status === 'error'
|
||||
? t.palette.negative_500
|
||||
: t.palette.primary_500
|
||||
}
|
||||
progress={wheelProgress}
|
||||
/>
|
||||
)}
|
||||
<Text style={[a.font_semi_bold, a.ml_sm]}>{text}</Text>
|
||||
</ToolbarWrapper>
|
||||
)
|
||||
|
||||
@@ -17,7 +17,11 @@ import {uploadVideo} from '#/lib/media/video/upload'
|
||||
import {createVideoAgent} from '#/lib/media/video/util'
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {logger} from '#/logger'
|
||||
import {advanceVideoProgress, videoProgressForPhase} from './videoProgress'
|
||||
import {
|
||||
advanceVideoProgress,
|
||||
didSkipVideoCompression,
|
||||
videoProgressForPhase,
|
||||
} from './videoProgress'
|
||||
|
||||
type CaptionsTrack = {lang: string; file: File}
|
||||
|
||||
@@ -331,7 +335,7 @@ export async function processVideo(
|
||||
dispatch({
|
||||
type: 'compressing_to_uploading',
|
||||
video,
|
||||
compressionSkipped: video.passthroughReason !== undefined,
|
||||
compressionSkipped: didSkipVideoCompression(video.passthroughReason),
|
||||
signal,
|
||||
})
|
||||
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
import {
|
||||
advanceVideoProgress,
|
||||
didSkipVideoCompression,
|
||||
videoProgressForPhase,
|
||||
videoProgressWithinPhase,
|
||||
} from './videoProgress'
|
||||
|
||||
describe('didSkipVideoCompression', () => {
|
||||
it('distinguishes a real skip from a failed compression attempt', () => {
|
||||
expect(didSkipVideoCompression(undefined)).toBe(false)
|
||||
expect(didSkipVideoCompression('below-byte-threshold')).toBe(true)
|
||||
expect(didSkipVideoCompression('no-webcodecs')).toBe(true)
|
||||
expect(didSkipVideoCompression('gif')).toBe(true)
|
||||
expect(didSkipVideoCompression('compress-error-fallback')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('videoProgressForPhase', () => {
|
||||
it('maps each phase onto one continuous timeline', () => {
|
||||
expect(videoProgressForPhase('compressing', 0)).toBe(0)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import {type VideoCompressSkipReason} from '#/lib/media/video/types'
|
||||
|
||||
export type VideoProgressPhase =
|
||||
| 'compressing'
|
||||
| 'uploading'
|
||||
@@ -14,6 +16,18 @@ const PHASE_RANGES: Record<VideoProgressPhase, [number, number]> = {
|
||||
processing: [0.5, 1],
|
||||
}
|
||||
|
||||
export function didSkipVideoCompression(
|
||||
passthroughReason: VideoCompressSkipReason | undefined,
|
||||
): boolean {
|
||||
// The web compressor can return the original file after reporting partial
|
||||
// compression progress. Keep that case on the post-compression upload band
|
||||
// so the global indicator cannot jump backwards.
|
||||
return (
|
||||
passthroughReason !== undefined &&
|
||||
passthroughReason !== 'compress-error-fallback'
|
||||
)
|
||||
}
|
||||
|
||||
export function videoProgressForPhase(
|
||||
phase: VideoProgressPhase,
|
||||
phaseProgress: number,
|
||||
|
||||
Reference in New Issue
Block a user