bsky-app/src/view/com/profile/ProfileSubpageHeader.tsx
Stanislas Signoud 008893b911
Internationalize more strings (#2440)
Co-authored-by: Ansh <anshnanda10@gmail.com>
2024-01-09 14:37:15 -08:00

200 lines
5.6 KiB
TypeScript

import React from 'react'
import {Pressable, StyleSheet, View} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {useNavigation} from '@react-navigation/native'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {Text} from '../util/text/Text'
import {TextLink} from '../util/Link'
import {UserAvatar, UserAvatarType} from '../util/UserAvatar'
import {LoadingPlaceholder} from '../util/LoadingPlaceholder'
import {CenteredView} from '../util/Views'
import {sanitizeHandle} from 'lib/strings/handles'
import {makeProfileLink} from 'lib/routes/links'
import {NavigationProp} from 'lib/routes/types'
import {BACK_HITSLOP} from 'lib/constants'
import {isNative} from 'platform/detection'
import {useLightboxControls, ImagesLightbox} from '#/state/lightbox'
import {useLingui} from '@lingui/react'
import {Trans, msg} from '@lingui/macro'
import {useSetDrawerOpen} from '#/state/shell'
import {emitSoftReset} from '#/state/events'
export function ProfileSubpageHeader({
isLoading,
href,
title,
avatar,
isOwner,
creator,
avatarType,
children,
}: React.PropsWithChildren<{
isLoading?: boolean
href: string
title: string | undefined
avatar: string | undefined
isOwner: boolean | undefined
creator:
| {
did: string
handle: string
}
| undefined
avatarType: UserAvatarType
}>) {
const setDrawerOpen = useSetDrawerOpen()
const navigation = useNavigation<NavigationProp>()
const {_} = useLingui()
const {isMobile} = useWebMediaQueries()
const {openLightbox} = useLightboxControls()
const pal = usePalette('default')
const canGoBack = navigation.canGoBack()
const onPressBack = React.useCallback(() => {
if (navigation.canGoBack()) {
navigation.goBack()
} else {
navigation.navigate('Home')
}
}, [navigation])
const onPressMenu = React.useCallback(() => {
setDrawerOpen(true)
}, [setDrawerOpen])
const onPressAvi = React.useCallback(() => {
if (
avatar // TODO && !(view.moderation.avatar.blur && view.moderation.avatar.noOverride)
) {
openLightbox(new ImagesLightbox([{uri: avatar}], 0))
}
}, [openLightbox, avatar])
return (
<CenteredView style={pal.view}>
{isMobile && (
<View
style={[
{
flexDirection: 'row',
alignItems: 'center',
borderBottomWidth: 1,
paddingTop: isNative ? 0 : 8,
paddingBottom: 8,
paddingHorizontal: isMobile ? 12 : 14,
},
pal.border,
]}>
<Pressable
testID="headerDrawerBtn"
onPress={canGoBack ? onPressBack : onPressMenu}
hitSlop={BACK_HITSLOP}
style={canGoBack ? styles.backBtn : styles.backBtnWide}
accessibilityRole="button"
accessibilityLabel={canGoBack ? 'Back' : 'Menu'}
accessibilityHint="">
{canGoBack ? (
<FontAwesomeIcon
size={18}
icon="angle-left"
style={[styles.backIcon, pal.text]}
/>
) : (
<FontAwesomeIcon
size={18}
icon="bars"
style={[styles.backIcon, pal.textLight]}
/>
)}
</Pressable>
<View style={{flex: 1}} />
{children}
</View>
)}
<View
style={{
flexDirection: 'row',
alignItems: 'flex-start',
gap: 10,
paddingTop: 14,
paddingBottom: 6,
paddingHorizontal: isMobile ? 12 : 14,
}}>
<Pressable
testID="headerAviButton"
onPress={onPressAvi}
accessibilityRole="image"
accessibilityLabel={_(msg`View the avatar`)}
accessibilityHint=""
style={{width: 58}}>
<UserAvatar type={avatarType} size={58} avatar={avatar} />
</Pressable>
<View style={{flex: 1}}>
{isLoading ? (
<LoadingPlaceholder
width={200}
height={32}
style={{marginVertical: 6}}
/>
) : (
<TextLink
testID="headerTitle"
type="title-xl"
href={href}
style={[pal.text, {fontWeight: 'bold'}]}
text={title || ''}
onPress={emitSoftReset}
numberOfLines={4}
/>
)}
{isLoading ? (
<LoadingPlaceholder width={50} height={8} />
) : (
<Text type="xl" style={[pal.textLight]} numberOfLines={1}>
{!creator ? (
<Trans>by </Trans>
) : isOwner ? (
<Trans>by you</Trans>
) : (
<Trans>
by{' '}
<TextLink
text={sanitizeHandle(creator.handle, '@')}
href={makeProfileLink(creator)}
style={pal.textLight}
/>
</Trans>
)}
</Text>
)}
</View>
{!isMobile && (
<View
style={{
flexDirection: 'row',
alignItems: 'center',
}}>
{children}
</View>
)}
</View>
</CenteredView>
)
}
const styles = StyleSheet.create({
backBtn: {
width: 20,
height: 30,
},
backBtnWide: {
width: 20,
height: 30,
paddingHorizontal: 6,
},
backIcon: {
marginTop: 6,
},
})