Improve moderation behaviors: show alert/inform sources and improve UX around threads (#3677)

* Dont show account or profile alerts and informs on posts

* Sort threads to put blurred items at bottom

* Group blurred replies under a single 'show hidden replies' control

* Distinguish between muted and hidden replies in the thread view

* Fix types

* Modify the label alerts with some minor aesthetic updates and to show the source of a label

* Tune when an account-level alert is shown on a post

* Revert: show account-level alerts on posts again

* Rm unused import

* Fix to showing hidden replies when viewing a blurred item

* Go ahead and uncover replies when 'show hidden posts' is clicked

---------

Co-authored-by: dan <dan.abramov@gmail.com>
This commit is contained in:
Paul Frazee 2024-05-23 16:39:39 -07:00 committed by GitHub
parent d2c42cf169
commit f7ee532a85
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 311 additions and 67 deletions

View file

@ -1,16 +1,16 @@
import React from 'react'
import {StyleProp, View, ViewStyle} from 'react-native'
import {ModerationUI, ModerationCause} from '@atproto/api'
import {ModerationCause, ModerationUI} from '@atproto/api'
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
import {getModerationCauseKey} from '#/lib/moderation'
import {atoms as a} from '#/alf'
import {Button, ButtonText, ButtonIcon} from '#/components/Button'
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
import {atoms as a, useTheme} from '#/alf'
import {Button} from '#/components/Button'
import {
ModerationDetailsDialog,
useModerationDetailsDialogControl,
} from '#/components/moderation/ModerationDetailsDialog'
import {Text} from '#/components/Typography'
export function PostAlerts({
modui,
@ -41,23 +41,41 @@ export function PostAlerts({
function PostLabel({cause}: {cause: ModerationCause}) {
const control = useModerationDetailsDialogControl()
const desc = useModerationCauseDescription(cause)
const t = useTheme()
return (
<>
<Button
label={desc.name}
variant="solid"
color="secondary"
size="small"
shape="default"
onPress={() => {
control.open()
}}
style={[a.px_sm, a.py_xs, a.gap_xs]}>
<ButtonIcon icon={desc.icon} position="left" />
<ButtonText style={[a.text_left, a.leading_snug]}>
{desc.name}
</ButtonText>
}}>
{({hovered, pressed}) => (
<View
style={[
a.flex_row,
a.align_center,
{paddingLeft: 4, paddingRight: 6, paddingVertical: 1},
a.gap_xs,
a.rounded_sm,
hovered || pressed
? t.atoms.bg_contrast_50
: t.atoms.bg_contrast_25,
]}>
<desc.icon size="xs" fill={t.atoms.text_contrast_medium.color} />
<Text
style={[
a.text_left,
a.leading_snug,
a.text_xs,
t.atoms.text_contrast_medium,
a.font_semibold,
]}>
{desc.name}
{desc.source ? ` ${desc.source}` : ''}
</Text>
</View>
)}
</Button>
<ModerationDetailsDialog control={control} modcause={cause} />

View file

@ -18,6 +18,7 @@ import {
import {Text} from '#/components/Typography'
interface Props extends ComponentProps<typeof Link> {
disabled: boolean
iconSize: number
iconStyles: StyleProp<ViewStyle>
modui: ModerationUI
@ -27,6 +28,7 @@ interface Props extends ComponentProps<typeof Link> {
export function PostHider({
testID,
href,
disabled,
modui,
style,
children,
@ -47,7 +49,7 @@ export function PostHider({
precacheProfile(queryClient, profile)
}, [queryClient, profile])
if (!blur) {
if (!blur || (disabled && !modui.noOverride)) {
return (
<Link
testID={testID}

View file

@ -2,15 +2,15 @@ import React from 'react'
import {StyleProp, View, ViewStyle} from 'react-native'
import {ModerationCause, ModerationDecision} from '@atproto/api'
import {getModerationCauseKey} from 'lib/moderation'
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
import {atoms as a} from '#/alf'
import {Button, ButtonText, ButtonIcon} from '#/components/Button'
import {getModerationCauseKey} from 'lib/moderation'
import {atoms as a, useTheme} from '#/alf'
import {Button} from '#/components/Button'
import {
ModerationDetailsDialog,
useModerationDetailsDialogControl,
} from '#/components/moderation/ModerationDetailsDialog'
import {Text} from '#/components/Typography'
export function ProfileHeaderAlerts({
moderation,
@ -39,6 +39,7 @@ export function ProfileHeaderAlerts({
}
function ProfileLabel({cause}: {cause: ModerationCause}) {
const t = useTheme()
const control = useModerationDetailsDialogControl()
const desc = useModerationCauseDescription(cause)
@ -46,18 +47,35 @@ function ProfileLabel({cause}: {cause: ModerationCause}) {
<>
<Button
label={desc.name}
variant="solid"
color="secondary"
size="small"
shape="default"
onPress={() => {
control.open()
}}
style={[a.px_sm, a.py_xs, a.gap_xs]}>
<ButtonIcon icon={desc.icon} position="left" />
<ButtonText style={[a.text_left, a.leading_snug]}>
{desc.name}
</ButtonText>
}}>
{({hovered, pressed}) => (
<View
style={[
a.flex_row,
a.align_center,
{paddingLeft: 6, paddingRight: 8, paddingVertical: 4},
a.gap_xs,
a.rounded_md,
hovered || pressed
? t.atoms.bg_contrast_50
: t.atoms.bg_contrast_25,
]}>
<desc.icon size="sm" fill={t.atoms.text_contrast_medium.color} />
<Text
style={[
a.text_left,
a.leading_snug,
a.text_sm,
t.atoms.text_contrast_medium,
a.font_semibold,
]}>
{desc.name}
{desc.source ? ` ${desc.source}` : ''}
</Text>
</View>
)}
</Button>
<ModerationDetailsDialog control={control} modcause={cause} />