import React, { useState, useEffect } from 'react' import { Image, View, StyleSheet } from 'react-native' interface Props { uri: string originalWidth?: number originalHeight?: number minWidth?: number maxWidth?: number minHeight?: number maxHeight?: number borderRadius?: number style?: object } function computeDimensions( srcWidth: number, srcHeight: number, minWidth: number, maxWidth: number, minHeight: number, maxHeight: number, ): { width: number; height: number } { if (srcWidth <= 0 || srcHeight <= 0) { return { width: minWidth, height: minHeight } } const aspectRatio = srcWidth / srcHeight // Start from maxWidth and compute height let width = maxWidth let height = width / aspectRatio // If height exceeds maxHeight, clamp by height if (height > maxHeight) { height = maxHeight width = height * aspectRatio } // Enforce minimums if (width < minWidth) { width = minWidth height = width / aspectRatio } if (height < minHeight) { height = minHeight width = height * aspectRatio } // Final clamp to maximums after minimum adjustments width = Math.min(width, maxWidth) height = Math.min(height, maxHeight) return { width: Math.round(width), height: Math.round(height) } } export function ScaledImage(props: Props): JSX.Element { const { uri, originalWidth, originalHeight, minWidth = 120, maxWidth = 240, minHeight = 80, maxHeight = 320, borderRadius, style, } = props const [dimensions, setDimensions] = useState<{ width: number; height: number } | null>(() => { if (originalWidth !== undefined && originalHeight !== undefined) { return computeDimensions(originalWidth, originalHeight, minWidth, maxWidth, minHeight, maxHeight) } return null }) useEffect(() => { if (originalWidth !== undefined && originalHeight !== undefined) { setDimensions( computeDimensions(originalWidth, originalHeight, minWidth, maxWidth, minHeight, maxHeight), ) return } // Use Image.getSize to determine dimensions at runtime Image.getSize( uri, (w, h) => { setDimensions(computeDimensions(w, h, minWidth, maxWidth, minHeight, maxHeight)) }, () => { // Fallback to min dimensions on error setDimensions({ width: minWidth, height: minHeight }) }, ) }, [uri, originalWidth, originalHeight, minWidth, maxWidth, minHeight, maxHeight]) if (!dimensions) { // Placeholder while size is being resolved return } return ( ) } const styles = StyleSheet.create({ placeholder: { backgroundColor: '#e0e0e0', }, })