import useDefaultStyles from '@/components/Colors'; import React, { useCallback, useMemo } from 'react'; import { FlatListProps, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useAppDispatch, useTypedSelector } from '@/store'; import formatBytes from '@/utility/formatBytes'; import TrashIcon from '@/assets/icons/trash.svg'; import ArrowClockwise from '@/assets/icons/arrow-clockwise.svg'; import { queueTrackForDownload, removeDownloadedTrack } from '@/store/downloads/actions'; import Button from '@/components/Button'; import DownloadIcon from '@/components/DownloadIcon'; import styled from 'styled-components/native'; import { Text } from '@/components/Typography'; import FastImage from 'react-native-fast-image'; import { useGetImage } from '@/utility/JellyfinApi'; import { ShadowWrapper } from '@/components/Shadow'; import { SafeFlatList } from '@/components/SafeNavigatorView'; import { THEME_COLOR } from '@/CONSTANTS'; import { t } from '@/localisation'; const DownloadedTrack = styled.View` flex: 1 0 auto; flex-direction: row; padding: 8px 0; align-items: center; margin: 0 20px; `; const AlbumImage = styled(FastImage)` height: 32px; width: 32px; border-radius: 4px; `; const ErrorWrapper = styled.View` padding: 2px 16px 8px 16px; `; function Downloads() { const defaultStyles = useDefaultStyles(); const dispatch = useAppDispatch(); const getImage = useGetImage(); const { entities, ids } = useTypedSelector((state) => state.downloads); const tracks = useTypedSelector((state) => state.music.tracks.entities); // Calculate the total download size const totalDownloadSize = useMemo(() => ( ids?.reduce((sum, id) => sum + (entities[id]?.size || 0), 0) ), [ids, entities]); /** * Handlers for actions in this components */ // Delete a single downloaded track const handleDelete = useCallback((id: string) => { dispatch(removeDownloadedTrack(id)); }, [dispatch]); // Delete all downloaded tracks const handleDeleteAllTracks = useCallback(() => ids.forEach(handleDelete), [handleDelete, ids]); // Retry a single failed track const retryTrack = useCallback((id: string) => { dispatch(queueTrackForDownload(id)); }, [dispatch]); // Retry all failed tracks const failedIds = useMemo(() => ids.filter((id) => !entities[id]?.isComplete), [ids, entities]); const handleRetryFailed = useCallback(() => ( failedIds.forEach(retryTrack) ), [failedIds, retryTrack]); /** * Render section */ const ListHeaderComponent = useMemo(() => ( {t('total-download-size')}{': '}{formatBytes(totalDownloadSize)}