import React, { useMemo } from 'react'; import { useState } from 'react'; import { Image as RNImage, ImageProps, Text, TouchableOpacity, View, TouchableOpacityProps, ActivityIndicatorProps } from 'react-native'; import { themeColors, ThemeName } from '../constants/Colors'; import useTheme from '../hooks/useTheme'; import Skeleton from './Skeleton' export type Props = ImageProps & { src: string | null | undefined; showImageError?: boolean; blurUrl?: string | null | undefined; source?: undefined; isTouchableOpacity?: boolean; touchableOpacityProps?: TouchableOpacityProps activityIndicatorProps?: ActivityIndicatorProps isActivityIndicator?: boolean; borderVariant?: "default" | "secondary" | ThemeName; borderWidth?: number; isBorder?: boolean; borderStyle?: TouchableOpacityProps["style"]; onPress?: () => void; onLongPress?: () => void; size: number; themeScheme?: "light" | "dark"; }; const Avatar = ({ style, src, themeScheme, isTouchableOpacity = false, touchableOpacityProps, activityIndicatorProps, isActivityIndicator = true, showImageError = false, blurUrl, borderWidth = 0, borderVariant = "default", onPress, onLongPress, size = 60, ...otherProps }: Props) => { const { currentTheme, themeScheme: defaultThemeScheme } = useTheme(); const [state, setState] = useState<"idle" | "pending" | "normal" | "error">("idle"); borderWidth = borderWidth > 0 ? borderWidth : 0 const colorStyle = useMemo(() => { if (borderVariant === 'default') { return { isFocused: currentTheme.primary }; } if (borderVariant === 'secondary') { return { isFocused: currentTheme.secondary }; } const theme = themeColors.find((t) => t.name === borderVariant)?.[themeScheme ?? defaultThemeScheme]; return { isFocused: theme?.primary ?? currentTheme.primary }; }, [currentTheme, themeScheme, defaultThemeScheme, borderVariant]); if (state === "error" && showImageError || !src) { return ( 0 ? borderWidth : 0, justifyContent: "center", alignItems: "center", }}> {/* */} Failed to load image ) } const ImageComponent = () => { return ( { if (state === "error") return; setState("error") }} onLoadEnd={() => { if (state === "normal") return; setState("normal") }} {...otherProps} />) } return ( <> ) } export default Avatar;