Update profile to pull from labeler definition

This commit is contained in:
Paul Frazee
2024-03-04 14:02:54 -08:00
parent 473ca0deff
commit 4d0dc7438b
6 changed files with 138 additions and 80 deletions
@@ -38,16 +38,16 @@ import {
interface Props {
profile: AppBskyActorDefs.ProfileViewDetailed
modservice: AppBskyLabelerDefs.LabelerViewDetailed
labeler: AppBskyLabelerDefs.LabelerViewDetailed
descriptionRT: RichTextAPI | null
moderationOpts: ModerationOpts
hideBackButton?: boolean
isPlaceholderProfile?: boolean
}
let ProfileHeaderModerator = ({
let ProfileHeaderLabeler = ({
profile: profileUnshadowed,
modservice,
labeler,
descriptionRT,
moderationOpts,
hideBackButton = false,
@@ -74,12 +74,12 @@ let ProfileHeaderModerator = ({
const {mutateAsync: unlikeMod, isPending: isUnlikePending} =
useUnlikeMutation()
const [likeUri, setLikeUri] = React.useState<string>(
modservice.viewer?.like || '',
labeler.viewer?.like || '',
)
const isLiked = !!likeUri
const onToggleLiked = React.useCallback(async () => {
if (!modservice) {
if (!labeler) {
return
}
try {
@@ -90,7 +90,7 @@ let ProfileHeaderModerator = ({
track('CustomFeed:Unlike')
setLikeUri('')
} else {
const res = await likeMod({uri: modservice.uri, cid: modservice.cid})
const res = await likeMod({uri: labeler.uri, cid: labeler.cid})
track('CustomFeed:Like')
setLikeUri(res.uri)
}
@@ -102,7 +102,7 @@ let ProfileHeaderModerator = ({
)
logger.error(`Failed to toggle labeler like`, {message: e.message})
}
}, [modservice, likeUri, isLiked, likeMod, unlikeMod, track, _])
}, [labeler, likeUri, isLiked, likeMod, unlikeMod, track, _])
const onPressEditProfile = React.useCallback(() => {
track('ProfileHeader:EditProfileButtonClicked')
@@ -213,13 +213,13 @@ let ProfileHeaderModerator = ({
)}
</Button>
{typeof modservice.likeCount === 'number' && (
{typeof labeler.likeCount === 'number' && (
<InlineLink
to={'#todo'}
style={[t.atoms.text_contrast_medium, a.font_bold]}>
<Trans>
Liked by {modservice.likeCount}{' '}
{pluralize(modservice.likeCount, 'user')}
Liked by {labeler.likeCount}{' '}
{pluralize(labeler.likeCount, 'user')}
</Trans>
</InlineLink>
)}
@@ -230,5 +230,5 @@ let ProfileHeaderModerator = ({
</ProfileHeaderShell>
)
}
ProfileHeaderModerator = memo(ProfileHeaderModerator)
export {ProfileHeaderModerator}
ProfileHeaderLabeler = memo(ProfileHeaderLabeler)
export {ProfileHeaderLabeler}
+4 -4
View File
@@ -10,7 +10,7 @@ import {LoadingPlaceholder} from 'view/com/util/LoadingPlaceholder'
import {usePalette} from 'lib/hooks/usePalette'
import {ProfileHeaderStandard} from './ProfileHeaderStandard'
import {ProfileHeaderModerator} from './ProfileHeaderModerator'
import {ProfileHeaderLabeler} from './ProfileHeaderLabeler'
let ProfileHeaderLoading = (_props: {}): React.ReactNode => {
const pal = usePalette('default')
@@ -34,7 +34,7 @@ export {ProfileHeaderLoading}
interface Props {
profile: AppBskyActorDefs.ProfileViewDetailed
modservice: AppBskyLabelerDefs.LabelerViewDetailed | undefined
labeler: AppBskyLabelerDefs.LabelerViewDetailed | undefined
descriptionRT: RichTextAPI | null
moderationOpts: ModerationOpts
hideBackButton?: boolean
@@ -43,10 +43,10 @@ interface Props {
let ProfileHeader = (props: Props): React.ReactNode => {
if (props.profile.associated?.labeler) {
if (!props.modservice) {
if (!props.labeler) {
return <ProfileHeaderLoading />
}
return <ProfileHeaderModerator {...props} modservice={props.modservice} />
return <ProfileHeaderLabeler {...props} labeler={props.labeler} />
}
return <ProfileHeaderStandard {...props} />
}
@@ -1,12 +1,18 @@
import React from 'react'
import {View} from 'react-native'
import {AppBskyLabelerDefs, ModerationOpts} from '@atproto/api'
import {
AppBskyLabelerDefs,
ModerationOpts,
interpretLabelValueDefinitions,
InterprettedLabelValueDefinition,
} from '@atproto/api'
import {Trans, msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useSafeAreaFrame} from 'react-native-safe-area-context'
import {useLabelerSubscriptionMutation} from '#/state/queries/labeler'
import {logger} from '#/logger'
import {lookupLabelValueDefinition} from '#/lib/moderation'
import {useTheme, atoms as a} from '#/alf'
import {Text} from '#/components/Typography'
@@ -17,21 +23,20 @@ import {CenteredView, ScrollView} from '#/view/com/util/Views'
import {ErrorState} from '../ErrorState'
import {ModerationLabelPref} from '#/components/ModerationLabelPref'
export function ProfileContentFiltersSection({
modServiceQuery,
export function ProfileLabelsSection({
isLabelerLoading,
labelerInfo,
labelerError,
moderationOpts,
}: {
modServiceQuery: {
data: AppBskyLabelerDefs.LabelerViewDetailed | undefined
isLoading: boolean
error: Error | null
}
isLabelerLoading: boolean
labelerInfo: AppBskyLabelerDefs.LabelerViewDetailed | undefined
labelerError: Error | null
moderationOpts: ModerationOpts
}) {
const t = useTheme()
const {_} = useLingui()
const {height: minHeight} = useSafeAreaFrame()
const {isLoading, error, data: modservice} = modServiceQuery
return (
<CenteredView>
<View
@@ -44,21 +49,21 @@ export function ProfileContentFiltersSection({
minHeight,
},
]}>
{isLoading ? (
{isLabelerLoading ? (
<View style={[a.w_full, a.align_center]}>
<Loader size="xl" />
</View>
) : error || !modservice ? (
) : labelerError || !labelerInfo ? (
<ErrorState
error={
error?.toString() ||
labelerError?.toString() ||
_(msg`Something went wrong, please try again.`)
}
/>
) : (
<ProfileContentFiltersSectionInner
<ProfileLabelsSectionInner
moderationOpts={moderationOpts}
modservice={modservice}
labelerInfo={labelerInfo}
/>
)}
</View>
@@ -66,37 +71,46 @@ export function ProfileContentFiltersSection({
)
}
export function ProfileContentFiltersSectionInner({
export function ProfileLabelsSectionInner({
moderationOpts,
modservice,
labelerInfo,
}: {
moderationOpts: ModerationOpts
modservice: AppBskyLabelerDefs.LabelerViewDetailed
labelerInfo: AppBskyLabelerDefs.LabelerViewDetailed
}) {
const {_} = useLingui()
const t = useTheme()
const isEnabled = Boolean(
moderationOpts.prefs.mods.find(mod => mod.did === modservice.creator.did),
moderationOpts.prefs.mods.find(mod => mod.did === labelerInfo.creator.did),
)
const hasSession = true // TODO
const {labelValues} = labelerInfo.policies
const labelDefs = React.useMemo(() => {
const customDefs = interpretLabelValueDefinitions(labelerInfo)
return labelValues
.map(val => lookupLabelValueDefinition(val, customDefs))
.filter(
def => def && def?.configurable,
) as InterprettedLabelValueDefinition[]
}, [labelerInfo, labelValues])
const {mutateAsync: toggleSubscription, variables} =
useLabelerSubscriptionMutation()
const isSubscribed =
variables?.subscribe ??
moderationOpts.prefs.mods.find(mod => mod.did === modservice.creator.did)
moderationOpts.prefs.mods.find(mod => mod.did === labelerInfo.creator.did)
const onPressSubscribe = React.useCallback(async () => {
try {
await toggleSubscription({
did: modservice.creator.did,
did: labelerInfo.creator.did,
subscribe: !isSubscribed,
})
} catch (e: any) {
// setSubscriptionError(e.message)
logger.error(`Failed to subscribe to labeler`, {message: e.message})
}
}, [toggleSubscription, isSubscribed, modservice])
}, [toggleSubscription, isSubscribed, labelerInfo])
return (
<ScrollView
@@ -112,7 +126,7 @@ export function ProfileContentFiltersSectionInner({
hide, warn, and categorize the network.
</Trans>
</Text>
{!isSubscribed && (
{labelValues.length === 0 ? (
<Text
style={[
a.pt_xl,
@@ -121,33 +135,46 @@ export function ProfileContentFiltersSectionInner({
a.text_sm,
]}>
<Trans>
Subscribe to @{modservice.creator.handle} to use these labels:
This labeler hasn't declared what labels it publishes, and may not
be active.
</Trans>
</Text>
)}
</View>
<View
style={[
a.mt_xl,
t.atoms.bg_contrast_25,
a.rounded_md,
a.border,
t.atoms.border_contrast_low,
]}>
{
undefined /* TODO modservice.policies.labelValues.map((def, i) => {
return (
<React.Fragment key={def.id}>
{i !== 0 && <Divider />}
<ModerationLabelPref
disabled={isEnabled ? undefined : true}
labelGroup={def.id}
/>
</React.Fragment>
)
})*/
}
) : !isSubscribed ? (
<Text
style={[
a.pt_xl,
t.atoms.text_contrast_high,
a.leading_snug,
a.text_sm,
]}>
<Trans>
Subscribe to @{labelerInfo.creator.handle} to use these labels:
</Trans>
</Text>
) : null}
</View>
{labelDefs.length > 0 && (
<View
style={[
a.mt_xl,
t.atoms.bg_contrast_25,
a.rounded_md,
a.border,
t.atoms.border_contrast_low,
]}>
{labelDefs.map((labelDef, i) => {
return (
<React.Fragment key={labelDef?.identifier}>
{i !== 0 && <Divider />}
<ModerationLabelPref
disabled={isEnabled ? undefined : true}
labelValueDefinition={labelDef}
/>
</React.Fragment>
)
})}
</View>
)}
<View style={{height: 100}} />
</ScrollView>