Bluesky app fork with some witchin' additions 馃挮
at jean/pds-label 109 lines 3.6 kB view raw
1import {useCallback, useEffect, useState} from 'react' 2import {type ModerationOpts} from '@atproto/api' 3import {msg} from '@lingui/core/macro' 4import {useLingui} from '@lingui/react' 5import {Trans} from '@lingui/react/macro' 6 7import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification' 8import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name' 9import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons' 10import {Button, ButtonIcon} from '#/components/Button' 11import {useDialogControl} from '#/components/Dialog' 12import {BellPlus_Stroke2_Corner0_Rounded as BellPlusIcon} from '#/components/icons/BellPlus' 13import {BellRinging_Filled_Corner0_Rounded as BellRingingIcon} from '#/components/icons/BellRinging' 14import * as Tooltip from '#/components/Tooltip' 15import {Text} from '#/components/Typography' 16import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged' 17import type * as bsky from '#/types/bsky' 18import {SubscribeProfileDialog} from './SubscribeProfileDialog' 19 20export function SubscribeProfileButton({ 21 profile, 22 moderationOpts, 23 disableHint, 24}: { 25 profile: bsky.profile.AnyProfileView 26 moderationOpts: ModerationOpts 27 disableHint?: boolean 28}) { 29 const {_} = useLingui() 30 const requireEmailVerification = useRequireEmailVerification() 31 const subscribeDialogControl = useDialogControl() 32 const [activitySubscriptionsNudged, setActivitySubscriptionsNudged] = 33 useActivitySubscriptionsNudged() 34 const [showTooltip, setShowTooltip] = useState(false) 35 36 useEffect(() => { 37 if (!activitySubscriptionsNudged) { 38 const timeout = setTimeout(() => { 39 setShowTooltip(true) 40 }, 500) 41 return () => clearTimeout(timeout) 42 } 43 }, [activitySubscriptionsNudged]) 44 45 const onDismissTooltip = (visible: boolean) => { 46 if (visible) return 47 48 setShowTooltip(false) 49 setActivitySubscriptionsNudged(true) 50 } 51 52 const onPress = useCallback(() => { 53 subscribeDialogControl.open() 54 }, [subscribeDialogControl]) 55 56 const name = createSanitizedDisplayName(profile, true) 57 58 const wrappedOnPress = requireEmailVerification(onPress, { 59 instructions: [ 60 <Trans key="message"> 61 Before you can get notifications for {name}'s posts, you must first 62 verify your email. 63 </Trans>, 64 ], 65 }) 66 67 const isSubscribed = 68 profile.viewer?.activitySubscription?.post || 69 profile.viewer?.activitySubscription?.reply 70 71 const Icon = isSubscribed ? BellRingingIcon : BellPlusIcon 72 73 const enableSquareButtons = useEnableSquareButtons() 74 75 const tooltipVisible = showTooltip && !disableHint 76 77 return ( 78 <> 79 <Tooltip.Outer 80 visible={tooltipVisible} 81 onVisibleChange={onDismissTooltip} 82 position="bottom"> 83 <Tooltip.Target> 84 <Button 85 accessibilityRole="button" 86 testID="dmBtn" 87 size="small" 88 color={tooltipVisible ? 'primary_subtle' : 'secondary'} 89 shape={enableSquareButtons ? 'square' : 'round'} 90 label={_(msg`Get notified when ${name} posts`)} 91 onPress={wrappedOnPress}> 92 <ButtonIcon icon={Icon} size="md" /> 93 </Button> 94 </Tooltip.Target> 95 <Tooltip.TextBubble> 96 <Text> 97 <Trans>Get notified about new posts</Trans> 98 </Text> 99 </Tooltip.TextBubble> 100 </Tooltip.Outer> 101 102 <SubscribeProfileDialog 103 control={subscribeDialogControl} 104 profile={profile} 105 moderationOpts={moderationOpts} 106 /> 107 </> 108 ) 109}