diff options
author | dan <dan.abramov@gmail.com> | 2024-11-01 03:45:55 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-01 03:45:55 +0000 |
commit | 7a08d61d889328ff5e3b8ba61faab71a5568df2f (patch) | |
tree | 105fd6ef552581048349ca1e756b71daebf7fc20 /src/view/com/composer/state/composer.ts | |
parent | 01c9ac0e13e959bae9ab221cd0a724a70c222772 (diff) | |
download | voidsky-7a08d61d889328ff5e3b8ba61faab71a5568df2f.tar.zst |
Thread composer UI (#6050)
* Basic adding of posts * Switch active post on focus * Conditionally show plus button * Insert posts midthread * Track active/inactive post * Delete posts in a thread * Focus after deletion * Tweak empty post detection * Mix height for active only * Move toolbar with post on web * Fix footer positioning * Post All button * Fix reply to positioning * Improve memoization * Improve memoization for clearVideo * Remove unnecessary argument * Add some manual memoization to fix re-renders * Scroll to bottom on add new * Fix opacity on Android * Add backdrop * Fix videos * Check alt for video too * Clear pending publish on error * Fork alt message by type * Separate placeholder for next posts * Limit hitslop to avoid clashes
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: [ { |