Improve the visual clarity of labels on profiles and posts (#4262)
* Update PostAlerts rendering to show the avi of the labeler rather than the display name; also add size variations * Update ProfileHeaderAlerts to match PostAlerts behaviorzio/stable
parent
4cc55f05c2
commit
5fe1e171f0
|
@ -1,9 +1,10 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {StyleProp, View, ViewStyle} from 'react-native'
|
import {StyleProp, View, ViewStyle} from 'react-native'
|
||||||
import {ModerationCause, ModerationUI} from '@atproto/api'
|
import {BSKY_LABELER_DID, ModerationCause, ModerationUI} from '@atproto/api'
|
||||||
|
|
||||||
import {getModerationCauseKey} from '#/lib/moderation'
|
import {getModerationCauseKey} from '#/lib/moderation'
|
||||||
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
|
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
|
||||||
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {Button} from '#/components/Button'
|
import {Button} from '#/components/Button'
|
||||||
import {
|
import {
|
||||||
|
@ -14,9 +15,11 @@ import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
export function PostAlerts({
|
export function PostAlerts({
|
||||||
modui,
|
modui,
|
||||||
|
size,
|
||||||
style,
|
style,
|
||||||
}: {
|
}: {
|
||||||
modui: ModerationUI
|
modui: ModerationUI
|
||||||
|
size?: 'medium' | 'large'
|
||||||
includeMute?: boolean
|
includeMute?: boolean
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
}) {
|
}) {
|
||||||
|
@ -28,17 +31,31 @@ export function PostAlerts({
|
||||||
<View style={[a.flex_col, a.gap_xs, style]}>
|
<View style={[a.flex_col, a.gap_xs, style]}>
|
||||||
<View style={[a.flex_row, a.flex_wrap, a.gap_xs]}>
|
<View style={[a.flex_row, a.flex_wrap, a.gap_xs]}>
|
||||||
{modui.alerts.map(cause => (
|
{modui.alerts.map(cause => (
|
||||||
<PostLabel key={getModerationCauseKey(cause)} cause={cause} />
|
<PostLabel
|
||||||
|
key={getModerationCauseKey(cause)}
|
||||||
|
cause={cause}
|
||||||
|
size={size}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
{modui.informs.map(cause => (
|
{modui.informs.map(cause => (
|
||||||
<PostLabel key={getModerationCauseKey(cause)} cause={cause} />
|
<PostLabel
|
||||||
|
key={getModerationCauseKey(cause)}
|
||||||
|
cause={cause}
|
||||||
|
size={size}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function PostLabel({cause}: {cause: ModerationCause}) {
|
function PostLabel({
|
||||||
|
cause,
|
||||||
|
size,
|
||||||
|
}: {
|
||||||
|
cause: ModerationCause
|
||||||
|
size?: 'medium' | 'large'
|
||||||
|
}) {
|
||||||
const control = useModerationDetailsDialogControl()
|
const control = useModerationDetailsDialogControl()
|
||||||
const desc = useModerationCauseDescription(cause)
|
const desc = useModerationCauseDescription(cause)
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
@ -55,24 +72,36 @@ function PostLabel({cause}: {cause: ModerationCause}) {
|
||||||
style={[
|
style={[
|
||||||
a.flex_row,
|
a.flex_row,
|
||||||
a.align_center,
|
a.align_center,
|
||||||
{paddingLeft: 4, paddingRight: 6, paddingVertical: 1},
|
|
||||||
a.gap_xs,
|
a.gap_xs,
|
||||||
a.rounded_sm,
|
a.rounded_sm,
|
||||||
hovered || pressed
|
hovered || pressed
|
||||||
? t.atoms.bg_contrast_50
|
? size === 'large'
|
||||||
: t.atoms.bg_contrast_25,
|
? t.atoms.bg_contrast_50
|
||||||
|
: t.atoms.bg_contrast_25
|
||||||
|
: size === 'large'
|
||||||
|
? t.atoms.bg_contrast_25
|
||||||
|
: undefined,
|
||||||
|
size === 'large'
|
||||||
|
? {paddingLeft: 4, paddingRight: 6, paddingVertical: 2}
|
||||||
|
: {paddingRight: 4, paddingVertical: 1},
|
||||||
]}>
|
]}>
|
||||||
<desc.icon size="xs" fill={t.atoms.text_contrast_medium.color} />
|
{desc.sourceType === 'labeler' &&
|
||||||
|
desc.sourceDid !== BSKY_LABELER_DID ? (
|
||||||
|
<UserAvatar
|
||||||
|
avatar={desc.sourceAvi}
|
||||||
|
size={size === 'large' ? 16 : 12}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<desc.icon size="sm" fill={t.atoms.text_contrast_medium.color} />
|
||||||
|
)}
|
||||||
<Text
|
<Text
|
||||||
style={[
|
style={[
|
||||||
a.text_left,
|
a.text_left,
|
||||||
a.leading_snug,
|
a.leading_snug,
|
||||||
a.text_xs,
|
size === 'large' ? {fontSize: 13} : a.text_xs,
|
||||||
t.atoms.text_contrast_medium,
|
size === 'large' ? t.atoms.text : t.atoms.text_contrast_high,
|
||||||
a.font_semibold,
|
|
||||||
]}>
|
]}>
|
||||||
{desc.name}
|
{desc.name}
|
||||||
{desc.source ? ` – ${desc.source}` : ''}
|
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {StyleProp, View, ViewStyle} from 'react-native'
|
import {StyleProp, View, ViewStyle} from 'react-native'
|
||||||
import {ModerationCause, ModerationDecision} from '@atproto/api'
|
import {
|
||||||
|
BSKY_LABELER_DID,
|
||||||
|
ModerationCause,
|
||||||
|
ModerationDecision,
|
||||||
|
} from '@atproto/api'
|
||||||
|
|
||||||
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
|
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
|
||||||
import {getModerationCauseKey} from 'lib/moderation'
|
import {getModerationCauseKey} from 'lib/moderation'
|
||||||
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {Button} from '#/components/Button'
|
import {Button} from '#/components/Button'
|
||||||
import {
|
import {
|
||||||
|
@ -62,7 +67,12 @@ function ProfileLabel({cause}: {cause: ModerationCause}) {
|
||||||
? t.atoms.bg_contrast_50
|
? t.atoms.bg_contrast_50
|
||||||
: t.atoms.bg_contrast_25,
|
: t.atoms.bg_contrast_25,
|
||||||
]}>
|
]}>
|
||||||
<desc.icon size="sm" fill={t.atoms.text_contrast_medium.color} />
|
{desc.sourceType === 'labeler' &&
|
||||||
|
desc.sourceDid !== BSKY_LABELER_DID ? (
|
||||||
|
<UserAvatar avatar={desc.sourceAvi} size={16} />
|
||||||
|
) : (
|
||||||
|
<desc.icon size="sm" fill={t.atoms.text_contrast_medium.color} />
|
||||||
|
)}
|
||||||
<Text
|
<Text
|
||||||
style={[
|
style={[
|
||||||
a.text_left,
|
a.text_left,
|
||||||
|
@ -72,7 +82,6 @@ function ProfileLabel({cause}: {cause: ModerationCause}) {
|
||||||
a.font_semibold,
|
a.font_semibold,
|
||||||
]}>
|
]}>
|
||||||
{desc.name}
|
{desc.name}
|
||||||
{desc.source ? ` – ${desc.source}` : ''}
|
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -6,15 +6,15 @@ import {
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {getDefinition, getLabelStrings} from './useLabelInfo'
|
|
||||||
import {useLabelDefinitions} from '#/state/preferences'
|
|
||||||
import {useGlobalLabelStrings} from './useGlobalLabelStrings'
|
|
||||||
|
|
||||||
import {Props as SVGIconProps} from '#/components/icons/common'
|
import {useLabelDefinitions} from '#/state/preferences'
|
||||||
import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning'
|
|
||||||
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
|
||||||
import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash'
|
|
||||||
import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign'
|
import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign'
|
||||||
|
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
||||||
|
import {Props as SVGIconProps} from '#/components/icons/common'
|
||||||
|
import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash'
|
||||||
|
import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning'
|
||||||
|
import {useGlobalLabelStrings} from './useGlobalLabelStrings'
|
||||||
|
import {getDefinition, getLabelStrings} from './useLabelInfo'
|
||||||
|
|
||||||
export interface ModerationCauseDescription {
|
export interface ModerationCauseDescription {
|
||||||
icon: React.ComponentType<SVGIconProps>
|
icon: React.ComponentType<SVGIconProps>
|
||||||
|
@ -22,6 +22,8 @@ export interface ModerationCauseDescription {
|
||||||
description: string
|
description: string
|
||||||
source?: string
|
source?: string
|
||||||
sourceType?: ModerationCauseSource['type']
|
sourceType?: ModerationCauseSource['type']
|
||||||
|
sourceAvi?: string
|
||||||
|
sourceDid?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useModerationCauseDescription(
|
export function useModerationCauseDescription(
|
||||||
|
@ -138,6 +140,8 @@ export function useModerationCauseDescription(
|
||||||
description: strings.description,
|
description: strings.description,
|
||||||
source,
|
source,
|
||||||
sourceType: cause.source.type,
|
sourceType: cause.source.type,
|
||||||
|
sourceAvi: labeler?.creator.avatar,
|
||||||
|
sourceDid: cause.label.src,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// should never happen
|
// should never happen
|
||||||
|
|
|
@ -316,6 +316,7 @@ let PostThreadItemLoaded = ({
|
||||||
childContainerStyle={styles.contentHiderChild}>
|
childContainerStyle={styles.contentHiderChild}>
|
||||||
<PostAlerts
|
<PostAlerts
|
||||||
modui={moderation.ui('contentView')}
|
modui={moderation.ui('contentView')}
|
||||||
|
size="large"
|
||||||
includeMute
|
includeMute
|
||||||
style={[a.pt_2xs, a.pb_sm]}
|
style={[a.pt_2xs, a.pb_sm]}
|
||||||
/>
|
/>
|
||||||
|
@ -517,7 +518,7 @@ let PostThreadItemLoaded = ({
|
||||||
<LabelsOnMyPost post={post} />
|
<LabelsOnMyPost post={post} />
|
||||||
<PostAlerts
|
<PostAlerts
|
||||||
modui={moderation.ui('contentList')}
|
modui={moderation.ui('contentList')}
|
||||||
style={[a.pt_xs, a.pb_sm]}
|
style={[a.pt_2xs, a.pb_2xs]}
|
||||||
/>
|
/>
|
||||||
{richText?.text ? (
|
{richText?.text ? (
|
||||||
<View style={styles.postTextContainer}>
|
<View style={styles.postTextContainer}>
|
||||||
|
|
|
@ -368,7 +368,7 @@ let PostContent = ({
|
||||||
modui={moderation.ui('contentList')}
|
modui={moderation.ui('contentList')}
|
||||||
ignoreMute
|
ignoreMute
|
||||||
childContainerStyle={styles.contentHiderChild}>
|
childContainerStyle={styles.contentHiderChild}>
|
||||||
<PostAlerts modui={moderation.ui('contentList')} style={[a.pb_xs]} />
|
<PostAlerts modui={moderation.ui('contentList')} style={[a.py_2xs]} />
|
||||||
{richText.text ? (
|
{richText.text ? (
|
||||||
<View style={styles.postTextContainer}>
|
<View style={styles.postTextContainer}>
|
||||||
<RichText
|
<RichText
|
||||||
|
|
Loading…
Reference in New Issue