mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at next/base 198 lines 6.1 kB view raw
1import React from 'react' 2import {Pressable, View} from 'react-native' 3import {MeasuredDimensions, runOnJS, runOnUI} from 'react-native-reanimated' 4import {AppBskyGraphDefs} from '@atproto/api' 5import {msg, Trans} from '@lingui/macro' 6import {useLingui} from '@lingui/react' 7import {useNavigation} from '@react-navigation/native' 8 9import {measureHandle, useHandleRef} from '#/lib/hooks/useHandleRef' 10import {usePalette} from '#/lib/hooks/usePalette' 11import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 12import {makeProfileLink} from '#/lib/routes/links' 13import {NavigationProp} from '#/lib/routes/types' 14import {sanitizeHandle} from '#/lib/strings/handles' 15import {emitSoftReset} from '#/state/events' 16import {useLightboxControls} from '#/state/lightbox' 17import {TextLink} from '#/view/com/util/Link' 18import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' 19import {Text} from '#/view/com/util/text/Text' 20import {UserAvatar, UserAvatarType} from '#/view/com/util/UserAvatar' 21import {StarterPack} from '#/components/icons/StarterPack' 22import * as Layout from '#/components/Layout' 23 24export function ProfileSubpageHeader({ 25 isLoading, 26 href, 27 title, 28 avatar, 29 isOwner, 30 purpose, 31 creator, 32 avatarType, 33 children, 34}: React.PropsWithChildren<{ 35 isLoading?: boolean 36 href: string 37 title: string | undefined 38 avatar: string | undefined 39 isOwner: boolean | undefined 40 purpose: AppBskyGraphDefs.ListPurpose | undefined 41 creator: 42 | { 43 did: string 44 handle: string 45 } 46 | undefined 47 avatarType: UserAvatarType | 'starter-pack' 48}>) { 49 const navigation = useNavigation<NavigationProp>() 50 const {_} = useLingui() 51 const {isMobile} = useWebMediaQueries() 52 const {openLightbox} = useLightboxControls() 53 const pal = usePalette('default') 54 const canGoBack = navigation.canGoBack() 55 const aviRef = useHandleRef() 56 57 const _openLightbox = React.useCallback( 58 (uri: string, thumbRect: MeasuredDimensions | null) => { 59 openLightbox({ 60 images: [ 61 { 62 uri, 63 thumbUri: uri, 64 thumbRect, 65 dimensions: { 66 // It's fine if it's actually smaller but we know it's 1:1. 67 height: 1000, 68 width: 1000, 69 }, 70 thumbDimensions: null, 71 type: 'rect-avi', 72 }, 73 ], 74 index: 0, 75 }) 76 }, 77 [openLightbox], 78 ) 79 80 const onPressAvi = React.useCallback(() => { 81 if ( 82 avatar // TODO && !(view.moderation.avatar.blur && view.moderation.avatar.noOverride) 83 ) { 84 const aviHandle = aviRef.current 85 runOnUI(() => { 86 'worklet' 87 const rect = measureHandle(aviHandle) 88 runOnJS(_openLightbox)(avatar, rect) 89 })() 90 } 91 }, [_openLightbox, avatar, aviRef]) 92 93 return ( 94 <> 95 <Layout.Header.Outer> 96 {canGoBack ? ( 97 <Layout.Header.BackButton /> 98 ) : ( 99 <Layout.Header.MenuButton /> 100 )} 101 <Layout.Header.Content /> 102 {children} 103 </Layout.Header.Outer> 104 105 <View 106 style={{ 107 flexDirection: 'row', 108 alignItems: 'flex-start', 109 gap: 10, 110 paddingTop: 14, 111 paddingBottom: 14, 112 paddingHorizontal: isMobile ? 12 : 14, 113 }}> 114 <View ref={aviRef} collapsable={false}> 115 <Pressable 116 testID="headerAviButton" 117 onPress={onPressAvi} 118 accessibilityRole="image" 119 accessibilityLabel={_(msg`View the avatar`)} 120 accessibilityHint="" 121 style={{width: 58}}> 122 {avatarType === 'starter-pack' ? ( 123 <StarterPack width={58} gradient="sky" /> 124 ) : ( 125 <UserAvatar type={avatarType} size={58} avatar={avatar} /> 126 )} 127 </Pressable> 128 </View> 129 <View style={{flex: 1, gap: 4}}> 130 {isLoading ? ( 131 <LoadingPlaceholder 132 width={200} 133 height={32} 134 style={{marginVertical: 6}} 135 /> 136 ) : ( 137 <TextLink 138 testID="headerTitle" 139 type="title-xl" 140 href={href} 141 style={[pal.text, {fontWeight: '600'}]} 142 text={title || ''} 143 onPress={emitSoftReset} 144 numberOfLines={4} 145 /> 146 )} 147 148 {isLoading || !creator ? ( 149 <LoadingPlaceholder width={50} height={8} /> 150 ) : ( 151 <Text type="lg" style={[pal.textLight]} numberOfLines={1}> 152 {purpose === 'app.bsky.graph.defs#curatelist' ? ( 153 isOwner ? ( 154 <Trans>List by you</Trans> 155 ) : ( 156 <Trans> 157 List by{' '} 158 <TextLink 159 text={sanitizeHandle(creator.handle || '', '@')} 160 href={makeProfileLink(creator)} 161 style={pal.textLight} 162 /> 163 </Trans> 164 ) 165 ) : purpose === 'app.bsky.graph.defs#modlist' ? ( 166 isOwner ? ( 167 <Trans>Moderation list by you</Trans> 168 ) : ( 169 <Trans> 170 Moderation list by{' '} 171 <TextLink 172 text={sanitizeHandle(creator.handle || '', '@')} 173 href={makeProfileLink(creator)} 174 style={pal.textLight} 175 /> 176 </Trans> 177 ) 178 ) : purpose === 'app.bsky.graph.defs#referencelist' ? ( 179 isOwner ? ( 180 <Trans>Starter pack by you</Trans> 181 ) : ( 182 <Trans> 183 Starter pack by{' '} 184 <TextLink 185 text={sanitizeHandle(creator.handle || '', '@')} 186 href={makeProfileLink(creator)} 187 style={pal.textLight} 188 /> 189 </Trans> 190 ) 191 ) : null} 192 </Text> 193 )} 194 </View> 195 </View> 196 </> 197 ) 198}