105 lines
1.9 KiB
TypeScript
105 lines
1.9 KiB
TypeScript
import { Image } from 'expo-image';
|
|
import {
|
|
StyleSheet,
|
|
Text,
|
|
View,
|
|
type ImageStyle,
|
|
type StyleProp,
|
|
type ViewStyle,
|
|
} from 'react-native';
|
|
|
|
import { Catamaran, FunnelSans } from '@/constants/fonts';
|
|
import { Palette } from '@/constants/palette';
|
|
import { Radius } from '@/constants/styles';
|
|
|
|
type AvatarSize = 'sm' | 'md' | 'lg';
|
|
|
|
type AvatarProps = {
|
|
uri?: string | null;
|
|
name?: string | null;
|
|
size?: AvatarSize;
|
|
style?: StyleProp<ImageStyle>;
|
|
};
|
|
|
|
const avatarSizeMap = {
|
|
sm: 40,
|
|
md: 64,
|
|
lg: 104,
|
|
} as const;
|
|
|
|
function getInitials(name?: string | null) {
|
|
if (!name?.trim()) {
|
|
return '?';
|
|
}
|
|
|
|
const parts = name
|
|
.trim()
|
|
.split(/\s+/)
|
|
.slice(0, 2);
|
|
|
|
return parts.map((part) => part[0]?.toUpperCase() ?? '').join('') || '?';
|
|
}
|
|
|
|
export function Avatar({ uri, name, size = 'md', style }: AvatarProps) {
|
|
const avatarSize = avatarSizeMap[size];
|
|
const initials = getInitials(name);
|
|
|
|
if (uri) {
|
|
return (
|
|
<Image
|
|
contentFit="cover"
|
|
source={{ uri }}
|
|
style={[
|
|
styles.base,
|
|
{
|
|
width: avatarSize,
|
|
height: avatarSize,
|
|
borderRadius: avatarSize / 2,
|
|
},
|
|
style,
|
|
]}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<View
|
|
style={[
|
|
styles.base,
|
|
styles.fallback,
|
|
{
|
|
width: avatarSize,
|
|
height: avatarSize,
|
|
borderRadius: avatarSize / 2,
|
|
},
|
|
style,
|
|
]}
|
|
>
|
|
<Text style={[size === 'lg' ? styles.largeText : styles.text]}>{initials}</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
base: {
|
|
overflow: 'hidden',
|
|
},
|
|
fallback: {
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
backgroundColor: Palette.black,
|
|
borderWidth: 1,
|
|
borderColor: Palette.gray,
|
|
},
|
|
text: {
|
|
...FunnelSans.semiBold14,
|
|
color: Palette.white,
|
|
},
|
|
largeText: {
|
|
...Catamaran.bold18,
|
|
color: Palette.white,
|
|
},
|
|
});
|
|
|
|
export default Avatar;
|