import {useMemo} from 'react' import {View} from 'react-native' import {api} from '@bsky/sdk' import {type ModerationCause} from '@bsky/sdk/moderation' import {Trans, useLingui} from '@lingui/react/macro' import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons' import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useTheme, type ViewStyleProp} from '#/alf' import {Button} from '#/components/Button' import {RepostStrike_Stroke2_Corner0_Rounded as RepostStrikeIcon} from '#/components/icons/Repost' import { ModerationDetailsDialog, useModerationDetailsDialogControl, } from '#/components/moderation/ModerationDetailsDialog' import {Text} from '#/components/Typography' export type AppModerationCause = | ModerationCause | { type: 'reply-hidden' source: {type: 'user'; did: string} priority: 6 downgraded?: boolean } export type CommonProps = { size?: 'sm' | 'lg' } export function Row({ children, style, size = 'sm', }: {children: React.ReactNode | React.ReactNode[]} & CommonProps & ViewStyleProp) { const styles = useMemo(() => { switch (size) { case 'lg': return [{gap: 5}] case 'sm': default: return [{gap: 3}] } }, [size]) return ( {children} ) } export type LabelProps = { cause: AppModerationCause 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 === api.moderation.did const avi = size === 'lg' ? 16 : 12 return ( <> control.open()} icon={ isBlueskyLabel || !isLabeler ? ( ) : ( ) } /> {!disableDetailsDialog && ( )} ) } export type LabelBaseProps = { /** * The accessibility label for the pill. */ label: string /** * The visible pill text. Defaults to `label`. Use this when the visible * text is too terse to serve as the accessibility label, e.g. "+2". */ cta?: string onPress: () => void disabled?: boolean noBg?: boolean icon?: React.ReactNode } & CommonProps export function LabelBase({ label, cta = label, onPress, disabled, size = 'sm', noBg, icon, }: LabelBaseProps) { const t = useTheme() const enableSquareButtons = useEnableSquareButtons() const {outer, text} = useMemo(() => { switch (size) { case 'lg': { return { outer: [ t.atoms.bg_contrast_25, { gap: 5, paddingHorizontal: 5, paddingVertical: 5, }, ], text: [a.text_sm], } } case 'sm': default: { return { outer: [ !noBg && t.atoms.bg_contrast_25, { gap: 3, paddingHorizontal: 3, paddingVertical: 3, }, ], text: [a.text_xs], } } } }, [t, size, noBg]) return ( ) } export function FollowsYou({size = 'sm'}: CommonProps) { const t = useTheme() const variantStyles = useMemo(() => { switch (size) { case 'sm': case 'lg': default: return [ { paddingHorizontal: 6, paddingVertical: 3, borderRadius: 4, }, ] } }, [size]) return ( Follows you ) } export function MutedOnlyReposts(props: CommonProps) { const t = useTheme() const {t: l} = useLingui() const size = props.size === 'lg' ? 16 : 12 return ( } disabled={true} onPress={() => {}} /> ) }