import {useEffect, useMemo, useState} from 'react' import {Keyboard, type StyleProp, type ViewStyle} from 'react-native' import {type AnimatedStyle} from 'react-native-reanimated' import {type AppBskyFeedPostgate} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import deepEqual from 'fast-deep-equal' import {isNetworkError} from '#/lib/strings/errors' import {logger} from '#/logger' import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings' import {createPostgateRecord} from '#/state/queries/postgate/util' import {usePreferencesQuery} from '#/state/queries/preferences' import { type ThreadgateAllowUISetting, threadgateAllowUISettingToAllowRecordValue, threadgateRecordToAllowUISetting, } from '#/state/queries/threadgate' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {PostInteractionSettingsControlledDialog} from '#/components/dialogs/PostInteractionSettingsDialog' import {TinyChevronBottom_Stroke2_Corner0_Rounded as TinyChevronIcon} from '#/components/icons/Chevron' import {Earth_Stroke2_Corner0_Rounded as EarthIcon} from '#/components/icons/Globe' import {Group3_Stroke2_Corner0_Rounded as GroupIcon} from '#/components/icons/Group' import * as Tooltip from '#/components/Tooltip' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_NATIVE} from '#/env' import {useThreadgateNudged} from '#/storage/hooks/threadgate-nudged' export function ThreadgateBtn({ postgate, onChangePostgate, threadgateAllowUISettings, onChangeThreadgateAllowUISettings, }: { postgate: AppBskyFeedPostgate.Record onChangePostgate: (v: AppBskyFeedPostgate.Record) => void threadgateAllowUISettings: ThreadgateAllowUISetting[] onChangeThreadgateAllowUISettings: (v: ThreadgateAllowUISetting[]) => void style?: StyleProp> }) { const {_} = useLingui() const ax = useAnalytics() const control = Dialog.useDialogControl() const [threadgateNudged, setThreadgateNudged] = useThreadgateNudged() const [showTooltip, setShowTooltip] = useState(false) const [tooltipWasShown] = useState(!threadgateNudged) useEffect(() => { if (!threadgateNudged) { const timeout = setTimeout(() => { setShowTooltip(true) }, 1000) return () => clearTimeout(timeout) } }, [threadgateNudged]) const onDismissTooltip = (visible: boolean) => { if (visible) return setThreadgateNudged(true) setShowTooltip(false) } const {data: preferences} = usePreferencesQuery() const [persist, setPersist] = useState(false) const onPress = () => { ax.metric('composer:threadgate:open', { nudged: tooltipWasShown, }) if (IS_NATIVE && Keyboard.isVisible()) { Keyboard.dismiss() } setShowTooltip(false) setThreadgateNudged(true) control.open() } const prefThreadgateAllowUISettings = threadgateRecordToAllowUISetting({ $type: 'app.bsky.feed.threadgate', post: '', createdAt: new Date().toISOString(), allow: preferences?.postInteractionSettings.threadgateAllowRules, }) const prefPostgate = createPostgateRecord({ post: '', embeddingRules: preferences?.postInteractionSettings?.postgateEmbeddingRules || [], }) const isDirty = useMemo(() => { const everybody = [{type: 'everybody'}] return ( !deepEqual( threadgateAllowUISettings, prefThreadgateAllowUISettings ?? everybody, ) || !deepEqual(postgate.embeddingRules, prefPostgate?.embeddingRules ?? []) ) }, [ prefThreadgateAllowUISettings, prefPostgate, threadgateAllowUISettings, postgate, ]) const {mutate: persistChanges, isPending: isSaving} = usePostInteractionSettingsMutation({ onError: err => { if (!isNetworkError(err)) { logger.error('Failed to persist threadgate settings', { safeMessage: err, }) } }, onSettled: () => { control.close(() => { setPersist(false) }) }, }) const anyoneCanReply = threadgateAllowUISettings.length === 1 && threadgateAllowUISettings[0].type === 'everybody' const anyoneCanQuote = !postgate.embeddingRules || postgate.embeddingRules.length === 0 const anyoneCanInteract = anyoneCanReply && anyoneCanQuote const label = anyoneCanInteract ? _(msg`Anyone can interact`) : _(msg`Interaction limited`) return ( <> Psst! You can edit who can interact with this post. { if (persist) { persistChanges({ threadgateAllowRules: threadgateAllowUISettingToAllowRecordValue( threadgateAllowUISettings, ), postgateEmbeddingRules: postgate.embeddingRules ?? [], }) } else { control.close() } }} isSaving={isSaving} postgate={postgate} onChangePostgate={onChangePostgate} threadgateAllowUISettings={threadgateAllowUISettings} onChangeThreadgateAllowUISettings={onChangeThreadgateAllowUISettings} isDirty={isDirty} persist={persist} onChangePersist={setPersist} /> ) }