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