import React, { useEffect } from 'react'; import { View, Text, Image, ActivityIndicator, StyleSheet } from 'react-native'; import { LinearGradient } from 'expo-linear-gradient'; import { Ionicons } from '@expo/vector-icons'; import Animated, { FadeIn, useSharedValue, useAnimatedStyle, withRepeat, withTiming, interpolate, Easing, } from 'react-native-reanimated'; import { colors, gradients, spacing, radius } from '../../../theme'; import { UploadStatus } from '../types'; export interface UploadProgressProps { uploadStatus: UploadStatus; } const ACCENT = colors.premium.gold; /** * Upload progress skeleton component showing when media is being uploaded. * Displays a shimmer effect with thumbnail preview for images. */ export function UploadProgress({ uploadStatus }: UploadProgressProps) { const shimmer = useSharedValue(0); useEffect(() => { shimmer.value = withRepeat( withTiming(1, { duration: 1500, easing: Easing.inOut(Easing.ease) }), -1, false ); }, []); const shimmerStyle = useAnimatedStyle(() => ({ opacity: interpolate(shimmer.value, [0, 0.5, 1], [0.3, 0.6, 0.3]), })); if (!uploadStatus) return null; const isVideo = uploadStatus.mediaType === 'video'; const statusText = uploadStatus.status === 'compressing' ? 'Compressing video...' : `Uploading ${isVideo ? 'video' : 'image'}...`; return ( {/* Silk highlight */} {/* Skeleton media placeholder */} {uploadStatus.thumbnailUri && !isVideo ? ( ) : ( )} {/* Overlay with spinner and status */} {statusText} ); } const styles = StyleSheet.create({ container: { alignItems: 'flex-end', marginBottom: spacing.sm, paddingHorizontal: spacing.md, }, bubbleContainer: { maxWidth: '80%', }, bubble: { borderRadius: radius.xl, borderTopRightRadius: radius.sm, overflow: 'hidden', minWidth: 200, }, silkHighlight: { position: 'absolute', top: 0, left: 0, right: 0, height: 40, }, mediaSkeleton: { height: 180, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0, 0, 0, 0.2)', }, thumbnail: { ...StyleSheet.absoluteFill, }, iconContainer: { width: 64, height: 64, borderRadius: 32, backgroundColor: 'rgba(255, 255, 255, 0.1)', justifyContent: 'center', alignItems: 'center', }, overlay: { ...StyleSheet.absoluteFill, backgroundColor: 'rgba(0, 0, 0, 0.5)', justifyContent: 'center', alignItems: 'center', gap: spacing.sm, }, statusText: { color: colors.textSecondary, fontSize: 13, }, }); export default UploadProgress;