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 {Admonition} from '#/components/Admonition'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import * as EmojiPicker from '#/components/EmojiPicker'
|
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 {CircleInfo_Stroke2_Corner0_Rounded as CircleInfoIcon} from '#/components/icons/CircleInfo'
|
||||||
import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmileIcon} from '#/components/icons/Emoji'
|
import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmileIcon} from '#/components/icons/Emoji'
|
||||||
import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus'
|
import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus'
|
||||||
@@ -2717,17 +2718,25 @@ function VideoUploadToolbar({state}: {state: VideoState}) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolbarWrapper style={[a.flex_row, a.align_center, {paddingVertical: 5}]}>
|
<ToolbarWrapper style={[a.flex_row, a.align_center, {paddingVertical: 5}]}>
|
||||||
<ProgressCircle
|
{state.status === 'done' ? (
|
||||||
size={30}
|
<Animated.View
|
||||||
borderWidth={1}
|
entering={ZoomIn.duration(300)}
|
||||||
borderColor={t.atoms.border_contrast_low.borderColor}
|
style={[a.align_center, a.justify_center, {height: 30, width: 30}]}>
|
||||||
color={
|
<CircleCheckIcon size="lg" fill={t.palette.primary_500} />
|
||||||
state.status === 'error'
|
</Animated.View>
|
||||||
? t.palette.negative_500
|
) : (
|
||||||
: t.palette.primary_500
|
<ProgressCircle
|
||||||
}
|
size={30}
|
||||||
progress={wheelProgress}
|
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>
|
<Text style={[a.font_semi_bold, a.ml_sm]}>{text}</Text>
|
||||||
</ToolbarWrapper>
|
</ToolbarWrapper>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ import {uploadVideo} from '#/lib/media/video/upload'
|
|||||||
import {createVideoAgent} from '#/lib/media/video/util'
|
import {createVideoAgent} from '#/lib/media/video/util'
|
||||||
import {isNetworkError} from '#/lib/strings/errors'
|
import {isNetworkError} from '#/lib/strings/errors'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {advanceVideoProgress, videoProgressForPhase} from './videoProgress'
|
import {
|
||||||
|
advanceVideoProgress,
|
||||||
|
didSkipVideoCompression,
|
||||||
|
videoProgressForPhase,
|
||||||
|
} from './videoProgress'
|
||||||
|
|
||||||
type CaptionsTrack = {lang: string; file: File}
|
type CaptionsTrack = {lang: string; file: File}
|
||||||
|
|
||||||
@@ -331,7 +335,7 @@ export async function processVideo(
|
|||||||
dispatch({
|
dispatch({
|
||||||
type: 'compressing_to_uploading',
|
type: 'compressing_to_uploading',
|
||||||
video,
|
video,
|
||||||
compressionSkipped: video.passthroughReason !== undefined,
|
compressionSkipped: didSkipVideoCompression(video.passthroughReason),
|
||||||
signal,
|
signal,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
import {
|
import {
|
||||||
advanceVideoProgress,
|
advanceVideoProgress,
|
||||||
|
didSkipVideoCompression,
|
||||||
videoProgressForPhase,
|
videoProgressForPhase,
|
||||||
videoProgressWithinPhase,
|
videoProgressWithinPhase,
|
||||||
} from './videoProgress'
|
} 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', () => {
|
describe('videoProgressForPhase', () => {
|
||||||
it('maps each phase onto one continuous timeline', () => {
|
it('maps each phase onto one continuous timeline', () => {
|
||||||
expect(videoProgressForPhase('compressing', 0)).toBe(0)
|
expect(videoProgressForPhase('compressing', 0)).toBe(0)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import {type VideoCompressSkipReason} from '#/lib/media/video/types'
|
||||||
|
|
||||||
export type VideoProgressPhase =
|
export type VideoProgressPhase =
|
||||||
| 'compressing'
|
| 'compressing'
|
||||||
| 'uploading'
|
| 'uploading'
|
||||||
@@ -14,6 +16,18 @@ const PHASE_RANGES: Record<VideoProgressPhase, [number, number]> = {
|
|||||||
processing: [0.5, 1],
|
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(
|
export function videoProgressForPhase(
|
||||||
phase: VideoProgressPhase,
|
phase: VideoProgressPhase,
|
||||||
phaseProgress: number,
|
phaseProgress: number,
|
||||||
|
|||||||
Reference in New Issue
Block a user