Add minimal header to profiles (#8936)
This commit is contained in:
@@ -23,7 +23,6 @@ import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
|
||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||
import {useRequireAuth, useSession} from '#/state/session'
|
||||
import {ProfileMenu} from '#/view/com/profile/ProfileMenu'
|
||||
import * as Toast from '#/view/com/util/Toast'
|
||||
import {atoms as a, tokens, useTheme} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
import {type DialogOuterProps, useDialogControl} from '#/components/Dialog'
|
||||
@@ -34,6 +33,7 @@ import {
|
||||
import {Link} from '#/components/Link'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {ProfileHeaderDisplayName} from './DisplayName'
|
||||
import {EditProfileDialog} from './EditProfileDialog'
|
||||
@@ -63,28 +63,17 @@ let ProfileHeaderLabeler = ({
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const {currentAccount, hasSession} = useSession()
|
||||
const requireAuth = useRequireAuth()
|
||||
const playHaptic = useHaptics()
|
||||
const cantSubscribePrompt = Prompt.usePromptControl()
|
||||
const isSelf = currentAccount?.did === profile.did
|
||||
|
||||
const moderation = useMemo(
|
||||
() => moderateProfile(profile, moderationOpts),
|
||||
[profile, moderationOpts],
|
||||
)
|
||||
const {data: preferences} = usePreferencesQuery()
|
||||
const {
|
||||
mutateAsync: toggleSubscription,
|
||||
variables,
|
||||
reset,
|
||||
} = useLabelerSubscriptionMutation()
|
||||
const isSubscribed =
|
||||
variables?.subscribe ??
|
||||
preferences?.moderationPrefs.labelers.find(l => l.did === profile.did)
|
||||
const {mutateAsync: likeMod, isPending: isLikePending} = useLikeMutation()
|
||||
const {mutateAsync: unlikeMod, isPending: isUnlikePending} =
|
||||
useUnlikeMutation()
|
||||
const [likeUri, setLikeUri] = useState<string>(labeler.viewer?.like || '')
|
||||
const [likeUri, setLikeUri] = useState(labeler.viewer?.like || '')
|
||||
const [likeCount, setLikeCount] = useState(labeler.likeCount || 0)
|
||||
|
||||
const onToggleLiked = useCallback(async () => {
|
||||
@@ -108,56 +97,12 @@ let ProfileHeaderLabeler = ({
|
||||
_(
|
||||
msg`There was an issue contacting the server, please check your internet connection and try again.`,
|
||||
),
|
||||
'xmark',
|
||||
{type: 'error'},
|
||||
)
|
||||
logger.error(`Failed to toggle labeler like`, {message: e.message})
|
||||
}
|
||||
}, [labeler, playHaptic, likeUri, unlikeMod, likeMod, _])
|
||||
|
||||
const editProfileControl = useDialogControl()
|
||||
|
||||
const onPressSubscribe = useCallback(() => {
|
||||
requireAuth(async (): Promise<void> => {
|
||||
playHaptic()
|
||||
const subscribe = !isSubscribed
|
||||
|
||||
try {
|
||||
await toggleSubscription({
|
||||
did: profile.did,
|
||||
subscribe,
|
||||
})
|
||||
|
||||
logger.metric(
|
||||
subscribe
|
||||
? 'moderation:subscribedToLabeler'
|
||||
: 'moderation:unsubscribedFromLabeler',
|
||||
{},
|
||||
{statsig: true},
|
||||
)
|
||||
} catch (e: any) {
|
||||
reset()
|
||||
if (e.message === 'MAX_LABELERS') {
|
||||
cantSubscribePrompt.open()
|
||||
return
|
||||
}
|
||||
logger.error(`Failed to subscribe to labeler`, {message: e.message})
|
||||
}
|
||||
})
|
||||
}, [
|
||||
playHaptic,
|
||||
requireAuth,
|
||||
toggleSubscription,
|
||||
isSubscribed,
|
||||
profile,
|
||||
cantSubscribePrompt,
|
||||
reset,
|
||||
])
|
||||
|
||||
const isMe = useMemo(
|
||||
() => currentAccount?.did === profile.did,
|
||||
[currentAccount, profile],
|
||||
)
|
||||
|
||||
return (
|
||||
<ProfileHeaderShell
|
||||
profile={profile}
|
||||
@@ -170,75 +115,7 @@ let ProfileHeaderLabeler = ({
|
||||
<View
|
||||
style={[a.flex_row, a.justify_end, a.align_center, a.gap_xs, a.pb_lg]}
|
||||
pointerEvents={isIOS ? 'auto' : 'box-none'}>
|
||||
{isMe ? (
|
||||
<>
|
||||
<Button
|
||||
testID="profileHeaderEditProfileButton"
|
||||
size="small"
|
||||
color="secondary"
|
||||
variant="solid"
|
||||
onPress={editProfileControl.open}
|
||||
label={_(msg`Edit profile`)}
|
||||
style={a.rounded_full}>
|
||||
<ButtonText>
|
||||
<Trans>Edit Profile</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
<EditProfileDialog
|
||||
profile={profile}
|
||||
control={editProfileControl}
|
||||
/>
|
||||
</>
|
||||
) : !isAppLabeler(profile.did) ? (
|
||||
<>
|
||||
<Button
|
||||
testID="toggleSubscribeBtn"
|
||||
label={
|
||||
isSubscribed
|
||||
? _(msg`Unsubscribe from this labeler`)
|
||||
: _(msg`Subscribe to this labeler`)
|
||||
}
|
||||
onPress={onPressSubscribe}>
|
||||
{state => (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
paddingVertical: 9,
|
||||
paddingHorizontal: 12,
|
||||
borderRadius: 6,
|
||||
gap: 6,
|
||||
backgroundColor: isSubscribed
|
||||
? state.hovered || state.pressed
|
||||
? t.palette.contrast_50
|
||||
: t.palette.contrast_25
|
||||
: state.hovered || state.pressed
|
||||
? tokens.color.temp_purple_dark
|
||||
: tokens.color.temp_purple,
|
||||
},
|
||||
]}>
|
||||
<Text
|
||||
style={[
|
||||
{
|
||||
color: isSubscribed
|
||||
? t.palette.contrast_700
|
||||
: t.palette.white,
|
||||
},
|
||||
a.font_semi_bold,
|
||||
a.text_center,
|
||||
a.leading_tight,
|
||||
]}>
|
||||
{isSubscribed ? (
|
||||
<Trans>Unsubscribe</Trans>
|
||||
) : (
|
||||
<Trans>Subscribe to Labeler</Trans>
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
<ProfileMenu profile={profile} />
|
||||
<HeaderLabelerButtons profile={profile} />
|
||||
</View>
|
||||
<View style={[a.flex_col, a.gap_2xs, a.pt_2xs, a.pb_md]}>
|
||||
<ProfileHeaderDisplayName profile={profile} moderation={moderation} />
|
||||
@@ -265,7 +142,6 @@ let ProfileHeaderLabeler = ({
|
||||
testID="toggleLikeBtn"
|
||||
size="small"
|
||||
color="secondary"
|
||||
variant="solid"
|
||||
shape="round"
|
||||
label={_(msg`Like this labeler`)}
|
||||
disabled={!hasSession || isLikePending || isUnlikePending}
|
||||
@@ -318,7 +194,6 @@ let ProfileHeaderLabeler = ({
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
<CantSubscribePrompt control={cantSubscribePrompt} />
|
||||
</ProfileHeaderShell>
|
||||
)
|
||||
}
|
||||
@@ -349,3 +224,132 @@ function CantSubscribePrompt({
|
||||
</Prompt.Outer>
|
||||
)
|
||||
}
|
||||
|
||||
export function HeaderLabelerButtons({
|
||||
profile,
|
||||
minimal = false,
|
||||
}: {
|
||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>
|
||||
/** disable the subscribe button */
|
||||
minimal?: boolean
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const t = useTheme()
|
||||
const {currentAccount} = useSession()
|
||||
const requireAuth = useRequireAuth()
|
||||
const playHaptic = useHaptics()
|
||||
const editProfileControl = useDialogControl()
|
||||
const {data: preferences} = usePreferencesQuery()
|
||||
const {
|
||||
mutateAsync: toggleSubscription,
|
||||
variables,
|
||||
reset,
|
||||
} = useLabelerSubscriptionMutation()
|
||||
const isSubscribed =
|
||||
variables?.subscribe ??
|
||||
preferences?.moderationPrefs.labelers.find(l => l.did === profile.did)
|
||||
|
||||
const cantSubscribePrompt = Prompt.usePromptControl()
|
||||
|
||||
const isMe = currentAccount?.did === profile.did
|
||||
|
||||
const onPressSubscribe = () =>
|
||||
requireAuth(async (): Promise<void> => {
|
||||
playHaptic()
|
||||
const subscribe = !isSubscribed
|
||||
|
||||
try {
|
||||
await toggleSubscription({
|
||||
did: profile.did,
|
||||
subscribe,
|
||||
})
|
||||
|
||||
logger.metric(
|
||||
subscribe
|
||||
? 'moderation:subscribedToLabeler'
|
||||
: 'moderation:unsubscribedFromLabeler',
|
||||
{},
|
||||
{statsig: true},
|
||||
)
|
||||
} catch (e: any) {
|
||||
reset()
|
||||
if (e.message === 'MAX_LABELERS') {
|
||||
cantSubscribePrompt.open()
|
||||
return
|
||||
}
|
||||
logger.error(`Failed to subscribe to labeler`, {message: e.message})
|
||||
}
|
||||
})
|
||||
return (
|
||||
<>
|
||||
{isMe ? (
|
||||
<>
|
||||
<Button
|
||||
testID="profileHeaderEditProfileButton"
|
||||
size="small"
|
||||
color="secondary"
|
||||
onPress={editProfileControl.open}
|
||||
label={_(msg`Edit profile`)}
|
||||
style={a.rounded_full}>
|
||||
<ButtonText>
|
||||
<Trans>Edit Profile</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
<EditProfileDialog profile={profile} control={editProfileControl} />
|
||||
</>
|
||||
) : !isAppLabeler(profile.did) && !minimal ? (
|
||||
// hidden in the minimal header, because it's not shadowed so the two buttons
|
||||
// can get out of sync. if you want to reenable, you'll need to add shadowing
|
||||
// to the subscribed state -sfn
|
||||
<Button
|
||||
testID="toggleSubscribeBtn"
|
||||
label={
|
||||
isSubscribed
|
||||
? _(msg`Unsubscribe from this labeler`)
|
||||
: _(msg`Subscribe to this labeler`)
|
||||
}
|
||||
onPress={onPressSubscribe}>
|
||||
{state => (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
paddingVertical: 9,
|
||||
paddingHorizontal: 12,
|
||||
borderRadius: 6,
|
||||
gap: 6,
|
||||
backgroundColor: isSubscribed
|
||||
? state.hovered || state.pressed
|
||||
? t.palette.contrast_50
|
||||
: t.palette.contrast_25
|
||||
: state.hovered || state.pressed
|
||||
? tokens.color.temp_purple_dark
|
||||
: tokens.color.temp_purple,
|
||||
},
|
||||
]}>
|
||||
<Text
|
||||
style={[
|
||||
{
|
||||
color: isSubscribed
|
||||
? t.palette.contrast_700
|
||||
: t.palette.white,
|
||||
},
|
||||
a.font_semi_bold,
|
||||
a.text_center,
|
||||
a.leading_tight,
|
||||
]}>
|
||||
{isSubscribed ? (
|
||||
<Trans>Unsubscribe</Trans>
|
||||
) : (
|
||||
<Trans>Subscribe to Labeler</Trans>
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</Button>
|
||||
) : null}
|
||||
<ProfileMenu profile={profile} />
|
||||
|
||||
<CantSubscribePrompt control={cantSubscribePrompt} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user