Unify label pills (#4676)
* New label pills * Fix type errors, add default case * Remove negative margin, only works in some places * Fix alignment edge case * Add a bit of padding --------- Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
		
							parent
							
								
									c133661768
								
							
						
					
					
						commit
						14c2d75d49
					
				
					 9 changed files with 226 additions and 234 deletions
				
			
		
							
								
								
									
										169
									
								
								src/components/Pills.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								src/components/Pills.tsx
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 (
 | 
			
		||||
    <View style={[a.flex_row, a.flex_wrap, a.gap_xs, styles, style]}>
 | 
			
		||||
      {children}
 | 
			
		||||
    </View>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 (
 | 
			
		||||
    <>
 | 
			
		||||
      <Button
 | 
			
		||||
        disabled={disableDetailsDialog}
 | 
			
		||||
        label={desc.name}
 | 
			
		||||
        onPress={e => {
 | 
			
		||||
          e.preventDefault()
 | 
			
		||||
          e.stopPropagation()
 | 
			
		||||
          control.open()
 | 
			
		||||
        }}>
 | 
			
		||||
        {({hovered, pressed}) => (
 | 
			
		||||
          <View
 | 
			
		||||
            style={[
 | 
			
		||||
              a.flex_row,
 | 
			
		||||
              a.align_center,
 | 
			
		||||
              a.rounded_full,
 | 
			
		||||
              outer,
 | 
			
		||||
              (hovered || pressed) && t.atoms.bg_contrast_50,
 | 
			
		||||
            ]}>
 | 
			
		||||
            {isBlueskyLabel || !isLabeler ? (
 | 
			
		||||
              <desc.icon
 | 
			
		||||
                width={avi}
 | 
			
		||||
                fill={t.atoms.text_contrast_medium.color}
 | 
			
		||||
              />
 | 
			
		||||
            ) : (
 | 
			
		||||
              <UserAvatar avatar={desc.sourceAvi} size={avi} />
 | 
			
		||||
            )}
 | 
			
		||||
 | 
			
		||||
            <Text
 | 
			
		||||
              style={[
 | 
			
		||||
                text,
 | 
			
		||||
                a.font_semibold,
 | 
			
		||||
                a.leading_tight,
 | 
			
		||||
                t.atoms.text_contrast_medium,
 | 
			
		||||
                {paddingRight: 3},
 | 
			
		||||
              ]}>
 | 
			
		||||
              {desc.name}
 | 
			
		||||
            </Text>
 | 
			
		||||
          </View>
 | 
			
		||||
        )}
 | 
			
		||||
      </Button>
 | 
			
		||||
 | 
			
		||||
      {!disableDetailsDialog && (
 | 
			
		||||
        <ModerationDetailsDialog control={control} modcause={cause} />
 | 
			
		||||
      )}
 | 
			
		||||
    </>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 (
 | 
			
		||||
    <View style={[variantStyles, a.justify_center, t.atoms.bg_contrast_25]}>
 | 
			
		||||
      <Text style={[a.text_xs, a.leading_tight]}>
 | 
			
		||||
        <Trans>Follows You</Trans>
 | 
			
		||||
      </Text>
 | 
			
		||||
    </View>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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 && (
 | 
			
		||||
        <View style={[a.flex_row, a.flex_wrap, a.gap_xs]}>
 | 
			
		||||
          {moderation.ui('profileView').alerts.map(cause => (
 | 
			
		||||
            <ProfileLabel
 | 
			
		||||
            <Pills.Label
 | 
			
		||||
              key={getModerationCauseKey(cause)}
 | 
			
		||||
              size="lg"
 | 
			
		||||
              cause={cause}
 | 
			
		||||
              disableDetailsDialog
 | 
			
		||||
            />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -214,7 +214,7 @@ function HeaderReady({
 | 
			
		|||
        ]}>
 | 
			
		||||
        <PostAlerts
 | 
			
		||||
          modui={moderation.ui('contentList')}
 | 
			
		||||
          size="large"
 | 
			
		||||
          size="lg"
 | 
			
		||||
          style={[a.pt_xs]}
 | 
			
		||||
        />
 | 
			
		||||
      </View>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,9 +165,7 @@ export function ContentHider({
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
const styles = StyleSheet.create({
 | 
			
		||||
  outer: {
 | 
			
		||||
    overflow: 'hidden',
 | 
			
		||||
  },
 | 
			
		||||
  outer: {},
 | 
			
		||||
  cover: {
 | 
			
		||||
    flexDirection: 'row',
 | 
			
		||||
    alignItems: 'center',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<ViewStyle>
 | 
			
		||||
}) {
 | 
			
		||||
| 
						 | 
				
			
			@ -28,90 +20,23 @@ export function PostAlerts({
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <View style={[a.flex_col, a.gap_xs, style]}>
 | 
			
		||||
      <View style={[a.flex_row, a.flex_wrap, a.gap_xs]}>
 | 
			
		||||
    <Pills.Row size={size} style={[size === 'sm' && {marginLeft: -3}, style]}>
 | 
			
		||||
      {modui.alerts.map(cause => (
 | 
			
		||||
          <PostLabel
 | 
			
		||||
        <Pills.Label
 | 
			
		||||
          key={getModerationCauseKey(cause)}
 | 
			
		||||
          cause={cause}
 | 
			
		||||
          size={size}
 | 
			
		||||
          noBg={size === 'sm'}
 | 
			
		||||
        />
 | 
			
		||||
      ))}
 | 
			
		||||
      {modui.informs.map(cause => (
 | 
			
		||||
          <PostLabel
 | 
			
		||||
        <Pills.Label
 | 
			
		||||
          key={getModerationCauseKey(cause)}
 | 
			
		||||
          cause={cause}
 | 
			
		||||
          size={size}
 | 
			
		||||
          noBg={size === 'sm'}
 | 
			
		||||
        />
 | 
			
		||||
      ))}
 | 
			
		||||
      </View>
 | 
			
		||||
    </View>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function PostLabel({
 | 
			
		||||
  cause,
 | 
			
		||||
  size,
 | 
			
		||||
}: {
 | 
			
		||||
  cause: ModerationCause
 | 
			
		||||
  size?: 'medium' | 'large'
 | 
			
		||||
}) {
 | 
			
		||||
  const control = useModerationDetailsDialogControl()
 | 
			
		||||
  const desc = useModerationCauseDescription(cause)
 | 
			
		||||
  const t = useTheme()
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <Button
 | 
			
		||||
        label={desc.name}
 | 
			
		||||
        onPress={e => {
 | 
			
		||||
          e.preventDefault()
 | 
			
		||||
          e.stopPropagation()
 | 
			
		||||
          control.open()
 | 
			
		||||
        }}>
 | 
			
		||||
        {({hovered, pressed}) => (
 | 
			
		||||
          <View
 | 
			
		||||
            style={[
 | 
			
		||||
              a.flex_row,
 | 
			
		||||
              a.align_center,
 | 
			
		||||
              a.gap_xs,
 | 
			
		||||
              a.rounded_sm,
 | 
			
		||||
              hovered || pressed
 | 
			
		||||
                ? size === 'large'
 | 
			
		||||
                  ? 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.sourceType === 'labeler' &&
 | 
			
		||||
            desc.sourceDid !== BSKY_LABELER_DID ? (
 | 
			
		||||
              <UserAvatar
 | 
			
		||||
                avatar={desc.sourceAvi}
 | 
			
		||||
                size={size === 'large' ? 16 : 12}
 | 
			
		||||
                type="labeler"
 | 
			
		||||
                shape="circle"
 | 
			
		||||
              />
 | 
			
		||||
            ) : (
 | 
			
		||||
              <desc.icon size="sm" fill={t.atoms.text_contrast_medium.color} />
 | 
			
		||||
            )}
 | 
			
		||||
            <Text
 | 
			
		||||
              style={[
 | 
			
		||||
                a.text_left,
 | 
			
		||||
                a.leading_snug,
 | 
			
		||||
                size === 'large' ? {fontSize: 13} : a.text_xs,
 | 
			
		||||
                size === 'large' ? t.atoms.text : t.atoms.text_contrast_high,
 | 
			
		||||
              ]}>
 | 
			
		||||
              {desc.name}
 | 
			
		||||
            </Text>
 | 
			
		||||
          </View>
 | 
			
		||||
        )}
 | 
			
		||||
      </Button>
 | 
			
		||||
 | 
			
		||||
      <ModerationDetailsDialog control={control} modcause={cause} />
 | 
			
		||||
    </>
 | 
			
		||||
    </Pills.Row>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<ViewStyle>
 | 
			
		||||
| 
						 | 
				
			
			@ -30,73 +17,21 @@ export function ProfileHeaderAlerts({
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <View style={[a.flex_col, a.gap_xs, style]}>
 | 
			
		||||
      <View style={[a.flex_row, a.flex_wrap, a.gap_xs]}>
 | 
			
		||||
    <Pills.Row size="lg">
 | 
			
		||||
      {modui.alerts.map(cause => (
 | 
			
		||||
          <ProfileLabel key={getModerationCauseKey(cause)} cause={cause} />
 | 
			
		||||
        <Pills.Label
 | 
			
		||||
          size="lg"
 | 
			
		||||
          key={getModerationCauseKey(cause)}
 | 
			
		||||
          cause={cause}
 | 
			
		||||
        />
 | 
			
		||||
      ))}
 | 
			
		||||
      {modui.informs.map(cause => (
 | 
			
		||||
          <ProfileLabel key={getModerationCauseKey(cause)} cause={cause} />
 | 
			
		||||
        <Pills.Label
 | 
			
		||||
          size="lg"
 | 
			
		||||
          key={getModerationCauseKey(cause)}
 | 
			
		||||
          cause={cause}
 | 
			
		||||
        />
 | 
			
		||||
      ))}
 | 
			
		||||
      </View>
 | 
			
		||||
    </View>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function ProfileLabel({
 | 
			
		||||
  cause,
 | 
			
		||||
  disableDetailsDialog,
 | 
			
		||||
}: {
 | 
			
		||||
  cause: ModerationCause
 | 
			
		||||
  disableDetailsDialog?: boolean
 | 
			
		||||
}) {
 | 
			
		||||
  const t = useTheme()
 | 
			
		||||
  const control = useModerationDetailsDialogControl()
 | 
			
		||||
  const desc = useModerationCauseDescription(cause)
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <Button
 | 
			
		||||
        disabled={disableDetailsDialog}
 | 
			
		||||
        label={desc.name}
 | 
			
		||||
        onPress={() => {
 | 
			
		||||
          control.open()
 | 
			
		||||
        }}>
 | 
			
		||||
        {({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.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
 | 
			
		||||
              style={[
 | 
			
		||||
                a.text_left,
 | 
			
		||||
                a.leading_snug,
 | 
			
		||||
                a.text_sm,
 | 
			
		||||
                t.atoms.text_contrast_medium,
 | 
			
		||||
                a.font_semibold,
 | 
			
		||||
              ]}>
 | 
			
		||||
              {desc.name}
 | 
			
		||||
            </Text>
 | 
			
		||||
          </View>
 | 
			
		||||
        )}
 | 
			
		||||
      </Button>
 | 
			
		||||
 | 
			
		||||
      {!disableDetailsDialog && (
 | 
			
		||||
        <ModerationDetailsDialog control={control} modcause={cause} />
 | 
			
		||||
      )}
 | 
			
		||||
    </>
 | 
			
		||||
    </Pills.Row>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -315,7 +315,7 @@ function ChatListItemReady({
 | 
			
		|||
 | 
			
		||||
              <PostAlerts
 | 
			
		||||
                modui={moderation.ui('contentList')}
 | 
			
		||||
                size="large"
 | 
			
		||||
                size="lg"
 | 
			
		||||
                style={[a.pt_xs]}
 | 
			
		||||
              />
 | 
			
		||||
            </View>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -313,7 +313,7 @@ let PostThreadItemLoaded = ({
 | 
			
		|||
              childContainerStyle={styles.contentHiderChild}>
 | 
			
		||||
              <PostAlerts
 | 
			
		||||
                modui={moderation.ui('contentView')}
 | 
			
		||||
                size="large"
 | 
			
		||||
                size="lg"
 | 
			
		||||
                includeMute
 | 
			
		||||
                style={[a.pt_2xs, a.pb_sm]}
 | 
			
		||||
              />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 (
 | 
			
		||||
    <View style={styles.pills}>
 | 
			
		||||
      {followedBy && (
 | 
			
		||||
        <View style={[s.mt5, pal.btn, styles.pill]}>
 | 
			
		||||
          <Text type="xs" style={pal.text}>
 | 
			
		||||
            <Trans>Follows You</Trans>
 | 
			
		||||
          </Text>
 | 
			
		||||
        </View>
 | 
			
		||||
      )}
 | 
			
		||||
    <Pills.Row style={[a.pt_xs]}>
 | 
			
		||||
      {followedBy && <Pills.FollowsYou />}
 | 
			
		||||
      {modui.alerts.map(alert => (
 | 
			
		||||
        <ProfileCardPillModerationCause
 | 
			
		||||
          key={getModerationCauseKey(alert)}
 | 
			
		||||
          cause={alert}
 | 
			
		||||
          severity="alert"
 | 
			
		||||
        />
 | 
			
		||||
        <Pills.Label key={getModerationCauseKey(alert)} cause={alert} />
 | 
			
		||||
      ))}
 | 
			
		||||
      {modui.informs.map(inform => (
 | 
			
		||||
        <ProfileCardPillModerationCause
 | 
			
		||||
          key={getModerationCauseKey(inform)}
 | 
			
		||||
          cause={inform}
 | 
			
		||||
          severity="inform"
 | 
			
		||||
        />
 | 
			
		||||
        <Pills.Label key={getModerationCauseKey(inform)} cause={inform} />
 | 
			
		||||
      ))}
 | 
			
		||||
    </View>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ProfileCardPillModerationCause({
 | 
			
		||||
  cause,
 | 
			
		||||
  severity,
 | 
			
		||||
}: {
 | 
			
		||||
  cause: ModerationCause
 | 
			
		||||
  severity: 'alert' | 'inform'
 | 
			
		||||
}) {
 | 
			
		||||
  const pal = usePalette('default')
 | 
			
		||||
  const {name} = useModerationCauseDescription(cause)
 | 
			
		||||
  return (
 | 
			
		||||
    <View
 | 
			
		||||
      style={[s.mt5, pal.btn, styles.pill]}
 | 
			
		||||
      key={getModerationCauseKey(cause)}>
 | 
			
		||||
      <Text type="xs" style={pal.text}>
 | 
			
		||||
        {severity === 'alert' ? '⚠ ' : ''}
 | 
			
		||||
        {name}
 | 
			
		||||
      </Text>
 | 
			
		||||
    </View>
 | 
			
		||||
    </Pills.Row>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -322,6 +285,7 @@ const styles = StyleSheet.create({
 | 
			
		|||
    paddingBottom: 10,
 | 
			
		||||
  },
 | 
			
		||||
  pills: {
 | 
			
		||||
    alignItems: 'flex-start',
 | 
			
		||||
    flexDirection: 'row',
 | 
			
		||||
    flexWrap: 'wrap',
 | 
			
		||||
    columnGap: 6,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue