Experiment to put labeling under a tab of a normal profile

This commit is contained in:
Paul Frazee
2024-02-27 14:33:57 -08:00
parent 6b9e3764b3
commit 697b262ba4
4 changed files with 94 additions and 45 deletions
-7
View File
@@ -43,13 +43,6 @@ export function ProfileHeaderHandle({
]}> ]}>
{invalidHandle ? <Trans>⚠Invalid Handle</Trans> : `@${profile.handle}`} {invalidHandle ? <Trans>⚠Invalid Handle</Trans> : `@${profile.handle}`}
</Text> </Text>
{profile.associated?.modservice ? (
<View style={[t.atoms.bg_contrast_50, a.rounded_xs, a.px_sm, a.py_xs]}>
<Text style={[t.atoms.text, a.text_sm]}>
<Trans>Moderation service</Trans>
</Text>
</View>
) : undefined}
</View> </View>
) )
} }
+6 -6
View File
@@ -42,12 +42,12 @@ interface Props {
} }
let ProfileHeader = (props: Props): React.ReactNode => { let ProfileHeader = (props: Props): React.ReactNode => {
if (props.profile.associated?.modservice) { // if (props.profile.associated?.modservice) {
if (!props.modservice) { // if (!props.modservice) {
return <ProfileHeaderLoading /> // return <ProfileHeaderLoading />
} // }
return <ProfileHeaderModerator {...props} modservice={props.modservice} /> // return <ProfileHeaderModerator {...props} modservice={props.modservice} />
} // }
return <ProfileHeaderStandard {...props} /> return <ProfileHeaderStandard {...props} />
} }
ProfileHeader = memo(ProfileHeader) ProfileHeader = memo(ProfileHeader)
@@ -5,13 +5,15 @@ 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 {useSetTitle} from '#/lib/hooks/useSetTitle' import {useModServiceSubscriptionMutation} from '#/state/queries/modservice'
import {getLabelGroupsFromLabels} from '#/lib/moderation' import {getLabelGroupsFromLabels} from '#/lib/moderation'
import {logger} from '#/logger'
import {useTheme, atoms as a} from '#/alf' import {useTheme, atoms as a} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import {Loader} from '#/components/Loader' import {Loader} from '#/components/Loader'
import {Divider} from '#/components/Divider' import {Divider} from '#/components/Divider'
import {Button, ButtonText} from '#/components/Button'
import {CenteredView, ScrollView} from '#/view/com/util/Views' import {CenteredView, ScrollView} from '#/view/com/util/Views'
import {ErrorState} from '../ErrorState' import {ErrorState} from '../ErrorState'
import {ModerationLabelPref} from '#/components/ModerationLabelPref' import {ModerationLabelPref} from '#/components/ModerationLabelPref'
@@ -72,6 +74,7 @@ export function ProfileContentFiltersSectionInner({
moderationOpts: ModerationOpts moderationOpts: ModerationOpts
modservice: AppBskyModerationDefs.ModServiceViewDetailed modservice: AppBskyModerationDefs.ModServiceViewDetailed
}) { }) {
const {_} = useLingui()
const t = useTheme() const t = useTheme()
const groups = React.useMemo(() => { const groups = React.useMemo(() => {
return getLabelGroupsFromLabels(modservice.policies.labelValues).filter( return getLabelGroupsFromLabels(modservice.policies.labelValues).filter(
@@ -83,8 +86,25 @@ export function ProfileContentFiltersSectionInner({
mod => mod.did === modservice.creator.did && mod.enabled, mod => mod.did === modservice.creator.did && mod.enabled,
), ),
) )
const hasSession = true // TODO
useSetTitle(modservice.creator.displayName || modservice.creator.handle) const {mutateAsync: toggleSubscription, variables} =
useModServiceSubscriptionMutation()
const isSubscribed =
variables?.subscribe ??
moderationOpts.mods.find(mod => mod.did === modservice.creator.did)
const onPressSubscribe = React.useCallback(async () => {
try {
await toggleSubscription({
did: modservice.creator.did,
subscribe: !isSubscribed,
})
} catch (e: any) {
// setSubscriptionError(e.message)
logger.error(`Failed to subscribe to labeler`, {message: e.message})
}
}, [toggleSubscription, isSubscribed, modservice])
return ( return (
<ScrollView <ScrollView
@@ -93,6 +113,15 @@ export function ProfileContentFiltersSectionInner({
borderWidth: 0, borderWidth: 0,
paddingHorizontal: a.px_xl.paddingLeft, paddingHorizontal: a.px_xl.paddingLeft,
}}> }}>
<View style={[a.flex_row, a.gap_md, a.pt_xl]}>
<View style={[a.flex_1]}>
<Text style={[t.atoms.text_contrast_high, a.leading_snug, a.text_md]}>
<Trans>
Labels are annotations on users and content. They can be used to
hide, warn, and categorize the network.
</Trans>
</Text>
{!isSubscribed && (
<Text <Text
style={[ style={[
a.pt_xl, a.pt_xl,
@@ -100,8 +129,36 @@ export function ProfileContentFiltersSectionInner({
a.leading_snug, a.leading_snug,
a.text_md, a.text_md,
]}> ]}>
<Trans>This service labels the following types of content.</Trans> <Trans>
Subscribe to use these labels from @{modservice.creator.handle}:
</Trans>
</Text> </Text>
)}
</View>
<View>
<Button
testID="toggleSubscribeBtn"
size="small"
color={isSubscribed ? 'secondary' : 'primary'}
variant="solid"
label={
isSubscribed
? _(msg`Unsubscribe from this labeler`)
: _(msg`Subscribe to this labeler`)
}
disabled={!hasSession}
onPress={onPressSubscribe}
style={a.rounded_full}>
<ButtonText>
{isSubscribed ? (
<Trans>Unsubscribe</Trans>
) : (
<Trans>Subscribe</Trans>
)}
</ButtonText>
</Button>
</View>
</View>
<View <View
style={[ style={[
a.mt_xl, a.mt_xl,
+20 -21
View File
@@ -477,12 +477,11 @@ function ProfileScreenLoadedV2({
) )
const isMe = profile.did === currentAccount?.did const isMe = profile.did === currentAccount?.did
const isModService = !!profile.associated?.modservice
const showFiltersTab = hasSession && profile.associated?.modservice const showFiltersTab = hasSession && profile.associated?.modservice
const showPostsTab = !isModService const showPostsTab = true
const showRepliesTab = hasSession && !isModService const showRepliesTab = hasSession
const showMediaTab = !isModService const showMediaTab = true
const showLikesTab = isMe && !isModService const showLikesTab = isMe
const showFeedsTab = const showFeedsTab =
hasSession && (isMe || (profile.associated?.feedgens || 0) > 0) hasSession && (isMe || (profile.associated?.feedgens || 0) > 0)
const showListsTab = const showListsTab =
@@ -490,12 +489,12 @@ function ProfileScreenLoadedV2({
const sectionTitles = useMemo<string[]>(() => { const sectionTitles = useMemo<string[]>(() => {
return [ return [
showFiltersTab ? _(msg`Content filters`) : undefined,
showPostsTab ? _(msg`Posts`) : undefined, showPostsTab ? _(msg`Posts`) : undefined,
showRepliesTab ? _(msg`Replies`) : undefined, showRepliesTab ? _(msg`Replies`) : undefined,
showMediaTab ? _(msg`Media`) : undefined, showMediaTab ? _(msg`Media`) : undefined,
showLikesTab ? _(msg`Likes`) : undefined, showLikesTab ? _(msg`Likes`) : undefined,
showFeedsTab ? _(msg`Feeds`) : undefined, showFeedsTab ? _(msg`Feeds`) : undefined,
showFiltersTab ? _(msg`Labels`) : undefined,
showListsTab ? _(msg`Lists`) : undefined, showListsTab ? _(msg`Lists`) : undefined,
].filter(Boolean) as string[] ].filter(Boolean) as string[]
}, [ }, [
@@ -511,9 +510,6 @@ function ProfileScreenLoadedV2({
let nextIndex = 0 let nextIndex = 0
let filtersIndex: number | null = null let filtersIndex: number | null = null
if (showFiltersTab) {
filtersIndex = nextIndex++
}
let postsIndex: number | null = null let postsIndex: number | null = null
if (showPostsTab) { if (showPostsTab) {
postsIndex = nextIndex++ postsIndex = nextIndex++
@@ -534,6 +530,9 @@ function ProfileScreenLoadedV2({
if (showFeedsTab) { if (showFeedsTab) {
feedsIndex = nextIndex++ feedsIndex = nextIndex++
} }
if (showFiltersTab) {
filtersIndex = nextIndex++
}
let listsIndex: number | null = null let listsIndex: number | null = null
if (showListsTab) { if (showListsTab) {
listsIndex = nextIndex++ listsIndex = nextIndex++
@@ -651,18 +650,6 @@ function ProfileScreenLoadedV2({
onPageSelected={onPageSelected} onPageSelected={onPageSelected}
onCurrentPageSelected={onCurrentPageSelected} onCurrentPageSelected={onCurrentPageSelected}
renderHeader={renderHeader}> renderHeader={renderHeader}>
{showFiltersTab
? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileContentFiltersSection
// ref={moderationSectionRef}
modServiceQuery={modServiceQuery}
moderationOpts={moderationOpts}
scrollElRef={scrollElRef as ListRef}
headerOffset={headerHeight}
enabled={isFocused}
/>
)
: null}
{showPostsTab {showPostsTab
? ({headerHeight, isFocused, scrollElRef}) => ( ? ({headerHeight, isFocused, scrollElRef}) => (
<FeedSection <FeedSection
@@ -722,6 +709,18 @@ function ProfileScreenLoadedV2({
/> />
) )
: null} : null}
{showFiltersTab
? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileContentFiltersSection
// ref={moderationSectionRef}
modServiceQuery={modServiceQuery}
moderationOpts={moderationOpts}
scrollElRef={scrollElRef as ListRef}
headerOffset={headerHeight}
enabled={isFocused}
/>
)
: null}
{showListsTab {showListsTab
? ({headerHeight, isFocused, scrollElRef}) => ( ? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileLists <ProfileLists