forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
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}