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} 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}