# Asset Management ## Folder Structure ``` src/assets/ ├── images/ │ ├── logo.png │ ├── logo@2x.png │ └── logo@3x.png ├── icons/ │ └── index.ts └── fonts/ ├── Montserrat-Regular.ttf └── Montserrat-Bold.ttf ``` ## Image Management **Create image index file:** ```typescript // src/assets/images/index.ts export const Images = { logo: require('./logo.png'), splash: require('./splash.png'), placeholder: require('./placeholder.png'), // Add more images here }; ``` **Usage in components:** ```typescript import {Images} from '@assets/images'; import {Image} from 'react-native'; const MyComponent = () => ( ); ``` ## Icon Management **Install react-native-vector-icons:** ```bash yarn add react-native-vector-icons yarn add -D @types/react-native-vector-icons # iOS setup cd ios && pod install ``` **Create icon component:** ```typescript // src/components/common/Icon/Icon.tsx import React from 'react'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; import Ionicons from 'react-native-vector-icons/Ionicons'; import FontAwesome from 'react-native-vector-icons/FontAwesome'; type IconFamily = 'MaterialIcons' | 'Ionicons' | 'FontAwesome'; interface IconProps { name: string; size?: number; color?: string; family?: IconFamily; } const IconComponents = { MaterialIcons, Ionicons, FontAwesome, }; export const Icon: React.FC = ({ name, size = 24, color = '#000', family = 'MaterialIcons', }) => { const IconComponent = IconComponents[family]; return ; }; ``` ## SVG Icons **Install react-native-svg:** ```bash yarn add react-native-svg yarn add -D @types/react-native-svg # iOS setup cd ios && pod install ``` **Create SVG icon component:** ```typescript // src/components/common/SvgIcon/SvgIcon.tsx import React from 'react'; import Svg, {Path, Circle, Rect} from 'react-native-svg'; interface SvgIconProps { name: string; size?: number; color?: string; } const iconPaths = { home: 'M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z', user: 'M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z', // Add more icon paths }; export const SvgIcon: React.FC = ({ name, size = 24, color = '#000', }) => { const path = iconPaths[name as keyof typeof iconPaths]; if (!path) { console.warn(`Icon "${name}" not found`); return null; } return ( ); }; ``` ## Image Optimization **Install react-native-fast-image:** ```bash yarn add react-native-fast-image # iOS setup cd ios && pod install ``` **Optimized image component:** ```typescript // src/components/common/OptimizedImage/OptimizedImage.tsx import React from 'react'; import FastImage, {FastImageProps} from 'react-native-fast-image'; import {StyleSheet, View, ActivityIndicator} from 'react-native'; interface OptimizedImageProps extends FastImageProps { showLoader?: boolean; loaderColor?: string; } export const OptimizedImage: React.FC = ({ showLoader = true, loaderColor = '#007AFF', style, ...props }) => { const [loading, setLoading] = React.useState(true); return ( setLoading(true)} onLoadEnd={() => setLoading(false)} resizeMode={FastImage.resizeMode.cover} /> {loading && showLoader && ( )} ); }; const styles = StyleSheet.create({ loader: { ...StyleSheet.absoluteFillObject, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0, 0, 0, 0.1)', }, }); ``` ## Asset Preloading ```typescript // src/utils/assetPreloader.ts import {Image} from 'react-native'; import {Images} from '@assets/images'; export const preloadImages = async (): Promise => { const imagePromises = Object.values(Images).map(image => { return new Promise((resolve, reject) => { Image.prefetch(Image.resolveAssetSource(image).uri) .then(() => resolve()) .catch(reject); }); }); try { await Promise.all(imagePromises); console.log('All images preloaded successfully'); } catch (error) { console.error('Error preloading images:', error); } }; ``` ## Image Caching Strategy ```typescript // src/utils/imageCache.ts import AsyncStorage from '@react-native-async-storage/async-storage'; import RNFS from 'react-native-fs'; const CACHE_DIR = `${RNFS.CachesDirectoryPath}/images`; const CACHE_KEY_PREFIX = 'image_cache_'; export class ImageCache { static async getCachedImagePath(url: string): Promise { try { const cacheKey = `${CACHE_KEY_PREFIX}${this.hashUrl(url)}`; const cachedPath = await AsyncStorage.getItem(cacheKey); if (cachedPath && await RNFS.exists(cachedPath)) { return cachedPath; } return null; } catch (error) { console.error('Error getting cached image:', error); return null; } } static async cacheImage(url: string): Promise { try { const fileName = this.hashUrl(url); const filePath = `${CACHE_DIR}/${fileName}`; const cacheKey = `${CACHE_KEY_PREFIX}${fileName}`; // Ensure cache directory exists await RNFS.mkdir(CACHE_DIR); // Download and cache the image await RNFS.downloadFile({ fromUrl: url, toFile: filePath, }).promise; // Store the path in AsyncStorage await AsyncStorage.setItem(cacheKey, filePath); return filePath; } catch (error) { console.error('Error caching image:', error); throw error; } } private static hashUrl(url: string): string { // Simple hash function for URL let hash = 0; for (let i = 0; i < url.length; i++) { const char = url.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash = hash & hash; // Convert to 32-bit integer } return Math.abs(hash).toString(); } } ```