Hook up data to settings page

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