Check video state for entire thread

This commit is contained in:
Dan Abramov
2024-10-26 23:59:32 +01:00
parent f4697a9c02
commit 101281e650
2 changed files with 81 additions and 26 deletions
+80 -24
View File
@@ -177,38 +177,68 @@ export const ComposePost = ({
}) })
}, []) }, [])
let videoState: VideoState | NoVideoState = NO_VIDEO
if (draft.embed.media?.type === 'video') {
videoState = draft.embed.media.video
}
const selectVideo = React.useCallback( const selectVideo = React.useCallback(
(asset: ImagePickerAsset) => { (postId: string | undefined, asset: ImagePickerAsset) => {
const abortController = new AbortController() const abortController = new AbortController()
dispatch({type: 'embed_add_video', asset, abortController}) composerDispatch({
type: 'update_post',
postId: postId,
postAction: {
type: 'embed_add_video',
asset,
abortController,
},
})
processVideo( processVideo(
asset, asset,
videoAction => dispatch({type: 'embed_update_video', videoAction}), videoAction => {
composerDispatch({
type: 'update_post',
postId: postId,
postAction: {
type: 'embed_update_video',
videoAction,
},
})
},
agent, agent,
currentDid, currentDid,
abortController.signal, abortController.signal,
_, _,
) )
}, },
[_, agent, currentDid, dispatch], [_, agent, currentDid, composerDispatch],
) )
// Whenever we receive an initial video uri, we should immediately run compression if necessary // Whenever we receive an initial video uri, we should immediately run compression if necessary
useEffect(() => { useEffect(() => {
if (initVideoUri) { if (initVideoUri) {
selectVideo(initVideoUri) selectVideo(undefined, initVideoUri)
} }
}, [initVideoUri, selectVideo]) }, [initVideoUri, selectVideo])
const clearVideo = React.useCallback(() => { const clearVideo = React.useCallback(
videoState.abortController.abort() (postId: string | undefined) => {
dispatch({type: 'embed_remove_video'}) let post: PostDraft | undefined
}, [videoState.abortController, dispatch]) if (postId !== undefined) {
post = thread.posts.find(p => p.id === postId)
} else {
post = thread.posts[composerState.activePostIndex]
}
const postMedia = post?.embed.media
if (postMedia?.type === 'video') {
postMedia.video.abortController.abort()
composerDispatch({
type: 'update_post',
postId: postId,
postAction: {
type: 'embed_remove_video',
},
})
}
},
[composerState, thread, composerDispatch],
)
const [publishOnUpload, setPublishOnUpload] = useState(false) const [publishOnUpload, setPublishOnUpload] = useState(false)
@@ -426,13 +456,35 @@ export const ComposePost = ({
) )
React.useEffect(() => { React.useEffect(() => {
if (videoState.pendingPublish && publishOnUpload) { if (publishOnUpload) {
if (!videoState.pendingPublish.mutableProcessed) { let uploadingVideos = 0
videoState.pendingPublish.mutableProcessed = true for (let post of thread.posts) {
if (post.embed.media?.type === 'video') {
const video = post.embed.media.video
if (!video.pendingPublish) {
uploadingVideos++
}
}
}
if (uploadingVideos === 0) {
setPublishOnUpload(false)
onPressPublish(true) onPressPublish(true)
} }
} }
}, [onPressPublish, publishOnUpload, videoState.pendingPublish]) }, [thread.posts, onPressPublish, publishOnUpload])
let erroredVideoPostId: string | undefined
let erroredVideo: VideoState | NoVideoState = NO_VIDEO
for (let i = 0; i < thread.posts.length; i++) {
const post = thread.posts[i]
if (
post.embed.media?.type === 'video' &&
post.embed.media.video.status === 'error'
) {
erroredVideoPostId = post.id
erroredVideo = post.embed.media.video
}
}
const onEmojiButtonPress = useCallback(() => { const onEmojiButtonPress = useCallback(() => {
openEmojiPicker?.(textInput.current?.getCursorPosition()) openEmojiPicker?.(textInput.current?.getCursorPosition())
@@ -462,7 +514,7 @@ export const ComposePost = ({
<ComposerTopBar <ComposerTopBar
canPost={canPost} canPost={canPost}
isReply={!!replyTo} isReply={!!replyTo}
isPublishQueued={videoState.status !== 'idle' && publishOnUpload} isPublishQueued={publishOnUpload}
isPublishing={isPublishing} isPublishing={isPublishing}
publishingStage={publishingStage} publishingStage={publishingStage}
topBarAnimatedStyle={topBarAnimatedStyle} topBarAnimatedStyle={topBarAnimatedStyle}
@@ -471,9 +523,13 @@ export const ComposePost = ({
{isAltTextRequiredAndMissing && <AltTextReminder />} {isAltTextRequiredAndMissing && <AltTextReminder />}
<ErrorBanner <ErrorBanner
error={error} error={error}
videoState={videoState} videoState={erroredVideo}
clearError={() => setError('')} clearError={() => setError('')}
clearVideo={clearVideo} clearVideo={
erroredVideoPostId
? () => clearVideo(erroredVideoPostId)
: () => {}
}
/> />
</ComposerTopBar> </ComposerTopBar>
@@ -491,8 +547,8 @@ export const ComposePost = ({
textInput={textInput} textInput={textInput}
isReply={!!replyTo} isReply={!!replyTo}
canRemoveQuote={!initQuote} canRemoveQuote={!initQuote}
onSelectVideo={selectVideo} onSelectVideo={asset => selectVideo(draft.id, asset)}
onClearVideo={clearVideo} onClearVideo={() => clearVideo(draft.id)}
onPublish={() => onPressPublish(false)} onPublish={() => onPressPublish(false)}
onError={setError} onError={setError}
/> />
@@ -513,7 +569,7 @@ export const ComposePost = ({
dispatch={dispatch} dispatch={dispatch}
onError={setError} onError={setError}
onEmojiButtonPress={onEmojiButtonPress} onEmojiButtonPress={onEmojiButtonPress}
onSelectVideo={selectVideo} onSelectVideo={asset => selectVideo(undefined, asset)}
/> />
</View> </View>
+1 -2
View File
@@ -132,7 +132,7 @@ type DoneState = {
asset: ImagePickerAsset asset: ImagePickerAsset
video: CompressedVideo video: CompressedVideo
jobId?: undefined jobId?: undefined
pendingPublish: {blobRef: BlobRef; mutableProcessed: boolean} pendingPublish: {blobRef: BlobRef}
altText: string altText: string
captions: CaptionsTrack[] captions: CaptionsTrack[]
} }
@@ -250,7 +250,6 @@ export function videoReducer(
video: state.video, video: state.video,
pendingPublish: { pendingPublish: {
blobRef: action.blobRef, blobRef: action.blobRef,
mutableProcessed: false,
}, },
altText: state.altText, altText: state.altText,
captions: state.captions, captions: state.captions,