diff --git a/src/components/Pills.tsx b/src/components/Pills.tsx
new file mode 100644
index 00000000..2fff9993
--- /dev/null
+++ b/src/components/Pills.tsx
@@ -0,0 +1,169 @@
+import React from 'react'
+import {View} from 'react-native'
+import {BSKY_LABELER_DID, ModerationCause} from '@atproto/api'
+import {Trans} from '@lingui/macro'
+
+import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
+import {UserAvatar} from '#/view/com/util/UserAvatar'
+import {atoms as a, useTheme, ViewStyleProp} from '#/alf'
+import {Button} from '#/components/Button'
+import {
+ ModerationDetailsDialog,
+ useModerationDetailsDialogControl,
+} from '#/components/moderation/ModerationDetailsDialog'
+import {Text} from '#/components/Typography'
+
+export type CommonProps = {
+ size?: 'sm' | 'lg'
+}
+
+export function Row({
+ children,
+ style,
+ size = 'sm',
+}: {children: React.ReactNode | React.ReactNode[]} & CommonProps &
+ ViewStyleProp) {
+ const styles = React.useMemo(() => {
+ switch (size) {
+ case 'lg':
+ return [{gap: 5}]
+ case 'sm':
+ default:
+ return [{gap: 3}]
+ }
+ }, [size])
+ return (
+
+ {children}
+
+ )
+}
+
+export type LabelProps = {
+ cause: ModerationCause
+ disableDetailsDialog?: boolean
+ noBg?: boolean
+} & CommonProps
+
+export function Label({
+ cause,
+ size = 'sm',
+ disableDetailsDialog,
+ noBg,
+}: LabelProps) {
+ const t = useTheme()
+ const control = useModerationDetailsDialogControl()
+ const desc = useModerationCauseDescription(cause)
+ const isLabeler = Boolean(desc.sourceType && desc.sourceDid)
+ const isBlueskyLabel =
+ desc.sourceType === 'labeler' && desc.sourceDid === BSKY_LABELER_DID
+
+ const {outer, avi, text} = React.useMemo(() => {
+ switch (size) {
+ case 'lg': {
+ return {
+ outer: [
+ t.atoms.bg_contrast_25,
+ {
+ gap: 5,
+ paddingHorizontal: 5,
+ paddingVertical: 5,
+ },
+ ],
+ avi: 16,
+ text: [a.text_sm],
+ }
+ }
+ case 'sm':
+ default: {
+ return {
+ outer: [
+ !noBg && t.atoms.bg_contrast_25,
+ {
+ gap: 3,
+ paddingHorizontal: 3,
+ paddingVertical: 3,
+ },
+ ],
+ avi: 12,
+ text: [a.text_xs],
+ }
+ }
+ }
+ }, [t, size, noBg])
+
+ return (
+ <>
+
+
+ {!disableDetailsDialog && (
+
+ )}
+ >
+ )
+}
+
+export function FollowsYou({size = 'sm'}: CommonProps) {
+ const t = useTheme()
+
+ const variantStyles = React.useMemo(() => {
+ switch (size) {
+ case 'sm':
+ case 'lg':
+ default:
+ return [
+ {
+ paddingHorizontal: 6,
+ paddingVertical: 3,
+ borderRadius: 4,
+ },
+ ]
+ }
+ }, [size])
+
+ return (
+
+
+ Follows You
+
+
+ )
+}
diff --git a/src/components/ProfileHoverCard/index.web.tsx b/src/components/ProfileHoverCard/index.web.tsx
index 4db9c4f8..84b1d6d2 100644
--- a/src/components/ProfileHoverCard/index.web.tsx
+++ b/src/components/ProfileHoverCard/index.web.tsx
@@ -29,10 +29,10 @@ import {
} from '#/components/KnownFollowers'
import {InlineLinkText, Link} from '#/components/Link'
import {Loader} from '#/components/Loader'
+import * as Pills from '#/components/Pills'
import {Portal} from '#/components/Portal'
import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography'
-import {ProfileLabel} from '../moderation/ProfileHeaderAlerts'
import {ProfileHoverCardProps} from './types'
const floatingMiddlewares = [
@@ -476,8 +476,9 @@ function Inner({
{isBlockedUser && (
{moderation.ui('profileView').alerts.map(cause => (
-
diff --git a/src/components/dms/MessagesListHeader.tsx b/src/components/dms/MessagesListHeader.tsx
index 0aeac362..8bf673d3 100644
--- a/src/components/dms/MessagesListHeader.tsx
+++ b/src/components/dms/MessagesListHeader.tsx
@@ -214,7 +214,7 @@ function HeaderReady({
]}>
diff --git a/src/components/moderation/ContentHider.tsx b/src/components/moderation/ContentHider.tsx
index fd71ec83..45122a4e 100644
--- a/src/components/moderation/ContentHider.tsx
+++ b/src/components/moderation/ContentHider.tsx
@@ -165,9 +165,7 @@ export function ContentHider({
}
const styles = StyleSheet.create({
- outer: {
- overflow: 'hidden',
- },
+ outer: {},
cover: {
flexDirection: 'row',
alignItems: 'center',
diff --git a/src/components/moderation/PostAlerts.tsx b/src/components/moderation/PostAlerts.tsx
index ec7529a4..efbf1821 100644
--- a/src/components/moderation/PostAlerts.tsx
+++ b/src/components/moderation/PostAlerts.tsx
@@ -1,25 +1,17 @@
import React from 'react'
-import {StyleProp, View, ViewStyle} from 'react-native'
-import {BSKY_LABELER_DID, ModerationCause, ModerationUI} from '@atproto/api'
+import {StyleProp, ViewStyle} from 'react-native'
+import {ModerationUI} from '@atproto/api'
import {getModerationCauseKey} from '#/lib/moderation'
-import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
-import {UserAvatar} from '#/view/com/util/UserAvatar'
-import {atoms as a, useTheme} from '#/alf'
-import {Button} from '#/components/Button'
-import {
- ModerationDetailsDialog,
- useModerationDetailsDialogControl,
-} from '#/components/moderation/ModerationDetailsDialog'
-import {Text} from '#/components/Typography'
+import * as Pills from '#/components/Pills'
export function PostAlerts({
modui,
- size,
+ size = 'sm',
style,
}: {
modui: ModerationUI
- size?: 'medium' | 'large'
+ size?: Pills.CommonProps['size']
includeMute?: boolean
style?: StyleProp
}) {
@@ -28,90 +20,23 @@ export function PostAlerts({
}
return (
-
-
- {modui.alerts.map(cause => (
-
- ))}
- {modui.informs.map(cause => (
-
- ))}
-
-
- )
-}
-
-function PostLabel({
- cause,
- size,
-}: {
- cause: ModerationCause
- size?: 'medium' | 'large'
-}) {
- const control = useModerationDetailsDialogControl()
- const desc = useModerationCauseDescription(cause)
- const t = useTheme()
-
- return (
- <>
-
-
-
- >
+
+ {modui.alerts.map(cause => (
+
+ ))}
+ {modui.informs.map(cause => (
+
+ ))}
+
)
}
diff --git a/src/components/moderation/ProfileHeaderAlerts.tsx b/src/components/moderation/ProfileHeaderAlerts.tsx
index 4b48b142..94779697 100644
--- a/src/components/moderation/ProfileHeaderAlerts.tsx
+++ b/src/components/moderation/ProfileHeaderAlerts.tsx
@@ -1,25 +1,12 @@
import React from 'react'
-import {StyleProp, View, ViewStyle} from 'react-native'
-import {
- BSKY_LABELER_DID,
- ModerationCause,
- ModerationDecision,
-} from '@atproto/api'
+import {StyleProp, ViewStyle} from 'react-native'
+import {ModerationDecision} from '@atproto/api'
-import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
import {getModerationCauseKey} from 'lib/moderation'
-import {UserAvatar} from '#/view/com/util/UserAvatar'
-import {atoms as a, useTheme} from '#/alf'
-import {Button} from '#/components/Button'
-import {
- ModerationDetailsDialog,
- useModerationDetailsDialogControl,
-} from '#/components/moderation/ModerationDetailsDialog'
-import {Text} from '#/components/Typography'
+import * as Pills from '#/components/Pills'
export function ProfileHeaderAlerts({
moderation,
- style,
}: {
moderation: ModerationDecision
style?: StyleProp
@@ -30,73 +17,21 @@ export function ProfileHeaderAlerts({
}
return (
-
-
- {modui.alerts.map(cause => (
-
- ))}
- {modui.informs.map(cause => (
-
- ))}
-
-
- )
-}
-
-export function ProfileLabel({
- cause,
- disableDetailsDialog,
-}: {
- cause: ModerationCause
- disableDetailsDialog?: boolean
-}) {
- const t = useTheme()
- const control = useModerationDetailsDialogControl()
- const desc = useModerationCauseDescription(cause)
-
- return (
- <>
-
-
- {!disableDetailsDialog && (
-
- )}
- >
+
+ {modui.alerts.map(cause => (
+
+ ))}
+ {modui.informs.map(cause => (
+
+ ))}
+
)
}
diff --git a/src/screens/Messages/List/ChatListItem.tsx b/src/screens/Messages/List/ChatListItem.tsx
index 8ebf8b00..c45cc28d 100644
--- a/src/screens/Messages/List/ChatListItem.tsx
+++ b/src/screens/Messages/List/ChatListItem.tsx
@@ -315,7 +315,7 @@ function ChatListItemReady({
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index 46c6c958..0f5350e7 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -313,7 +313,7 @@ let PostThreadItemLoaded = ({
childContainerStyle={styles.contentHiderChild}>
diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx
index d7ed0dd6..7332d452 100644
--- a/src/view/com/profile/ProfileCard.tsx
+++ b/src/view/com/profile/ProfileCard.tsx
@@ -3,13 +3,11 @@ import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
import {
AppBskyActorDefs,
moderateProfile,
- ModerationCause,
ModerationDecision,
} from '@atproto/api'
import {Trans} from '@lingui/macro'
import {useQueryClient} from '@tanstack/react-query'
-import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {Shadow} from '#/state/cache/types'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
@@ -26,6 +24,8 @@ import {Text} from '../util/text/Text'
import {PreviewableUserAvatar} from '../util/UserAvatar'
import {FollowButton} from './FollowButton'
import hairlineWidth = StyleSheet.hairlineWidth
+import {atoms as a} from '#/alf'
+import * as Pills from '#/components/Pills'
export function ProfileCard({
testID,
@@ -137,58 +137,21 @@ export function ProfileCardPills({
followedBy: boolean
moderation: ModerationDecision
}) {
- const pal = usePalette('default')
-
const modui = moderation.ui('profileList')
if (!followedBy && !modui.inform && !modui.alert) {
return null
}
return (
-
- {followedBy && (
-
-
- Follows You
-
-
- )}
+
+ {followedBy && }
{modui.alerts.map(alert => (
-
+
))}
{modui.informs.map(inform => (
-
+
))}
-
- )
-}
-
-function ProfileCardPillModerationCause({
- cause,
- severity,
-}: {
- cause: ModerationCause
- severity: 'alert' | 'inform'
-}) {
- const pal = usePalette('default')
- const {name} = useModerationCauseDescription(cause)
- return (
-
-
- {severity === 'alert' ? '⚠ ' : ''}
- {name}
-
-
+
)
}
@@ -322,6 +285,7 @@ const styles = StyleSheet.create({
paddingBottom: 10,
},
pills: {
+ alignItems: 'flex-start',
flexDirection: 'row',
flexWrap: 'wrap',
columnGap: 6,