import React from 'react' import {findNodeHandle, View} from 'react-native' import {useSafeAreaFrame} from 'react-native-safe-area-context' import { AppBskyLabelerDefs, InterpretedLabelValueDefinition, interpretLabelValueDefinitions, ModerationOpts, } from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED' import {isLabelerSubscribed, lookupLabelValueDefinition} from '#/lib/moderation' import {useScrollHandlers} from '#/lib/ScrollContext' import {isNative} from '#/platform/detection' import {ListRef} from '#/view/com/util/List' import {ScrollView} from '#/view/com/util/Views' import {atoms as a, useTheme} from '#/alf' import {Divider} from '#/components/Divider' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' import * as Layout from '#/components/Layout' import {Loader} from '#/components/Loader' import {LabelerLabelPreference} from '#/components/moderation/LabelPreference' import {Text} from '#/components/Typography' import {ErrorState} from '../ErrorState' import {SectionRef} from './types' interface LabelsSectionProps { isLabelerLoading: boolean labelerInfo: AppBskyLabelerDefs.LabelerViewDetailed | undefined labelerError: Error | null moderationOpts: ModerationOpts scrollElRef: ListRef headerHeight: number isFocused: boolean setScrollViewTag: (tag: number | null) => void } export const ProfileLabelsSection = React.forwardRef< SectionRef, LabelsSectionProps >(function LabelsSectionImpl( { isLabelerLoading, labelerInfo, labelerError, moderationOpts, scrollElRef, headerHeight, isFocused, setScrollViewTag, }, ref, ) { const {_} = useLingui() const {height: minHeight} = useSafeAreaFrame() const onScrollToTop = React.useCallback(() => { // @ts-ignore TODO fix this scrollElRef.current?.scrollTo({ animated: isNative, x: 0, y: -headerHeight, }) }, [scrollElRef, headerHeight]) React.useImperativeHandle(ref, () => ({ scrollToTop: onScrollToTop, })) React.useEffect(() => { if (isFocused && scrollElRef.current) { const nativeTag = findNodeHandle(scrollElRef.current) setScrollViewTag(nativeTag) } }, [isFocused, scrollElRef, setScrollViewTag]) return ( {isLabelerLoading ? ( ) : labelerError || !labelerInfo ? ( ) : ( )} ) }) export function ProfileLabelsSectionInner({ moderationOpts, labelerInfo, scrollElRef, headerHeight, }: { moderationOpts: ModerationOpts labelerInfo: AppBskyLabelerDefs.LabelerViewDetailed scrollElRef: ListRef headerHeight: number }) { const t = useTheme() // Intentionally destructured outside the main thread closure. // See https://github.com/bluesky-social/social-app/pull/4108. const { onBeginDrag: onBeginDragFromContext, onEndDrag: onEndDragFromContext, onScroll: onScrollFromContext, onMomentumEnd: onMomentumEndFromContext, } = useScrollHandlers() const scrollHandler = useAnimatedScrollHandler({ onBeginDrag(e, ctx) { onBeginDragFromContext?.(e, ctx) }, onEndDrag(e, ctx) { onEndDragFromContext?.(e, ctx) }, onScroll(e, ctx) { onScrollFromContext?.(e, ctx) }, onMomentumEnd(e, ctx) { onMomentumEndFromContext?.(e, ctx) }, }) const {labelValues} = labelerInfo.policies const isSubscribed = isLabelerSubscribed(labelerInfo, moderationOpts) const labelDefs = React.useMemo(() => { const customDefs = interpretLabelValueDefinitions(labelerInfo) return labelValues .map(val => lookupLabelValueDefinition(val, customDefs)) .filter( def => def && def?.configurable, ) as InterpretedLabelValueDefinition[] }, [labelerInfo, labelValues]) return ( Labels are annotations on users and content. They can be used to hide, warn, and categorize the network. {labelerInfo.creator.viewer?.blocking ? ( Blocking does not prevent this labeler from placing labels on your account. ) : null} {labelValues.length === 0 ? ( This labeler hasn't declared what labels it publishes, and may not be active. ) : !isSubscribed ? ( Subscribe to @{labelerInfo.creator.handle} to use these labels: ) : null} {labelDefs.length > 0 && ( {labelDefs.map((labelDef, i) => { return ( {i !== 0 && } ) })} )} ) }