Update to use new labeler semantics

This commit is contained in:
Paul Frazee
2024-03-04 13:04:33 -08:00
parent aa2f94e2fb
commit f30f31f123
12 changed files with 58 additions and 71 deletions
@@ -2,16 +2,16 @@ import React from 'react'
import {View} from 'react-native' import {View} from 'react-native'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {AppBskyModerationDefs} from '@atproto/api' import {AppBskyLabelerDefs} from '@atproto/api'
import {Link as InternalLink, LinkProps} from '#/components/Link' import {Link as InternalLink, LinkProps} from '#/components/Link'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import {useModServiceInfoQuery} from '#/state/queries/modservice' import {useLabelerInfoQuery} from '#/state/queries/labeler'
export * as Card from '#/components/ModerationServiceCard/Card' export * as Card from '#/components/ModerationServiceCard/Card'
type ModerationServiceProps = { type ModerationServiceProps = {
modservice: AppBskyModerationDefs.ModServiceViewDetailed modservice: AppBskyLabelerDefs.LabelerViewDetailed
} }
export function Link({ export function Link({
@@ -54,10 +54,10 @@ export function Loader({
loading?: React.ComponentType<{}> loading?: React.ComponentType<{}>
error?: React.ComponentType<{error: string}> error?: React.ComponentType<{error: string}>
component: React.ComponentType<{ component: React.ComponentType<{
modservice: AppBskyModerationDefs.ModServiceViewDetailed modservice: AppBskyLabelerDefs.LabelerViewDetailed
}> }>
}) { }) {
const {isLoading, data, error} = useModServiceInfoQuery({did}) const {isLoading, data, error} = useLabelerInfoQuery({did})
return isLoading ? ( return isLoading ? (
LoadingComponent ? ( LoadingComponent ? (
+4 -4
View File
@@ -2,7 +2,7 @@ import React from 'react'
import {View, Linking, Pressable} from 'react-native' import {View, Linking, Pressable} from 'react-native'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {AppBskyModerationDefs, LabelGroupDefinition} from '@atproto/api' import {AppBskyLabelerDefs, LabelGroupDefinition} from '@atproto/api'
import {atoms as a, useTheme, tokens, native} from '#/alf' import {atoms as a, useTheme, tokens, native} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
@@ -27,7 +27,7 @@ import {CharProgress} from '#/view/com/composer/char-progress/CharProgress'
import {Loader} from '#/components/Loader' import {Loader} from '#/components/Loader'
import * as Toast from '#/view/com/util/Toast' import * as Toast from '#/view/com/util/Toast'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferencesQuery} from '#/state/queries/preferences'
import {useModServicesDetailedInfoQuery} from '#/state/queries/modservice' import {useLabelersDetailedInfoQuery} from '#/state/queries/labeler'
import { import {
getModerationServiceTitle, getModerationServiceTitle,
useConfigurableContentLabelGroups, useConfigurableContentLabelGroups,
@@ -338,7 +338,7 @@ export function ReportDialogLoaded({
labelGroupToLabelerMap, labelGroupToLabelerMap,
...props ...props
}: ReportDialogProps & { }: ReportDialogProps & {
labelers: AppBskyModerationDefs.ModServiceViewDetailed[] labelers: AppBskyLabelerDefs.LabelerViewDetailed[]
labelGroupToLabelerMap: ReturnType<typeof getLabelGroupToLabelerMap> labelGroupToLabelerMap: ReturnType<typeof getLabelGroupToLabelerMap>
}) { }) {
const t = useTheme() const t = useTheme()
@@ -480,7 +480,7 @@ function ReportDialogInner(props: ReportDialogProps) {
isLoading: isModServicesLoading, isLoading: isModServicesLoading,
data: modservices, data: modservices,
error: modservicesError, error: modservicesError,
} = useModServicesDetailedInfoQuery({ } = useLabelersDetailedInfoQuery({
dids: preferences ? preferences.moderationOpts.mods.map(m => m.did) : [], dids: preferences ? preferences.moderationOpts.mods.map(m => m.did) : [],
}) })
const isLoading = isPreferencesLoading || isModServicesLoading const isLoading = isPreferencesLoading || isModServicesLoading
+1 -5
View File
@@ -1,9 +1,5 @@
import React from 'react' import React from 'react'
import { import {ModerationCause, ModerationUI, AppBskyLabelerDefs} from '@atproto/api'
ModerationCause,
ModerationUI,
AppBskyModerationDefs,
} from '@atproto/api'
import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles'
+4 -4
View File
@@ -4,7 +4,7 @@ import {useFocusEffect} from '@react-navigation/native'
import {ComAtprotoLabelDefs} from '@atproto/api' import {ComAtprotoLabelDefs} from '@atproto/api'
import {Trans, msg} from '@lingui/macro' import {Trans, msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {AppBskyModerationDefs} from '@atproto/api' import {AppBskyLabelerDefs} from '@atproto/api'
import {useSafeAreaFrame} from 'react-native-safe-area-context' import {useSafeAreaFrame} from 'react-native-safe-area-context'
import {NativeStackScreenProps, CommonNavigatorParams} from '#/lib/routes/types' import {NativeStackScreenProps, CommonNavigatorParams} from '#/lib/routes/types'
@@ -24,7 +24,7 @@ import {
usePreferencesQuery, usePreferencesQuery,
usePreferencesSetAdultContentMutation, usePreferencesSetAdultContentMutation,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {useModServicesDetailedInfoQuery} from '#/state/queries/modservice' import {useLabelersDetailedInfoQuery} from '#/state/queries/labeler'
import {useTheme, atoms as a, useBreakpoints} from '#/alf' import {useTheme, atoms as a, useBreakpoints} from '#/alf'
import {Divider} from '#/components/Divider' import {Divider} from '#/components/Divider'
@@ -85,7 +85,7 @@ export function ModerationScreen(
isLoading: isModServicesLoading, isLoading: isModServicesLoading,
data: modservices, data: modservices,
error: modservicesError, error: modservicesError,
} = useModServicesDetailedInfoQuery({ } = useLabelersDetailedInfoQuery({
dids: preferences ? preferences.moderationPrefs.mods.map(m => m.did) : [], dids: preferences ? preferences.moderationPrefs.mods.map(m => m.did) : [],
}) })
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
@@ -131,7 +131,7 @@ export function ModerationScreenInner({
modservices, modservices,
}: { }: {
preferences: UsePreferencesQueryResponse preferences: UsePreferencesQueryResponse
modservices: AppBskyModerationDefs.ModServiceViewDetailed[] modservices: AppBskyLabelerDefs.LabelerViewDetailed[]
}) { }) {
const t = useTheme() const t = useTheme()
const setMinimalShellMode = useSetMinimalShellMode() const setMinimalShellMode = useSetMinimalShellMode()
+2 -2
View File
@@ -154,7 +154,7 @@ export function ProfileHeaderDropdownBtn({
const dropdownItems: DropdownItem[] = React.useMemo(() => { const dropdownItems: DropdownItem[] = React.useMemo(() => {
let items: DropdownItem[] = [] let items: DropdownItem[] = []
if (hasSession && profile.associated?.modservice) { if (hasSession && profile.associated?.labeler) {
items.push({ items.push({
testID: 'profileHeaderDropdownFollowBtn', testID: 'profileHeaderDropdownFollowBtn',
label: _(msg`Follow Account`), label: _(msg`Follow Account`),
@@ -251,7 +251,7 @@ export function ProfileHeaderDropdownBtn({
}, [ }, [
isMe, isMe,
hasSession, hasSession,
profile.associated?.modservice, profile.associated?.labeler,
profile.viewer?.muted, profile.viewer?.muted,
profile.viewer?.mutedByList, profile.viewer?.mutedByList,
profile.viewer?.blocking, profile.viewer?.blocking,
+1 -3
View File
@@ -18,9 +18,7 @@ export function ProfileHeaderHandle({
const blockHide = profile.viewer?.blocking || profile.viewer?.blockedBy const blockHide = profile.viewer?.blocking || profile.viewer?.blockedBy
return ( return (
<View style={[a.flex_row, a.gap_xs, a.align_center]} pointerEvents="none"> <View style={[a.flex_row, a.gap_xs, a.align_center]} pointerEvents="none">
{profile.viewer?.followedBy && {profile.viewer?.followedBy && !blockHide ? (
!blockHide &&
!profile.associated?.modservice ? (
<View style={[t.atoms.bg_contrast_50, a.rounded_xs, a.px_sm, a.py_xs]}> <View style={[t.atoms.bg_contrast_50, a.rounded_xs, a.px_sm, a.py_xs]}>
<Text style={[t.atoms.text, a.text_sm]}> <Text style={[t.atoms.text, a.text_sm]}>
<Trans>Follows you</Trans> <Trans>Follows you</Trans>
@@ -2,7 +2,7 @@ import React, {memo, useMemo} from 'react'
import {View} from 'react-native' import {View} from 'react-native'
import { import {
AppBskyActorDefs, AppBskyActorDefs,
AppBskyModerationDefs, AppBskyLabelerDefs,
ModerationOpts, ModerationOpts,
moderateProfile, moderateProfile,
RichText as RichTextAPI, RichText as RichTextAPI,
@@ -16,7 +16,7 @@ import {useAnalytics} from 'lib/analytics/analytics'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {Shadow} from '#/state/cache/types' import {Shadow} from '#/state/cache/types'
import {useProfileShadow} from 'state/cache/profile-shadow' import {useProfileShadow} from 'state/cache/profile-shadow'
import {useModServiceSubscriptionMutation} from '#/state/queries/modservice' import {useLabelerSubscriptionMutation} from '#/state/queries/labeler'
import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like' import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
import {logger} from '#/logger' import {logger} from '#/logger'
import {Haptics} from '#/lib/haptics' import {Haptics} from '#/lib/haptics'
@@ -38,7 +38,7 @@ import {
interface Props { interface Props {
profile: AppBskyActorDefs.ProfileViewDetailed profile: AppBskyActorDefs.ProfileViewDetailed
modservice: AppBskyModerationDefs.ModServiceViewDetailed modservice: AppBskyLabelerDefs.LabelerViewDetailed
descriptionRT: RichTextAPI | null descriptionRT: RichTextAPI | null
moderationOpts: ModerationOpts moderationOpts: ModerationOpts
hideBackButton?: boolean hideBackButton?: boolean
@@ -66,7 +66,7 @@ let ProfileHeaderModerator = ({
) )
const {data: preferences} = usePreferencesQuery() const {data: preferences} = usePreferencesQuery()
const {mutateAsync: toggleSubscription, variables} = const {mutateAsync: toggleSubscription, variables} =
useModServiceSubscriptionMutation() useLabelerSubscriptionMutation()
const isSubscribed = const isSubscribed =
variables?.subscribe ?? variables?.subscribe ??
preferences?.moderationPrefs.mods.find(mod => mod.did === profile.did) preferences?.moderationPrefs.mods.find(mod => mod.did === profile.did)
+2 -2
View File
@@ -113,10 +113,10 @@ let ProfileHeaderShell = ({
t.atoms.bg, t.atoms.bg,
{borderColor: t.atoms.bg.backgroundColor}, {borderColor: t.atoms.bg.backgroundColor},
styles.avi, styles.avi,
profile.associated?.modservice && styles.aviLabeler, profile.associated?.labeler && styles.aviLabeler,
]}> ]}>
<UserAvatar <UserAvatar
type={profile.associated?.modservice ? 'labeler' : 'user'} type={profile.associated?.labeler ? 'labeler' : 'user'}
size={90} size={90}
avatar={profile.avatar} avatar={profile.avatar}
moderation={moderation.ui('avatar')} moderation={moderation.ui('avatar')}
+3 -3
View File
@@ -2,7 +2,7 @@ import React, {memo} from 'react'
import {StyleSheet, View} from 'react-native' import {StyleSheet, View} from 'react-native'
import { import {
AppBskyActorDefs, AppBskyActorDefs,
AppBskyModerationDefs, AppBskyLabelerDefs,
ModerationOpts, ModerationOpts,
RichText as RichTextAPI, RichText as RichTextAPI,
} from '@atproto/api' } from '@atproto/api'
@@ -34,7 +34,7 @@ export {ProfileHeaderLoading}
interface Props { interface Props {
profile: AppBskyActorDefs.ProfileViewDetailed profile: AppBskyActorDefs.ProfileViewDetailed
modservice: AppBskyModerationDefs.ModServiceViewDetailed | undefined modservice: AppBskyLabelerDefs.LabelerViewDetailed | undefined
descriptionRT: RichTextAPI | null descriptionRT: RichTextAPI | null
moderationOpts: ModerationOpts moderationOpts: ModerationOpts
hideBackButton?: boolean hideBackButton?: boolean
@@ -42,7 +42,7 @@ interface Props {
} }
let ProfileHeader = (props: Props): React.ReactNode => { let ProfileHeader = (props: Props): React.ReactNode => {
if (props.profile.associated?.modservice) { if (props.profile.associated?.labeler) {
if (!props.modservice) { if (!props.modservice) {
return <ProfileHeaderLoading /> return <ProfileHeaderLoading />
} }
@@ -1,11 +1,11 @@
import React from 'react' import React from 'react'
import {View} from 'react-native' import {View} from 'react-native'
import {AppBskyModerationDefs, ModerationOpts} from '@atproto/api' import {AppBskyLabelerDefs, ModerationOpts} from '@atproto/api'
import {Trans, msg} from '@lingui/macro' import {Trans, msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useSafeAreaFrame} from 'react-native-safe-area-context' import {useSafeAreaFrame} from 'react-native-safe-area-context'
import {useModServiceSubscriptionMutation} from '#/state/queries/modservice' import {useLabelerSubscriptionMutation} from '#/state/queries/labeler'
import {logger} from '#/logger' import {logger} from '#/logger'
import {useTheme, atoms as a} from '#/alf' import {useTheme, atoms as a} from '#/alf'
@@ -22,7 +22,7 @@ export function ProfileContentFiltersSection({
moderationOpts, moderationOpts,
}: { }: {
modServiceQuery: { modServiceQuery: {
data: AppBskyModerationDefs.ModServiceViewDetailed | undefined data: AppBskyLabelerDefs.LabelerViewDetailed | undefined
isLoading: boolean isLoading: boolean
error: Error | null error: Error | null
} }
@@ -71,7 +71,7 @@ export function ProfileContentFiltersSectionInner({
modservice, modservice,
}: { }: {
moderationOpts: ModerationOpts moderationOpts: ModerationOpts
modservice: AppBskyModerationDefs.ModServiceViewDetailed modservice: AppBskyLabelerDefs.LabelerViewDetailed
}) { }) {
const {_} = useLingui() const {_} = useLingui()
const t = useTheme() const t = useTheme()
@@ -81,7 +81,7 @@ export function ProfileContentFiltersSectionInner({
const hasSession = true // TODO const hasSession = true // TODO
const {mutateAsync: toggleSubscription, variables} = const {mutateAsync: toggleSubscription, variables} =
useModServiceSubscriptionMutation() useLabelerSubscriptionMutation()
const isSubscribed = const isSubscribed =
variables?.subscribe ?? variables?.subscribe ??
moderationOpts.prefs.mods.find(mod => mod.did === modservice.creator.did) moderationOpts.prefs.mods.find(mod => mod.did === modservice.creator.did)
@@ -1,21 +1,18 @@
import {z} from 'zod' import {z} from 'zod'
import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query' import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query'
import {AppBskyModerationDefs} from '@atproto/api' import {AppBskyLabelerDefs} from '@atproto/api'
import {getAgent} from '#/state/session' import {getAgent} from '#/state/session'
import {preferencesQueryKey} from '#/state/queries/preferences' import {preferencesQueryKey} from '#/state/queries/preferences'
export const modServiceInfoQueryKey = (did: string) => ['mod-service-info', did] export const labelerInfoQueryKey = (did: string) => ['labeler-info', did]
export const modServicesInfoQueryKey = (dids: string[]) => [ export const labelersInfoQueryKey = (dids: string[]) => ['labelers-info', dids]
'mod-services-info', export const labelersDetailedInfoQueryKey = (dids: string[]) => [
dids, 'labelers-detailed-info',
]
export const modServicesDetailedInfoQueryKey = (dids: string[]) => [
'mod-services-detailed-info',
dids, dids,
] ]
export function useModServiceInfoQuery({ export function useLabelerInfoQuery({
did, did,
enabled, enabled,
}: { }: {
@@ -24,43 +21,43 @@ export function useModServiceInfoQuery({
}) { }) {
return useQuery({ return useQuery({
enabled: !!did && enabled !== false, enabled: !!did && enabled !== false,
queryKey: modServiceInfoQueryKey(did as string), queryKey: labelerInfoQueryKey(did as string),
queryFn: async () => { queryFn: async () => {
const res = await getAgent().app.bsky.moderation.getServices({ const res = await getAgent().app.bsky.labeler.getServices({
dids: [did as string], dids: [did as string],
detailed: true, detailed: true,
}) })
return res.data.views[0] as AppBskyModerationDefs.ModServiceViewDetailed return res.data.views[0] as AppBskyLabelerDefs.LabelerViewDetailed
}, },
}) })
} }
export function useModServicesInfoQuery({dids}: {dids: string[]}) { export function useLabelersInfoQuery({dids}: {dids: string[]}) {
return useQuery({ return useQuery({
enabled: !!dids.length, enabled: !!dids.length,
queryKey: modServicesInfoQueryKey(dids), queryKey: labelersInfoQueryKey(dids),
queryFn: async () => { queryFn: async () => {
const res = await getAgent().app.bsky.moderation.getServices({dids}) const res = await getAgent().app.bsky.labeler.getServices({dids})
return res.data.views as AppBskyModerationDefs.ModServiceView[] return res.data.views as AppBskyLabelerDefs.LabelerView[]
}, },
}) })
} }
export function useModServicesDetailedInfoQuery({dids}: {dids: string[]}) { export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) {
return useQuery({ return useQuery({
enabled: !!dids.length, enabled: !!dids.length,
queryKey: modServicesDetailedInfoQueryKey(dids), queryKey: labelersDetailedInfoQueryKey(dids),
queryFn: async () => { queryFn: async () => {
const res = await getAgent().app.bsky.moderation.getServices({ const res = await getAgent().app.bsky.labeler.getServices({
dids, dids,
detailed: true, detailed: true,
}) })
return res.data.views as AppBskyModerationDefs.ModServiceViewDetailed[] return res.data.views as AppBskyLabelerDefs.LabelerViewDetailed[]
}, },
}) })
} }
export function useModServiceSubscriptionMutation() { export function useLabelerSubscriptionMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
return useMutation({ return useMutation({
+9 -13
View File
@@ -36,7 +36,7 @@ import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useSession, getAgent} from '#/state/session' import {useSession, getAgent} from '#/state/session'
import {useModerationOpts} from '#/state/queries/preferences' import {useModerationOpts} from '#/state/queries/preferences'
import {useProfileExtraInfoQuery} from '#/state/queries/profile-extra-info' import {useProfileExtraInfoQuery} from '#/state/queries/profile-extra-info'
import {useModServiceInfoQuery} from '#/state/queries/modservice' import {useLabelerInfoQuery} from '#/state/queries/labeler'
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from '#/state/shell' import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from '#/state/shell'
import {cleanError} from '#/lib/strings/errors' import {cleanError} from '#/lib/strings/errors'
@@ -118,10 +118,6 @@ export function ProfileScreen({route}: Props) {
) )
} }
if (profile && moderationOpts) { if (profile && moderationOpts) {
if (profile.handle === 'alice.test') {
// TODO removeme
profile.associated = {modservice: true, lists: 1}
}
return ( return (
<ProfileScreenLoadedV2 <ProfileScreenLoadedV2
profile={profile} profile={profile}
@@ -451,9 +447,9 @@ function ProfileScreenLoadedV2({
const setMinimalShellMode = useSetMinimalShellMode() const setMinimalShellMode = useSetMinimalShellMode()
const {openComposer} = useComposerControls() const {openComposer} = useComposerControls()
const {screen, track} = useAnalytics() const {screen, track} = useAnalytics()
const modServiceQuery = useModServiceInfoQuery({ const modServiceQuery = useLabelerInfoQuery({
did: profile.did, did: profile.did,
enabled: !!profile.associated?.modservice, enabled: !!profile.associated?.labeler,
}) })
const [currentPage, setCurrentPage] = React.useState(0) const [currentPage, setCurrentPage] = React.useState(0)
const {_} = useLingui() const {_} = useLingui()
@@ -478,10 +474,10 @@ function ProfileScreenLoadedV2({
) )
const isMe = profile.did === currentAccount?.did const isMe = profile.did === currentAccount?.did
const showFiltersTab = hasSession && profile.associated?.modservice const showFiltersTab = hasSession && profile.associated?.labeler
const showPostsTab = true const showPostsTab = true
const showRepliesTab = hasSession const showRepliesTab = hasSession
const showMediaTab = !profile.associated?.modservice const showMediaTab = !profile.associated?.labeler
const showLikesTab = isMe const showLikesTab = isMe
const showFeedsTab = const showFeedsTab =
hasSession && (isMe || (profile.associated?.feedgens || 0) > 0) hasSession && (isMe || (profile.associated?.feedgens || 0) > 0)
@@ -520,7 +516,7 @@ function ProfileScreenLoadedV2({
if (showFiltersTab) { if (showFiltersTab) {
filtersIndex = nextIndex++ filtersIndex = nextIndex++
} }
if (showListsTab && profile.associated?.modservice) { if (showListsTab && profile.associated?.labeler) {
listsIndex = nextIndex++ listsIndex = nextIndex++
} }
if (showPostsTab) { if (showPostsTab) {
@@ -538,7 +534,7 @@ function ProfileScreenLoadedV2({
if (showFeedsTab) { if (showFeedsTab) {
feedsIndex = nextIndex++ feedsIndex = nextIndex++
} }
if (showListsTab && !profile.associated?.modservice) { if (showListsTab && !profile.associated?.labeler) {
listsIndex = nextIndex++ listsIndex = nextIndex++
} }
@@ -666,7 +662,7 @@ function ProfileScreenLoadedV2({
/> />
) )
: null} : null}
{showListsTab && !!profile.associated?.modservice {showListsTab && !!profile.associated?.labeler
? ({headerHeight, isFocused, scrollElRef}) => ( ? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileLists <ProfileLists
ref={listsSectionRef} ref={listsSectionRef}
@@ -736,7 +732,7 @@ function ProfileScreenLoadedV2({
/> />
) )
: null} : null}
{showListsTab && !profile.associated?.modservice {showListsTab && !profile.associated?.labeler
? ({headerHeight, isFocused, scrollElRef}) => ( ? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileLists <ProfileLists
ref={listsSectionRef} ref={listsSectionRef}