From 29aaf09a8b8b199b249cef9123673022fde11c4f Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Mon, 24 Jun 2024 23:15:11 +0100 Subject: Composer - replace threadgate modal with alf dialog (#4329) * replace threadgate modal with alf dialog * add accessibility to selectable * add aria * hide spinner once fetched * add `hasOpenDialogs` value to context * remove state * Rm loading state * Update the threadgate dialog button theming * Factor out the threadgate editor and add editing to post views * Mark messages for localization * Use colors from mute dialog * Remove unnecessary effect * Reset state on dialog dismiss * Clearer CTA * Fix bugs * Scope keyboard fix * Rm getAreDialogsActive (no longer needed) --------- Co-authored-by: Dan Abramov Co-authored-by: Paul Frazee --- src/components/WhoCanReply.tsx | 150 ++++++++++++++++++++++------------------- 1 file changed, 82 insertions(+), 68 deletions(-) (limited to 'src/components/WhoCanReply.tsx') diff --git a/src/components/WhoCanReply.tsx b/src/components/WhoCanReply.tsx index cd171a0a4..a73aae850 100644 --- a/src/components/WhoCanReply.tsx +++ b/src/components/WhoCanReply.tsx @@ -17,7 +17,6 @@ import {HITSLOP_10} from '#/lib/constants' import {makeListLink, makeProfileLink} from '#/lib/routes/links' import {logger} from '#/logger' import {isNative} from '#/platform/detection' -import {useModalControls} from '#/state/modals' import {RQKEY_ROOT as POST_THREAD_RQKEY_ROOT} from '#/state/queries/post-thread' import { ThreadgateSetting, @@ -34,6 +33,7 @@ import {Earth_Stroke2_Corner0_Rounded as Earth} from '#/components/icons/Globe' import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group' import {Text} from '#/components/Typography' import {TextLink} from '../view/com/util/Link' +import {ThreadgateEditorDialog} from './dialogs/ThreadgateEditor' import {PencilLine_Stroke2_Corner0_Rounded as PencilLine} from './icons/Pencil' interface WhoCanReplyProps { @@ -46,7 +46,15 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) { const {_} = useLingui() const t = useTheme() const infoDialogControl = useDialogControl() - const {settings, isRootPost, onPressEdit} = useWhoCanReply(post) + const editDialogControl = useDialogControl() + const agent = useAgent() + const queryClient = useQueryClient() + + const settings = React.useMemo( + () => threadgateViewToSettings(post.threadgate), + [post], + ) + const isRootPost = !('reply' in post.record) if (!isRootPost) { return null @@ -63,6 +71,55 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) { ? _(msg`Replies disabled`) : _(msg`Some people can reply`) + const onPressEdit = () => { + if (isNative && Keyboard.isVisible()) { + Keyboard.dismiss() + } + if (isThreadAuthor) { + editDialogControl.open() + } else { + infoDialogControl.open() + } + } + + const onEditConfirm = async (newSettings: ThreadgateSetting[]) => { + if (JSON.stringify(settings) === JSON.stringify(newSettings)) { + return + } + try { + if (newSettings.length) { + await createThreadgate(agent, post.uri, newSettings) + } else { + await agent.api.com.atproto.repo.deleteRecord({ + repo: agent.session!.did, + collection: 'app.bsky.feed.threadgate', + rkey: new AtUri(post.uri).rkey, + }) + } + await whenAppViewReady(agent, post.uri, res => { + const thread = res.data.thread + if (AppBskyFeedDefs.isThreadViewPost(thread)) { + const fetchedSettings = threadgateViewToSettings( + thread.post.threadgate, + ) + return JSON.stringify(fetchedSettings) === JSON.stringify(newSettings) + } + return false + }) + Toast.show(_(msg`Thread settings updated`)) + queryClient.invalidateQueries({ + queryKey: [POST_THREAD_RQKEY_ROOT], + }) + } catch (err) { + Toast.show( + _( + msg`There was an issue. Please check your internet connection and try again.`, + ), + ) + logger.error('Failed to edit threadgate', {message: err}) + } + } + return ( <> - + + {isThreadAuthor && ( + + )} ) } @@ -113,24 +181,31 @@ function Icon({ return } -export function WhoCanReplyDialog({ +function WhoCanReplyDialog({ control, post, + settings, }: { control: Dialog.DialogControlProps post: AppBskyFeedDefs.PostView + settings: ThreadgateSetting[] }) { return ( - + ) } -function WhoCanReplyDialogInner({post}: {post: AppBskyFeedDefs.PostView}) { +function WhoCanReplyDialogInner({ + post, + settings, +}: { + post: AppBskyFeedDefs.PostView + settings: ThreadgateSetting[] +}) { const {_} = useLingui() - const {settings} = useWhoCanReply(post) return ( , } -function useWhoCanReply(post: AppBskyFeedDefs.PostView) { - const agent = useAgent() - const queryClient = useQueryClient() - const {openModal} = useModalControls() - - const settings = React.useMemo( - () => threadgateViewToSettings(post.threadgate), - [post], - ) - const isRootPost = !('reply' in post.record) - - const onPressEdit = () => { - if (isNative && Keyboard.isVisible()) { - Keyboard.dismiss() - } - openModal({ - name: 'threadgate', - settings, - async onConfirm(newSettings: ThreadgateSetting[]) { - if (JSON.stringify(settings) === JSON.stringify(newSettings)) { - return - } - try { - if (newSettings.length) { - await createThreadgate(agent, post.uri, newSettings) - } else { - await agent.api.com.atproto.repo.deleteRecord({ - repo: agent.session!.did, - collection: 'app.bsky.feed.threadgate', - rkey: new AtUri(post.uri).rkey, - }) - } - await whenAppViewReady(agent, post.uri, res => { - const thread = res.data.thread - if (AppBskyFeedDefs.isThreadViewPost(thread)) { - const fetchedSettings = threadgateViewToSettings( - thread.post.threadgate, - ) - return ( - JSON.stringify(fetchedSettings) === JSON.stringify(newSettings) - ) - } - return false - }) - Toast.show('Thread settings updated') - queryClient.invalidateQueries({ - queryKey: [POST_THREAD_RQKEY_ROOT], - }) - } catch (err) { - Toast.show( - 'There was an issue. Please check your internet connection and try again.', - ) - logger.error('Failed to edit threadgate', {message: err}) - } - }, - }) - } - - return {settings, isRootPost, onPressEdit} -} - async function whenAppViewReady( agent: BskyAgent, uri: string, -- cgit 1.4.1