import { Pressable, View } from 'react-native'; import { Text } from '@/components/Text'; import { spacing } from '@/theme'; import { useRipple } from '@/theme/ripple'; import { createThemedStyles, useColors } from '@/theme/themed'; import { useLibraryStore } from '@/stores/libraryStore'; /** Thin accent bar + caption shown under the library header while scanning. */ export function ScanProgress() { const styles = useStyles(); const colors = useColors(); const ripple = useRipple(); const isScanning = useLibraryStore((s) => s.isScanning); const isCancelling = useLibraryStore((s) => s.isCancelling); const progress = useLibraryStore((s) => s.scanProgress); const cancelScan = useLibraryStore((s) => s.cancelScan); if (!isScanning) return null; const label = progress.phase === 'analyzing' ? `Analyzing audio… ${progress.processed}/${progress.total}` : progress.phase === 'extracting' ? `Scanning ${progress.folderName ?? ''}… ${progress.processed}/${progress.total}` : progress.total > 0 ? `Found ${progress.total} files in ${progress.folderName ?? ''}…` : `Looking for music${progress.folderName ? ` in ${progress.folderName}` : ''}…`; const fraction = (progress.phase === 'extracting' || progress.phase === 'analyzing') && progress.total > 0 ? progress.processed / progress.total : 0; return ( {label} {isCancelling ? 'Cancelling…' : 'Cancel'} 0 ? { width: `${fraction * 100}%` } : styles.fillIndeterminate, ]} /> ); } const useStyles = createThemedStyles((colors) => ({ container: { gap: spacing.xs, marginBottom: spacing.md, }, labelRow: { minHeight: 32, flexDirection: 'row', alignItems: 'center', gap: spacing.sm, }, label: { flex: 1, }, cancelButton: { minHeight: 32, justifyContent: 'center', paddingHorizontal: spacing.xs, }, track: { height: 2, backgroundColor: colors.glassBorder, borderRadius: 1, overflow: 'hidden', }, fill: { height: 2, backgroundColor: colors.accent, }, fillIndeterminate: { width: '100%', opacity: 0.35, }, }));