Hook up data to settings page
This commit is contained in:
+22
-1
@@ -1,4 +1,10 @@
|
|||||||
import {ModerationCause, ProfileModeration, PostModeration} from '@atproto/api'
|
import {
|
||||||
|
ModerationCause,
|
||||||
|
ProfileModeration,
|
||||||
|
PostModeration,
|
||||||
|
LABEL_GROUPS,
|
||||||
|
LabelGroupDefinition,
|
||||||
|
} from '@atproto/api'
|
||||||
|
|
||||||
export function getProfileModerationCauses(
|
export function getProfileModerationCauses(
|
||||||
moderation: ProfileModeration,
|
moderation: ProfileModeration,
|
||||||
@@ -70,3 +76,18 @@ export function getModerationCauseKey(cause: ModerationCause): string {
|
|||||||
}
|
}
|
||||||
return `${cause.type}:${source}`
|
return `${cause.type}:${source}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLabelGroupsFromLabels(labels: string[]) {
|
||||||
|
const groups: LabelGroupDefinition[] = []
|
||||||
|
|
||||||
|
for (const label of labels) {
|
||||||
|
for (const group in LABEL_GROUPS) {
|
||||||
|
const def = LABEL_GROUPS[group as LabelGroupDefinition['id']]
|
||||||
|
if (def.labels.find(l => l.id === label)) {
|
||||||
|
groups.push(def)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(groups)
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ import {Bars3_Stroke2_Corner0_Rounded as Bars} from '#/components/icons/Bars'
|
|||||||
import {Divider} from '#/components/Divider'
|
import {Divider} from '#/components/Divider'
|
||||||
|
|
||||||
export function Header({
|
export function Header({
|
||||||
info,
|
modservice,
|
||||||
}: {
|
}: {
|
||||||
info: AppBskyModerationDefs.ModServiceViewDetailed
|
modservice: AppBskyModerationDefs.ModServiceViewDetailed
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {gtMobile} = useBreakpoints()
|
const {gtMobile} = useBreakpoints()
|
||||||
@@ -81,7 +81,7 @@ export function Header({
|
|||||||
</ButtonText>
|
</ButtonText>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<CommonControls info={info} />
|
<CommonControls modservice={modservice} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
@@ -98,8 +98,8 @@ export function Header({
|
|||||||
a.overflow_hidden,
|
a.overflow_hidden,
|
||||||
]}>
|
]}>
|
||||||
<LinearGradient
|
<LinearGradient
|
||||||
colors={tokens.gradients.bonfire.values.map(c => c[1])}
|
colors={tokens.gradients.midnight.values.map(c => c[1])}
|
||||||
locations={tokens.gradients.bonfire.values.map(c => c[0])}
|
locations={tokens.gradients.midnight.values.map(c => c[0])}
|
||||||
start={{x: 0, y: 0}}
|
start={{x: 0, y: 0}}
|
||||||
end={{x: 1, y: 1}}
|
end={{x: 1, y: 1}}
|
||||||
style={[a.absolute, a.inset_0]}
|
style={[a.absolute, a.inset_0]}
|
||||||
@@ -115,10 +115,11 @@ export function Header({
|
|||||||
onPress={emitSoftReset}
|
onPress={emitSoftReset}
|
||||||
style={[a.justify_start]}>
|
style={[a.justify_start]}>
|
||||||
<Text style={[a.text_4xl, a.font_bold, t.atoms.text]}>
|
<Text style={[a.text_4xl, a.font_bold, t.atoms.text]}>
|
||||||
{/* A really long and complex title for a moderation service */}
|
{modservice.displayName
|
||||||
{info.creator.displayName
|
? sanitizeDisplayName(modservice.displayName)
|
||||||
? sanitizeDisplayName(info.creator.displayName)
|
: modservice.creator.displayName
|
||||||
: sanitizeHandle(info.creator.handle, '@')}
|
? sanitizeDisplayName(modservice.creator.displayName)
|
||||||
|
: sanitizeHandle(modservice.creator.handle, '@')}
|
||||||
</Text>
|
</Text>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
@@ -139,7 +140,7 @@ export function Header({
|
|||||||
</ButtonText>
|
</ButtonText>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<CommonControls info={info} />
|
<CommonControls modservice={modservice} />
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
@@ -148,9 +149,9 @@ export function Header({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function CommonControls({
|
function CommonControls({
|
||||||
info,
|
modservice,
|
||||||
}: {
|
}: {
|
||||||
info: AppBskyModerationDefs.ModServiceViewDetailed
|
modservice: AppBskyModerationDefs.ModServiceViewDetailed
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
@@ -158,19 +159,19 @@ function CommonControls({
|
|||||||
const {openModal} = useModalControls()
|
const {openModal} = useModalControls()
|
||||||
|
|
||||||
const onPressShare = React.useCallback(() => {
|
const onPressShare = React.useCallback(() => {
|
||||||
const url = makeProfileLink(info.creator, 'modservice')
|
const url = makeProfileLink(modservice.creator, 'modservice')
|
||||||
shareUrl(url)
|
shareUrl(url)
|
||||||
// track('CustomFeed:Share') TODO
|
// track('CustomFeed:Share') TODO
|
||||||
}, [info /*, track*/])
|
}, [modservice /*, track*/])
|
||||||
|
|
||||||
const onPressReport = React.useCallback(() => {
|
const onPressReport = React.useCallback(() => {
|
||||||
if (!info) return
|
if (!modservice) return
|
||||||
openModal({
|
openModal({
|
||||||
name: 'report',
|
name: 'report',
|
||||||
uri: info.uri,
|
uri: modservice.uri,
|
||||||
cid: info.cid,
|
cid: modservice.cid,
|
||||||
})
|
})
|
||||||
}, [openModal, info])
|
}, [openModal, modservice])
|
||||||
|
|
||||||
const dropdownItems: DropdownItem[] = React.useMemo(() => {
|
const dropdownItems: DropdownItem[] = React.useMemo(() => {
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {Dimensions, View} from 'react-native'
|
import {Dimensions, View} from 'react-native'
|
||||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||||
import {AppBskyModerationDefs, LabelGroupDefinition} from '@atproto/api'
|
import {AppBskyModerationDefs} 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 {LABEL_GROUPS} from '@atproto/api'
|
|
||||||
|
|
||||||
import {usePalette} from '#/lib/hooks/usePalette'
|
import {usePalette} from '#/lib/hooks/usePalette'
|
||||||
import {CommonNavigatorParams} from '#/lib/routes/types'
|
import {CommonNavigatorParams} from '#/lib/routes/types'
|
||||||
@@ -28,6 +27,8 @@ import {useSession} from '#/state/session'
|
|||||||
import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
|
import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
|
|
||||||
|
import {getLabelGroupsFromLabels} from '#/lib/moderation'
|
||||||
|
|
||||||
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'
|
||||||
@@ -108,7 +109,7 @@ function ProfileModservicecreenIntermediate({modDid}: {modDid: string}) {
|
|||||||
<Loader size="xl" fill={t.atoms.text.color} />
|
<Loader size="xl" fill={t.atoms.text.color} />
|
||||||
</View>
|
</View>
|
||||||
) : preferences && info ? (
|
) : preferences && info ? (
|
||||||
<ProfileModserviceScreenInner preferences={preferences} modInfo={info} />
|
<ProfileModserviceScreenInner preferences={preferences} modservice={info} />
|
||||||
) : (
|
) : (
|
||||||
<ErrorState
|
<ErrorState
|
||||||
error={
|
error={
|
||||||
@@ -120,10 +121,10 @@ function ProfileModservicecreenIntermediate({modDid}: {modDid: string}) {
|
|||||||
|
|
||||||
export function ProfileModserviceScreenInner({
|
export function ProfileModserviceScreenInner({
|
||||||
// preferences,
|
// preferences,
|
||||||
modInfo,
|
modservice,
|
||||||
}: {
|
}: {
|
||||||
preferences: UsePreferencesQueryResponse
|
preferences: UsePreferencesQueryResponse
|
||||||
modInfo: AppBskyModerationDefs.ModServiceViewDetailed
|
modservice: AppBskyModerationDefs.ModServiceViewDetailed
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
@@ -134,13 +135,13 @@ export function ProfileModserviceScreenInner({
|
|||||||
const {mutateAsync: unlikeMod, isPending: isUnlikePending} =
|
const {mutateAsync: unlikeMod, isPending: isUnlikePending} =
|
||||||
useUnlikeMutation()
|
useUnlikeMutation()
|
||||||
const [likeUri, setLikeUri] = React.useState<string>(
|
const [likeUri, setLikeUri] = React.useState<string>(
|
||||||
modInfo.viewer?.like || '',
|
modservice.viewer?.like || '',
|
||||||
)
|
)
|
||||||
const groups = React.useMemo<
|
const groups = React.useMemo(() => {
|
||||||
[keyof typeof LABEL_GROUPS, LabelGroupDefinition][]
|
return getLabelGroupsFromLabels(modservice.policies.labelValues).filter(
|
||||||
>(() => {
|
def => def.configurable,
|
||||||
return Object.entries(LABEL_GROUPS).filter(([, def]) => def.configurable)
|
)
|
||||||
}, [])
|
}, [modservice.policies.labelValues])
|
||||||
|
|
||||||
const isLiked = !!likeUri
|
const isLiked = !!likeUri
|
||||||
// const isSaved = false // TODO
|
// const isSaved = false // TODO
|
||||||
@@ -150,7 +151,7 @@ export function ProfileModserviceScreenInner({
|
|||||||
// !unpinnedFeed &&
|
// !unpinnedFeed &&
|
||||||
// (!!pinnedFeed || preferences.feeds.pinned.includes(feedInfo.uri))
|
// (!!pinnedFeed || preferences.feeds.pinned.includes(feedInfo.uri))
|
||||||
|
|
||||||
useSetTitle(modInfo.creator.displayName || modInfo.creator.handle)
|
useSetTitle(modservice.creator.displayName || modservice.creator.handle)
|
||||||
|
|
||||||
// event handlers
|
// event handlers
|
||||||
//
|
//
|
||||||
@@ -163,7 +164,7 @@ export function ProfileModserviceScreenInner({
|
|||||||
track('CustomFeed:Unlike')
|
track('CustomFeed:Unlike')
|
||||||
setLikeUri('')
|
setLikeUri('')
|
||||||
} else {
|
} else {
|
||||||
const res = await likeMod({uri: modInfo.uri, cid: modInfo.cid})
|
const res = await likeMod({uri: modservice.uri, cid: modservice.cid})
|
||||||
track('CustomFeed:Like')
|
track('CustomFeed:Like')
|
||||||
setLikeUri(res.uri)
|
setLikeUri(res.uri)
|
||||||
}
|
}
|
||||||
@@ -175,7 +176,7 @@ export function ProfileModserviceScreenInner({
|
|||||||
)
|
)
|
||||||
logger.error('Failed up toggle like', {error: err})
|
logger.error('Failed up toggle like', {error: err})
|
||||||
}
|
}
|
||||||
}, [likeUri, isLiked, modInfo, likeMod, unlikeMod, track, _])
|
}, [likeUri, isLiked, modservice, likeMod, unlikeMod, track, _])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView
|
<ScrollView
|
||||||
@@ -185,14 +186,14 @@ export function ProfileModserviceScreenInner({
|
|||||||
borderWidth: 0,
|
borderWidth: 0,
|
||||||
paddingHorizontal: a.px_xl.paddingLeft,
|
paddingHorizontal: a.px_xl.paddingLeft,
|
||||||
}}>
|
}}>
|
||||||
<Header info={modInfo} />
|
<Header modservice={modservice} />
|
||||||
|
|
||||||
<View style={[a.gap_md]}>
|
<View style={[a.gap_md]}>
|
||||||
{modInfo.description ? (
|
{modservice.description ? (
|
||||||
<RichText
|
<RichText
|
||||||
testID="modinfoDescription"
|
testID="modinfoDescription"
|
||||||
resolveFacets
|
resolveFacets
|
||||||
value={modInfo.description}
|
value={modservice.description}
|
||||||
style={[a.text_md, a.leading_normal]}
|
style={[a.text_md, a.leading_normal]}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -203,7 +204,9 @@ export function ProfileModserviceScreenInner({
|
|||||||
t.atoms.text_contrast_medium,
|
t.atoms.text_contrast_medium,
|
||||||
{fontStyle: 'italic'},
|
{fontStyle: 'italic'},
|
||||||
]}>
|
]}>
|
||||||
<Trans>No description</Trans>
|
<Trans>
|
||||||
|
Moderation service managed by @{modservice.creator.handle}
|
||||||
|
</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -217,8 +220,8 @@ export function ProfileModserviceScreenInner({
|
|||||||
<Trans>
|
<Trans>
|
||||||
Operated by{' '}
|
Operated by{' '}
|
||||||
<TextLink
|
<TextLink
|
||||||
href={makeProfileLink(modInfo.creator)}
|
href={makeProfileLink(modservice.creator)}
|
||||||
text={sanitizeHandle(modInfo.creator.handle, '@')}
|
text={sanitizeHandle(modservice.creator.handle, '@')}
|
||||||
style={pal.link}
|
style={pal.link}
|
||||||
/>
|
/>
|
||||||
. Handles reports of anti-social behavior, illegal content, unwanted
|
. Handles reports of anti-social behavior, illegal content, unwanted
|
||||||
@@ -243,11 +246,11 @@ export function ProfileModserviceScreenInner({
|
|||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{typeof modInfo.likeCount === 'number' && (
|
{typeof modservice.likeCount === 'number' && (
|
||||||
<InlineLink to={'#todo'} style={[pal.textLight, s.semiBold]}>
|
<InlineLink to={'#todo'} style={[pal.textLight, s.semiBold]}>
|
||||||
<Trans>
|
<Trans>
|
||||||
Liked by {modInfo.likeCount}{' '}
|
Liked by {modservice.likeCount}{' '}
|
||||||
{pluralize(modInfo.likeCount, 'user')}
|
{pluralize(modservice.likeCount, 'user')}
|
||||||
</Trans>
|
</Trans>
|
||||||
</InlineLink>
|
</InlineLink>
|
||||||
)}
|
)}
|
||||||
@@ -255,11 +258,11 @@ export function ProfileModserviceScreenInner({
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={[a.gap_md, a.mt_xl]}>
|
<View style={[a.gap_md, a.mt_xl]}>
|
||||||
{groups.map(([name, def]) => {
|
{groups.map(def => {
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={def.id}>
|
<React.Fragment key={def.id}>
|
||||||
<Divider />
|
<Divider />
|
||||||
<PreferenceRow labelGroup={name} />
|
<PreferenceRow labelGroup={def.id} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
Reference in New Issue
Block a user