fix: download status

This commit is contained in:
Fredrik Burmester
2025-10-03 11:02:58 +02:00
parent d764e5f9d2
commit 4517fe354b
10 changed files with 47 additions and 54 deletions

View File

@@ -23,12 +23,12 @@ export default function page() {
const [seasonIndexState, setSeasonIndexState] = useState<SeasonIndexState>(
{},
);
const { getDownloadedItems, deleteItems } = useDownload();
const { downloadedItems, deleteItems } = useDownload();
const series = useMemo(() => {
try {
return (
getDownloadedItems()
downloadedItems
?.filter((f) => f.item.SeriesId === seriesId)
?.sort(
(a, b) => a?.item.ParentIndexNumber! - b.item.ParentIndexNumber!,
@@ -37,7 +37,7 @@ export default function page() {
} catch {
return [];
}
}, [getDownloadedItems]);
}, [downloadedItems, seriesId]);
// Group episodes by season in a single pass
const seasonGroups = useMemo(() => {

View File

@@ -18,10 +18,7 @@ import ActiveDownloads from "@/components/downloads/ActiveDownloads";
import { DownloadSize } from "@/components/downloads/DownloadSize";
import { MovieCard } from "@/components/downloads/MovieCard";
import { SeriesCard } from "@/components/downloads/SeriesCard";
import {
downloadsRefreshAtom,
useDownload,
} from "@/providers/DownloadProvider";
import { useDownload } from "@/providers/DownloadProvider";
import { type DownloadedItem } from "@/providers/Downloads/types";
import { queueAtom } from "@/utils/atoms/queue";
import { writeToLog } from "@/utils/log";
@@ -30,13 +27,8 @@ export default function page() {
const navigation = useNavigation();
const { t } = useTranslation();
const [queue, setQueue] = useAtom(queueAtom);
const [refreshKey] = useAtom(downloadsRefreshAtom);
const {
removeProcess,
getDownloadedItems,
deleteFileByType,
deleteAllFiles,
} = useDownload();
const { removeProcess, downloadedItems, deleteFileByType, deleteAllFiles } =
useDownload();
const router = useRouter();
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
@@ -66,10 +58,7 @@ export default function page() {
);
};
const downloadedFiles = useMemo(
() => getDownloadedItems(),
[getDownloadedItems, refreshKey],
);
const downloadedFiles = downloadedItems;
const movies = useMemo(() => {
try {

View File

@@ -64,12 +64,8 @@ export const DownloadItems: React.FC<DownloadProps> = ({
const { settings } = useSettings();
const [downloadUnwatchedOnly, setDownloadUnwatchedOnly] = useState(false);
const { processes, startBackgroundDownload, getDownloadedItems } =
useDownload();
const downloadedFiles = useMemo(
() => getDownloadedItems(),
[getDownloadedItems],
);
const { processes, startBackgroundDownload, downloadedItems } = useDownload();
const downloadedFiles = downloadedItems;
const [selectedOptions, setSelectedOptions] = useState<
SelectedOptions | undefined

View File

@@ -119,18 +119,24 @@ export const DownloadCard = ({ process, ...props }: DownloadCardProps) => {
{/* Action buttons in bottom right corner */}
<View className='absolute bottom-2 right-2 flex flex-row items-center space-x-2 z-10'>
{process.status === "downloading" && Platform.OS !== "ios" && (
<TouchableOpacity onPress={() => handlePause()} className='p-1'>
<TouchableOpacity
onPress={() => handlePause()}
className='p-2 bg-neutral-800 rounded-full'
>
<Ionicons name='pause' size={20} color='white' />
</TouchableOpacity>
)}
{process.status === "paused" && Platform.OS !== "ios" && (
<TouchableOpacity onPress={() => handleResume()} className='p-1'>
<TouchableOpacity
onPress={() => handleResume()}
className='p-2 bg-neutral-800 rounded-full'
>
<Ionicons name='play' size={20} color='white' />
</TouchableOpacity>
)}
<TouchableOpacity
onPress={() => handleDelete(process.id)}
className='p-1'
className='p-2 bg-neutral-800 rounded-full'
>
<Ionicons name='close' size={20} color='red' />
</TouchableOpacity>

View File

@@ -13,17 +13,13 @@ export const DownloadSize: React.FC<DownloadSizeProps> = ({
items,
...props
}) => {
const { getDownloadedItemSize, getDownloadedItems } = useDownload();
const downloadedFiles = useMemo(
() => getDownloadedItems(),
[getDownloadedItems],
);
const { getDownloadedItemSize, downloadedItems } = useDownload();
const [size, setSize] = useState<string | undefined>();
const itemIds = useMemo(() => items.map((i) => i.Id), [items]);
useEffect(() => {
if (!downloadedFiles) return;
if (!downloadedItems) return;
let s = 0;
@@ -35,7 +31,7 @@ export const DownloadSize: React.FC<DownloadSizeProps> = ({
}
}
setSize(s.bytesToReadable());
}, [itemIds]);
}, [itemIds, downloadedItems, getDownloadedItemSize]);
const sizeText = useMemo(() => {
if (!size) return "...";

View File

@@ -72,7 +72,7 @@ export const HomeIndex = () => {
const scrollViewRef = useRef<ScrollView>(null);
const { getDownloadedItems, cleanCacheDirectory } = useDownload();
const { downloadedItems, cleanCacheDirectory } = useDownload();
const prevIsConnected = useRef<boolean | null>(false);
const {
isConnected,
@@ -92,8 +92,8 @@ export const HomeIndex = () => {
const hasDownloads = useMemo(() => {
if (Platform.isTV) return false;
return getDownloadedItems().length > 0;
}, [getDownloadedItems]);
return downloadedItems.length > 0;
}, [downloadedItems]);
useEffect(() => {
if (Platform.isTV) {

View File

@@ -28,11 +28,7 @@ export const SeasonEpisodesCarousel: React.FC<Props> = ({
}) => {
const [api] = useAtom(apiAtom);
const [user] = useAtom(userAtom);
const { getDownloadedItems } = useDownload();
const downloadedFiles = useMemo(
() => getDownloadedItems(),
[getDownloadedItems],
);
const { downloadedItems } = useDownload();
const scrollRef = useRef<HorizontalScrollRef>(null);
@@ -45,10 +41,10 @@ export const SeasonEpisodesCarousel: React.FC<Props> = ({
}, [item]);
const { data: episodes, isPending } = useQuery({
queryKey: ["episodes", seasonId, isOffline],
queryKey: ["episodes", seasonId, isOffline, downloadedItems],
queryFn: async () => {
if (isOffline) {
return downloadedFiles
return downloadedItems
?.filter(
(f) => f.item.Type === "Episode" && f.item.SeasonId === seasonId,
)

View File

@@ -55,11 +55,8 @@ export const EpisodeList: React.FC<Props> = ({ item, close, goToItem }) => {
}
}, []);
const { getDownloadedItems } = useDownload();
const downloadedFiles = useMemo(
() => getDownloadedItems(),
[getDownloadedItems],
);
const { downloadedItems } = useDownload();
const downloadedFiles = downloadedItems;
const seasonIndex = seasonIndexState[item.ParentId ?? ""];

View File

@@ -69,7 +69,7 @@ export const usePlaybackManager = ({
const api = useAtomValue(apiAtom);
const user = useAtomValue(userAtom);
const { isConnected } = useNetworkStatus();
const { getDownloadedItemById, updateDownloadedItem, getDownloadedItems } =
const { getDownloadedItemById, updateDownloadedItem, downloadedItems } =
useDownload();
/** Whether the device is online. actually it's connected to the internet. */
@@ -77,14 +77,20 @@ export const usePlaybackManager = ({
// Adjacent episodes logic
const { data: adjacentItems } = useQuery({
queryKey: ["adjacentItems", item?.Id, item?.SeriesId, isOffline],
queryKey: [
"adjacentItems",
item?.Id,
item?.SeriesId,
isOffline,
downloadedItems,
],
queryFn: async (): Promise<BaseItemDto[] | null> => {
if (!item || !item.SeriesId) {
return null;
}
if (isOffline) {
return getOfflineAdjacentItems(item, getDownloadedItems() || []);
return getOfflineAdjacentItems(item, downloadedItems || []);
}
if (!api) {

View File

@@ -25,12 +25,17 @@ const DownloadContext = createContext<ReturnType<
function useDownloadProvider() {
const [api] = useAtom(apiAtom);
const [processes, setProcesses] = useAtom<JobStatus[]>(processesAtom);
const [, setRefreshKey] = useAtom(downloadsRefreshAtom);
const [refreshKey, setRefreshKey] = useAtom(downloadsRefreshAtom);
const successHapticFeedback = useHaptic("success");
// Track task ID to process ID mapping
const taskMapRef = useRef<Map<number, string>>(new Map());
// Reactive downloaded items that updates when refreshKey changes
const downloadedItems = useMemo(() => {
return getAllDownloadedItems();
}, [refreshKey]);
// Trigger refresh of download lists
const triggerRefresh = useCallback(() => {
setRefreshKey((prev) => prev + 1);
@@ -114,7 +119,8 @@ function useDownloadProvider() {
return {
processes,
startBackgroundDownload,
getDownloadedItems: getAllDownloadedItems,
downloadedItems, // Reactive value that auto-updates
getDownloadedItems: getAllDownloadedItems, // Keep for backward compatibility
getDownloadsDatabase,
deleteAllFiles,
deleteFile,
@@ -144,6 +150,7 @@ export function useDownload() {
return {
processes: [],
startBackgroundDownload: async () => {},
downloadedItems: [],
getDownloadedItems: () => [],
getDownloadsDatabase: () => ({ movies: {}, series: {}, other: {} }),
deleteAllFiles: async () => {},