feat(drafts): add restore_video_to_post action to avoid dirty flag

Add restore_video_to_post action that updates post state without setting
isDirty: true. This prevents drafts with videos from being marked as
modified immediately after restoration.

Also update embed_add_video action to accept optional localRefPath
parameter for preserving video identity across draft saves.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Samuel Newman
2026-01-30 20:45:07 +02:00
parent 13390ff174
commit fb459ad61f
+37 -1
View File
@@ -82,6 +82,8 @@ export type PostAction =
type: 'embed_add_video'
asset: ImagePickerAsset
abortController: AbortController
/** Optional localRefPath for draft restoration */
localRefPath?: string
}
| {type: 'embed_remove_video'}
| {type: 'embed_update_video'; videoAction: VideoAction}
@@ -120,6 +122,13 @@ export type ComposerAction =
postId: string
postAction: PostAction
}
| {
/** Like update_post but doesn't mark the composer as dirty.
* Used when restoring video from draft to avoid triggering "unsaved changes" prompt. */
type: 'restore_video_to_post'
postId: string
postAction: PostAction
}
| {
type: 'add_post'
}
@@ -202,6 +211,29 @@ export function composerReducer(
},
}
}
case 'restore_video_to_post': {
// Same as update_post but WITHOUT setting isDirty: true
// Used when restoring video from draft to avoid triggering "unsaved changes" prompt
let nextPosts = state.thread.posts
const postIndex = state.thread.posts.findIndex(
p => p.id === action.postId,
)
if (postIndex !== -1) {
nextPosts = state.thread.posts.slice()
nextPosts[postIndex] = postReducer(
state.thread.posts[postIndex],
action.postAction,
)
}
return {
...state,
// isDirty intentionally NOT set to true
thread: {
...state.thread,
posts: nextPosts,
},
}
}
case 'add_post': {
const activePostIndex = state.activePostIndex
const nextPosts = [...state.thread.posts]
@@ -413,7 +445,11 @@ function postReducer(state: PostDraft, action: PostAction): PostDraft {
if (!prevMedia) {
nextMedia = {
type: 'video',
video: createVideoState(action.asset, action.abortController),
video: createVideoState(
action.asset,
action.abortController,
action.localRefPath,
),
}
}
return {