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