diff options
Diffstat (limited to 'src/view/com/composer/state/composer.ts')
-rw-r--r-- | src/view/com/composer/state/composer.ts | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/src/view/com/composer/state/composer.ts b/src/view/com/composer/state/composer.ts index 4c94d5eac..27bed6d44 100644 --- a/src/view/com/composer/state/composer.ts +++ b/src/view/com/composer/state/composer.ts @@ -85,7 +85,9 @@ export type ThreadDraft = { export type ComposerState = { thread: ThreadDraft - activePostIndex: number // TODO: Add actions to update this. + activePostIndex: number + mutableNeedsFocusActive: boolean + mutableNeedsScrollToBottom: boolean } export type ComposerAction = @@ -96,6 +98,17 @@ export type ComposerAction = postId: string postAction: PostAction } + | { + type: 'add_post' + } + | { + type: 'remove_post' + postId: string + } + | { + type: 'focus_post' + postId: string + } export const MAX_IMAGES = 4 @@ -142,6 +155,69 @@ export function composerReducer( }, } } + case 'add_post': { + const activePostIndex = state.activePostIndex + const isAtTheEnd = activePostIndex === state.thread.posts.length - 1 + const nextPosts = [...state.thread.posts] + nextPosts.splice(activePostIndex + 1, 0, { + id: nanoid(), + richtext: new RichText({text: ''}), + shortenedGraphemeLength: 0, + labels: [], + embed: { + quote: undefined, + media: undefined, + link: undefined, + }, + }) + return { + ...state, + mutableNeedsScrollToBottom: isAtTheEnd, + thread: { + ...state.thread, + posts: nextPosts, + }, + } + } + case 'remove_post': { + if (state.thread.posts.length < 2) { + return state + } + let nextActivePostIndex = state.activePostIndex + const indexToRemove = state.thread.posts.findIndex( + p => p.id === action.postId, + ) + let nextPosts = [...state.thread.posts] + if (indexToRemove !== -1) { + const postToRemove = state.thread.posts[indexToRemove] + if (postToRemove.embed.media?.type === 'video') { + postToRemove.embed.media.video.abortController.abort() + } + nextPosts.splice(indexToRemove, 1) + nextActivePostIndex = Math.max(0, indexToRemove - 1) + } + return { + ...state, + activePostIndex: nextActivePostIndex, + mutableNeedsFocusActive: true, + thread: { + ...state.thread, + posts: nextPosts, + }, + } + } + case 'focus_post': { + const nextActivePostIndex = state.thread.posts.findIndex( + p => p.id === action.postId, + ) + if (nextActivePostIndex === -1) { + return state + } + return { + ...state, + activePostIndex: nextActivePostIndex, + } + } } } @@ -275,6 +351,7 @@ function postReducer(state: PostDraft, action: PostAction): PostDraft { const prevMedia = state.embed.media let nextMedia = prevMedia if (prevMedia?.type === 'video') { + prevMedia.video.abortController.abort() nextMedia = undefined } let nextLabels = state.labels @@ -436,6 +513,8 @@ export function createComposerState({ }) return { activePostIndex: 0, + mutableNeedsFocusActive: false, + mutableNeedsScrollToBottom: false, thread: { posts: [ { |