From e2a862d30b89907522a2135144c095a50f16250b Mon Sep 17 00:00:00 2001 From: Schnitzel5 Date: Fri, 2 May 2025 02:10:57 +0200 Subject: [PATCH] limited the amount of downloading operations + fixed failed downloads caused by spaces in file path --- .../manga/detail/manga_detail_view.dart | 71 ++++++++++++++----- .../detail/providers/state_providers.g.dart | 2 +- .../download/providers/download_provider.dart | 6 +- .../providers/download_provider.g.dart | 2 +- .../download_queue/download_queue_screen.dart | 16 ++--- lib/providers/storage_provider.dart | 6 +- 6 files changed, 70 insertions(+), 33 deletions(-) diff --git a/lib/modules/manga/detail/manga_detail_view.dart b/lib/modules/manga/detail/manga_detail_view.dart index 10799665..473e426c 100644 --- a/lib/modules/manga/detail/manga_detail_view.dart +++ b/lib/modules/manga/detail/manga_detail_view.dart @@ -160,6 +160,38 @@ class _MangaDetailViewState extends ConsumerState ); } + List _getFilteredAndSortedChapters() { + final filterScanlator = ref.read( + scanlatorsFilterStateProvider(widget.manga!), + ); + final filterUnread = ref.read( + chapterFilterUnreadStateProvider(mangaId: widget.manga!.id!), + ); + final filterBookmarked = ref.read( + chapterFilterBookmarkedStateProvider(mangaId: widget.manga!.id!), + ); + final filterDownloaded = ref.read( + chapterFilterDownloadedStateProvider(mangaId: widget.manga!.id!), + ); + final sortChapter = + ref.read(sortChapterStateProvider(mangaId: widget.manga!.id!)).index + as int; + final chapters = + isar.chapters + .filter() + .idIsNotNull() + .mangaIdEqualTo(widget.manga!.id!) + .findAllSync(); + return _filterAndSortChapter( + data: chapters, + filterUnread: filterUnread, + filterBookmarked: filterBookmarked, + filterDownloaded: filterDownloaded, + sortChapter: sortChapter, + filterScanlator: filterScanlator.$2, + ); + } + List _filterAndSortChapter({ required List data, required int filterUnread, @@ -454,12 +486,7 @@ class _MangaDetailViewState extends ConsumerState ]; }, onSelected: (value) { - final chapters = - isar.chapters - .filter() - .idIsNotNull() - .mangaIdEqualTo(widget.manga!.id!) - .findAllSync(); + final chapters = _getFilteredAndSortedChapters(); if (value == 0 || value == 1 || value == 2 || @@ -482,6 +509,7 @@ class _MangaDetailViewState extends ConsumerState chapter: chapter, ), ); + ref.watch(processDownloadsProvider()); } } else { final length = switch (value) { @@ -512,15 +540,22 @@ class _MangaDetailViewState extends ConsumerState } } } + ref.watch(processDownloadsProvider()); } } else if (value == 4) { - final unreadChapters = - isar.chapters - .filter() - .idIsNotNull() - .mangaIdEqualTo(widget.manga!.id!) - .isReadEqualTo(false) - .findAllSync(); + final List unreadChapters = + _getFilteredAndSortedChapters() + .where( + (element) => + !(element.isRead ?? false), + ) + .toList(); + isar.chapters + .filter() + .idIsNotNull() + .mangaIdEqualTo(widget.manga!.id!) + .isReadEqualTo(false) + .findAllSync(); for (var chapter in unreadChapters) { final entry = isar.downloads @@ -535,13 +570,10 @@ class _MangaDetailViewState extends ConsumerState ); } } + ref.watch(processDownloadsProvider()); } else if (value == 5) { - final allChapters = - isar.chapters - .filter() - .idIsNotNull() - .mangaIdEqualTo(widget.manga!.id!) - .findAllSync(); + final List allChapters = + _getFilteredAndSortedChapters(); for (var chapter in allChapters) { final entry = isar.downloads @@ -556,6 +588,7 @@ class _MangaDetailViewState extends ConsumerState ); } } + ref.watch(processDownloadsProvider()); } }, ), diff --git a/lib/modules/manga/detail/providers/state_providers.g.dart b/lib/modules/manga/detail/providers/state_providers.g.dart index b831d018..6dd8d95a 100644 --- a/lib/modules/manga/detail/providers/state_providers.g.dart +++ b/lib/modules/manga/detail/providers/state_providers.g.dart @@ -1110,7 +1110,7 @@ class _ChapterSetIsReadStateProviderElement } String _$chapterSetDownloadStateHash() => - r'321f00669a4644016076dcf5e007355d696d26e3'; + r'2f35d274b76e28376b0089b2f6ee6d9d7ebcbeec'; abstract class _$ChapterSetDownloadState extends BuildlessAutoDisposeNotifier { diff --git a/lib/modules/manga/download/providers/download_provider.dart b/lib/modules/manga/download/providers/download_provider.dart index ab73c3b9..7a69b9de 100644 --- a/lib/modules/manga/download/providers/download_provider.dart +++ b/lib/modules/manga/download/providers/download_provider.dart @@ -21,6 +21,7 @@ import 'package:mangayomi/services/get_chapter_pages.dart'; import 'package:mangayomi/services/http/m_client.dart'; import 'package:mangayomi/services/download_manager/m3u8/m3u8_downloader.dart'; import 'package:mangayomi/services/download_manager/m3u8/models/download.dart'; +import 'package:mangayomi/utils/extensions/chapter.dart'; import 'package:mangayomi/utils/extensions/string_extensions.dart'; import 'package:mangayomi/utils/headers.dart'; import 'package:mangayomi/utils/reg_exp_matcher.dart'; @@ -383,9 +384,12 @@ Future processDownloads(Ref ref, {bool? useWifi}) async { } if (current < maxConcurrentDownloads) { current++; + final downloadItem = ongoingDownloads[index++]; + final chapter = downloadItem.chapter.value!; + chapter.cancelDownloads(downloadItem.id); ref.read( downloadChapterProvider( - chapter: ongoingDownloads[index++].chapter.value!, + chapter: chapter, useWifi: useWifi, callback: () { downloaded++; diff --git a/lib/modules/manga/download/providers/download_provider.g.dart b/lib/modules/manga/download/providers/download_provider.g.dart index 5678edb8..3df105f2 100644 --- a/lib/modules/manga/download/providers/download_provider.g.dart +++ b/lib/modules/manga/download/providers/download_provider.g.dart @@ -321,7 +321,7 @@ class _DownloadChapterProviderElement void Function()? get callback => (origin as DownloadChapterProvider).callback; } -String _$processDownloadsHash() => r'6204b2ae0394c2b422ab3b5cd2eaaaa822a59ee1'; +String _$processDownloadsHash() => r'ef5107f9674f2175a7aa18b8e4fc4555f3b6b584'; /// See also [processDownloads]. @ProviderFor(processDownloads) diff --git a/lib/modules/more/download_queue/download_queue_screen.dart b/lib/modules/more/download_queue/download_queue_screen.dart index e08f2b0c..e634c2d3 100644 --- a/lib/modules/more/download_queue/download_queue_screen.dart +++ b/lib/modules/more/download_queue/download_queue_screen.dart @@ -18,16 +18,16 @@ class DownloadQueueScreen extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final l10n = l10nLocalizations(context); return StreamBuilder( - stream: isar.downloads.filter().idIsNotNull().watch( - fireImmediately: true, - ), + stream: isar.downloads + .filter() + .idIsNotNull() + .isDownloadEqualTo(false) + .isStartDownloadEqualTo(true) + .sortBySucceededDesc() + .watch(fireImmediately: true), builder: (context, snapshot) { if (snapshot.hasData && snapshot.data!.isNotEmpty) { - final entries = - snapshot.data! - .where((element) => element.isDownload == false) - .where((element) => element.isStartDownload == true) - .toList(); + final entries = snapshot.data!; final allQueueLength = entries.toList().length; return Scaffold( appBar: AppBar( diff --git a/lib/providers/storage_provider.dart b/lib/providers/storage_provider.dart index 4e0de9ce..5acce48d 100644 --- a/lib/providers/storage_provider.dart +++ b/lib/providers/storage_provider.dart @@ -98,7 +98,7 @@ class StorageProvider { 'downloads', itemTypePath, '${manga.source} (${manga.lang!.toUpperCase()})', - manga.name!.replaceForbiddenCharacters('_'), + manga.name!.replaceForbiddenCharacters('_').trim(), ), ); } @@ -107,12 +107,12 @@ class StorageProvider { final basedir = await getMangaMainDirectory(chapter); String scanlator = chapter.scanlator?.isNotEmpty ?? false - ? "${chapter.scanlator!.replaceForbiddenCharacters('_')}_" + ? chapter.scanlator!.replaceForbiddenCharacters('_').trim() : ""; return Directory( path.join( basedir!.path, - scanlator + chapter.name!.replaceForbiddenCharacters('_'), + scanlator + chapter.name!.replaceForbiddenCharacters('_').trim(), ), ); }