From 1e469614d9a7fcbc2012a760e68718fd14861975 Mon Sep 17 00:00:00 2001 From: Moustapha Kodjo Amadou <107993382+kodjodevf@users.noreply.github.com> Date: Sun, 14 Dec 2025 13:16:19 +0100 Subject: [PATCH] Chapter jump fix in vertical continuous mode --- .../managers/chapter_preload_manager.dart | 145 ------------------ .../mixins/reader_memory_management.dart | 2 - lib/modules/manga/reader/reader_view.dart | 22 +-- 3 files changed, 7 insertions(+), 162 deletions(-) diff --git a/lib/modules/manga/reader/managers/chapter_preload_manager.dart b/lib/modules/manga/reader/managers/chapter_preload_manager.dart index e4ca1516..9f2a696e 100644 --- a/lib/modules/manga/reader/managers/chapter_preload_manager.dart +++ b/lib/modules/manga/reader/managers/chapter_preload_manager.dart @@ -7,16 +7,6 @@ import 'package:mangayomi/services/get_chapter_pages.dart'; /// Manages the preloading and memory of chapters in the manga reader. class ChapterPreloadManager { - /// Maximum number of chapters to keep in memory - static const int maxChaptersInMemory = 3; - - /// Maximum number of pages to keep in the preload list - static const int maxPagesInMemory = 200; - - /// Buffer size around current index to keep - static const int pageBufferBefore = 30; - static const int pageBufferAfter = 70; - /// The list of preloaded chapter data final List _pages = []; @@ -34,7 +24,6 @@ class ChapterPreloadManager { /// Callbacks void Function()? onPagesUpdated; - void Function(int)? onIndexAdjusted; /// Gets the list of pages (read-only) List get pages => List.unmodifiable(_pages); @@ -161,9 +150,6 @@ class ChapterPreloadManager { _chapterLoadOrder.add(chapterId); } - // Evict old chapters if necessary - await _evictOldChaptersIfNeeded(); - // Notify listeners onPagesUpdated?.call(); @@ -206,136 +192,6 @@ class ChapterPreloadManager { return true; } - /// Evicts old chapters to stay within memory limits. - Future _evictOldChaptersIfNeeded() async { - // Evict by chapter count - while (_loadedChapterIds.length > maxChaptersInMemory && - _chapterLoadOrder.isNotEmpty) { - final oldestChapterId = _chapterLoadOrder.first; - - // Don't evict if current page is in this chapter - final currentPage = _currentIndex < _pages.length - ? _pages[_currentIndex] - : null; - final currentChapterId = currentPage != null - ? _getChapterIdentifier(currentPage.chapter) - : null; - - if (oldestChapterId == currentChapterId) { - // Can't evict current chapter, try next - if (_chapterLoadOrder.length > 1) { - _chapterLoadOrder.removeFirst(); - _chapterLoadOrder.add(oldestChapterId); - continue; - } - break; - } - - await _evictChapter(oldestChapterId); - } - - // Evict by page count if still too many - if (_pages.length > maxPagesInMemory) { - await _trimPagesToBuffer(); - } - } - - /// Evicts a specific chapter from memory. - Future _evictChapter(String chapterId) async { - final pagesToRemove = []; - final keysToRemoveFromCache = []; - - for (var i = 0; i < _pages.length; i++) { - final page = _pages[i]; - if (_getChapterIdentifier(page.chapter) == chapterId) { - pagesToRemove.add(i); - - // Clear the cropImage to free memory - page.cropImage = null; - - // Build cache key for image cache removal - if (page.pageUrl?.url != null) { - keysToRemoveFromCache.add(page.pageUrl!.url); - } - } - } - - // Remove pages from the end to avoid index shifting issues - for (var i = pagesToRemove.length - 1; i >= 0; i--) { - final index = pagesToRemove[i]; - _pages.removeAt(index); - - // Adjust current index if needed - if (_currentIndex > index) { - _currentIndex--; - } - } - - // Remove from tracking - _loadedChapterIds.remove(chapterId); - _chapterLoadOrder.remove(chapterId); - - // Notify about index adjustment - onIndexAdjusted?.call(_currentIndex); - - if (kDebugMode) { - debugPrint( - '[ChapterPreload] Evicted chapter: $chapterId, ' - 'Removed ${pagesToRemove.length} pages', - ); - } - } - - /// Trims pages to keep only those within the buffer range. - Future _trimPagesToBuffer() async { - if (_pages.length <= maxPagesInMemory) return; - - final startKeep = (_currentIndex - pageBufferBefore).clamp( - 0, - _pages.length, - ); - final endKeep = (_currentIndex + pageBufferAfter).clamp(0, _pages.length); - - final pagesToRemoveFromStart = startKeep; - final pagesToRemoveFromEnd = _pages.length - endKeep; - - // Remove from end first - if (pagesToRemoveFromEnd > 0) { - final keysToRemove = []; - for (var i = _pages.length - 1; i >= endKeep; i--) { - final page = _pages[i]; - page.cropImage = null; - if (page.pageUrl?.url != null) { - keysToRemove.add(page.pageUrl!.url); - } - } - _pages.removeRange(endKeep, _pages.length); - } - - // Remove from start - if (pagesToRemoveFromStart > 0) { - final keysToRemove = []; - for (var i = 0; i < pagesToRemoveFromStart; i++) { - final page = _pages[i]; - page.cropImage = null; - if (page.pageUrl?.url != null) { - keysToRemove.add(page.pageUrl!.url); - } - } - _pages.removeRange(0, pagesToRemoveFromStart); - _currentIndex -= pagesToRemoveFromStart; - - onIndexAdjusted?.call(_currentIndex); - } - - if (kDebugMode) { - debugPrint( - '[ChapterPreload] Trimmed pages, ' - 'New count: ${_pages.length}, Index: $_currentIndex', - ); - } - } - /// Gets a unique identifier for a chapter. String? _getChapterIdentifier(Chapter? chapter) { if (chapter == null) return null; @@ -358,7 +214,6 @@ class ChapterPreloadManager { // Clear callbacks onPagesUpdated = null; - onIndexAdjusted = null; if (kDebugMode) { debugPrint('[ChapterPreload] Disposed'); diff --git a/lib/modules/manga/reader/mixins/reader_memory_management.dart b/lib/modules/manga/reader/mixins/reader_memory_management.dart index 4500d38c..81d58aae 100644 --- a/lib/modules/manga/reader/mixins/reader_memory_management.dart +++ b/lib/modules/manga/reader/mixins/reader_memory_management.dart @@ -38,7 +38,6 @@ mixin ReaderMemoryManagement { GetChapterPagesModel chapterData, { int startIndex = 0, VoidCallback? onPagesUpdated, - void Function(int)? onIndexAdjusted, }) { if (_isPreloadManagerInitialized) { if (kDebugMode) { @@ -48,7 +47,6 @@ mixin ReaderMemoryManagement { } _preloadManager.onPagesUpdated = onPagesUpdated; - _preloadManager.onIndexAdjusted = onIndexAdjusted; _preloadManager.initialize(chapterData.uChapDataPreload, startIndex); diff --git a/lib/modules/manga/reader/reader_view.dart b/lib/modules/manga/reader/reader_view.dart index d58ae5bb..11aff970 100644 --- a/lib/modules/manga/reader/reader_view.dart +++ b/lib/modules/manga/reader/reader_view.dart @@ -389,7 +389,7 @@ class _MangaChapterPageGalleryState // Handle failed image loading if (_failedToLoadImage.value != value && context.mounted) { - _failedToLoadImage.value = value; + // _failedToLoadImage.value = value; } }, backgroundColor: backgroundColor, @@ -904,13 +904,6 @@ class _MangaChapterPageGalleryState ? (pages.length / 2).ceil() + 1 : pages.length; if (_currentIndex! >= 0 && _currentIndex! < pagesLength) { - try { - final idx = pages[_currentIndex!].index; - if (idx != null) { - _readerController.setPageIndex(_geCurrentIndex(idx), false); - } - } catch (_) {} - if (_readerController.chapter.id != pages[_currentIndex!].chapter!.id) { if (mounted) { setState(() { @@ -937,6 +930,12 @@ class _MangaChapterPageGalleryState try { _isNextChapterPreloading = true; if (!mounted) return; + try { + final idx = pages[_currentIndex!].index; + if (idx != null) { + _readerController.setPageIndex(_geCurrentIndex(idx), false); + } + } catch (_) {} final value = await ref.read( getChapterPagesProvider( chapter: _readerController.getNextChapter(), @@ -1000,13 +999,6 @@ class _MangaChapterPageGalleryState onPagesUpdated: () { if (mounted) setState(() {}); }, - onIndexAdjusted: (newIndex) { - if (mounted) { - setState(() { - _currentIndex = newIndex; - }); - } - }, ); _readerController.setMangaHistoryUpdate();