diff options
Diffstat (limited to 'src/screens/Profile/Sections/Labels.tsx')
-rw-r--r-- | src/screens/Profile/Sections/Labels.tsx | 251 |
1 files changed, 123 insertions, 128 deletions
diff --git a/src/screens/Profile/Sections/Labels.tsx b/src/screens/Profile/Sections/Labels.tsx index 770464a71..b7f702f11 100644 --- a/src/screens/Profile/Sections/Labels.tsx +++ b/src/screens/Profile/Sections/Labels.tsx @@ -1,11 +1,12 @@ import React from 'react' import {findNodeHandle, View} from 'react-native' +import type Animated from 'react-native-reanimated' import {useSafeAreaFrame} from 'react-native-safe-area-context' import { - AppBskyLabelerDefs, - InterpretedLabelValueDefinition, + type AppBskyLabelerDefs, + type InterpretedLabelValueDefinition, interpretLabelValueDefinitions, - ModerationOpts, + type ModerationOpts, } from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -14,7 +15,7 @@ import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIX import {isLabelerSubscribed, lookupLabelValueDefinition} from '#/lib/moderation' import {useScrollHandlers} from '#/lib/ScrollContext' import {isNative} from '#/platform/detection' -import {ListRef} from '#/view/com/util/List' +import {type ListRef} from '#/view/com/util/List' import {atoms as a, useTheme} from '#/alf' import {Divider} from '#/components/Divider' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' @@ -23,7 +24,7 @@ import {Loader} from '#/components/Loader' import {LabelerLabelPreference} from '#/components/moderation/LabelPreference' import {Text} from '#/components/Typography' import {ErrorState} from '../ErrorState' -import {SectionRef} from './types' +import {type SectionRef} from './types' interface LabelsSectionProps { isLabelerLoading: boolean @@ -54,6 +55,29 @@ export const ProfileLabelsSection = React.forwardRef< const {_} = useLingui() const {height: minHeight} = useSafeAreaFrame() + // 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 onScrollToTop = React.useCallback(() => { // @ts-ignore TODO fix this scrollElRef.current?.scrollTo({ @@ -75,26 +99,36 @@ export const ProfileLabelsSection = React.forwardRef< }, [isFocused, scrollElRef, setScrollViewTag]) return ( - <Layout.Center style={{flex: 1, minHeight}}> - {isLabelerLoading ? ( - <View style={[a.w_full, a.align_center]}> - <Loader size="xl" /> - </View> - ) : labelerError || !labelerInfo ? ( - <ErrorState - error={ - labelerError?.toString() || - _(msg`Something went wrong, please try again.`) - } - /> - ) : ( - <ProfileLabelsSectionInner - moderationOpts={moderationOpts} - labelerInfo={labelerInfo} - scrollElRef={scrollElRef} - headerHeight={headerHeight} - /> - )} + <Layout.Center style={{minHeight}}> + <Layout.Content + ref={scrollElRef as React.Ref<Animated.ScrollView>} + scrollEventThrottle={1} + contentContainerStyle={{ + paddingTop: headerHeight, + borderWidth: 0, + }} + contentOffset={{x: 0, y: headerHeight * -1}} + onScroll={scrollHandler}> + {isLabelerLoading ? ( + <View style={[a.w_full, a.align_center, a.py_4xl]}> + <Loader size="xl" /> + </View> + ) : labelerError || !labelerInfo ? ( + <View style={[a.w_full, a.align_center, a.py_4xl]}> + <ErrorState + error={ + labelerError?.toString() || + _(msg`Something went wrong, please try again.`) + } + /> + </View> + ) : ( + <ProfileLabelsSectionInner + moderationOpts={moderationOpts} + labelerInfo={labelerInfo} + /> + )} + </Layout.Content> </Layout.Center> ) }) @@ -102,39 +136,12 @@ export const ProfileLabelsSection = React.forwardRef< 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(() => { @@ -147,88 +154,76 @@ export function ProfileLabelsSectionInner({ }, [labelerInfo, labelValues]) return ( - <Layout.Content - // @ts-expect-error TODO fix this - ref={scrollElRef} - scrollEventThrottle={1} - contentContainerStyle={{ - paddingTop: headerHeight, - borderWidth: 0, - }} - contentOffset={{x: 0, y: headerHeight * -1}} - onScroll={scrollHandler}> - <View style={[a.pt_xl, a.px_lg, a.border_t, t.atoms.border_contrast_low]}> - <View> - <Text style={[t.atoms.text_contrast_high, a.leading_snug, a.text_sm]}> - <Trans> - Labels are annotations on users and content. They can be used to - hide, warn, and categorize the network. - </Trans> - </Text> - {labelerInfo.creator.viewer?.blocking ? ( - <View style={[a.flex_row, a.gap_sm, a.align_center, a.mt_md]}> - <CircleInfo size="sm" fill={t.atoms.text_contrast_medium.color} /> - <Text - style={[t.atoms.text_contrast_high, a.leading_snug, a.text_sm]}> - <Trans> - Blocking does not prevent this labeler from placing labels on - your account. - </Trans> - </Text> - </View> - ) : null} - {labelValues.length === 0 ? ( + <View style={[a.pt_xl, a.px_lg, a.border_t, t.atoms.border_contrast_low]}> + <View> + <Text style={[t.atoms.text_contrast_high, a.leading_snug, a.text_sm]}> + <Trans> + Labels are annotations on users and content. They can be used to + hide, warn, and categorize the network. + </Trans> + </Text> + {labelerInfo.creator.viewer?.blocking ? ( + <View style={[a.flex_row, a.gap_sm, a.align_center, a.mt_md]}> + <CircleInfo size="sm" fill={t.atoms.text_contrast_medium.color} /> <Text - style={[ - a.pt_xl, - t.atoms.text_contrast_high, - a.leading_snug, - a.text_sm, - ]}> + style={[t.atoms.text_contrast_high, a.leading_snug, a.text_sm]}> <Trans> - This labeler hasn't declared what labels it publishes, and may - not be active. + Blocking does not prevent this labeler from placing labels on + your account. </Trans> </Text> - ) : !isSubscribed ? ( - <Text - style={[ - a.pt_xl, - t.atoms.text_contrast_high, - a.leading_snug, - a.text_sm, - ]}> - <Trans> - Subscribe to @{labelerInfo.creator.handle} to use these labels: - </Trans> - </Text> - ) : null} - </View> - {labelDefs.length > 0 && ( - <View + </View> + ) : null} + {labelValues.length === 0 ? ( + <Text style={[ - a.mt_xl, - a.w_full, - a.rounded_md, - a.overflow_hidden, - t.atoms.bg_contrast_25, + a.pt_xl, + t.atoms.text_contrast_high, + a.leading_snug, + a.text_sm, ]}> - {labelDefs.map((labelDef, i) => { - return ( - <React.Fragment key={labelDef.identifier}> - {i !== 0 && <Divider />} - <LabelerLabelPreference - disabled={isSubscribed ? undefined : true} - labelDefinition={labelDef} - labelerDid={labelerInfo.creator.did} - /> - </React.Fragment> - ) - })} - </View> - )} - <View style={{height: 100}} /> + <Trans> + This labeler hasn't declared what labels it publishes, and may not + be active. + </Trans> + </Text> + ) : !isSubscribed ? ( + <Text + style={[ + a.pt_xl, + t.atoms.text_contrast_high, + a.leading_snug, + a.text_sm, + ]}> + <Trans> + Subscribe to @{labelerInfo.creator.handle} to use these labels: + </Trans> + </Text> + ) : null} </View> - </Layout.Content> + {labelDefs.length > 0 && ( + <View + style={[ + a.mt_xl, + a.w_full, + a.rounded_md, + a.overflow_hidden, + t.atoms.bg_contrast_25, + ]}> + {labelDefs.map((labelDef, i) => { + return ( + <React.Fragment key={labelDef.identifier}> + {i !== 0 && <Divider />} + <LabelerLabelPreference + disabled={isSubscribed ? undefined : true} + labelDefinition={labelDef} + labelerDid={labelerInfo.creator.did} + /> + </React.Fragment> + ) + })} + </View> + )} + </View> ) } |