mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-03-11 17:25:32 +00:00
Refactor
This commit is contained in:
parent
0d0f488ef3
commit
1f2b143585
3 changed files with 49 additions and 170 deletions
|
|
@ -247,7 +247,7 @@ class _MangaChapterPageGalleryState
|
|||
|
||||
late int pagePreloadAmount = ref.read(pagePreloadAmountStateProvider);
|
||||
late bool _isBookmarked = _readerController.getChapterBookmarked();
|
||||
|
||||
bool _isLastPageTransition = false;
|
||||
final _currentReaderMode = StateProvider<ReaderMode?>(() => null);
|
||||
PageMode? _pageMode;
|
||||
bool _isView = false;
|
||||
|
|
@ -471,7 +471,7 @@ class _MangaChapterPageGalleryState
|
|||
if (cropBorders) {
|
||||
_processCropBorders();
|
||||
}
|
||||
final usePageTapZones = ref.watch(usePageTapZonesStateProvider);
|
||||
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
return KeyboardListener(
|
||||
autofocus: true,
|
||||
|
|
@ -635,22 +635,24 @@ class _MangaChapterPageGalleryState
|
|||
}
|
||||
},
|
||||
onReachedLastPage: (lastPageIndex) {
|
||||
try {
|
||||
ref
|
||||
.watch(
|
||||
getChapterPagesProvider(
|
||||
chapter: _readerController
|
||||
.getNextChapter(),
|
||||
).future,
|
||||
)
|
||||
.then(
|
||||
(value) => _preloadNextChapter(
|
||||
value,
|
||||
chapter,
|
||||
),
|
||||
);
|
||||
} on RangeError {
|
||||
_addLastPageTransition(chapter);
|
||||
if (!_isLastPageTransition) {
|
||||
try {
|
||||
ref
|
||||
.watch(
|
||||
getChapterPagesProvider(
|
||||
chapter: _readerController
|
||||
.getNextChapter(),
|
||||
).future,
|
||||
)
|
||||
.then(
|
||||
(value) => _preloadNextChapter(
|
||||
value,
|
||||
chapter,
|
||||
),
|
||||
);
|
||||
} on RangeError {
|
||||
_addLastPageTransition(chapter);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
@ -941,8 +943,28 @@ class _MangaChapterPageGalleryState
|
|||
onPageChanged: _onPageChanged,
|
||||
),
|
||||
),
|
||||
_gestureRightLeft(failedToLoadImage, usePageTapZones),
|
||||
_gestureTopBottom(failedToLoadImage, usePageTapZones),
|
||||
Consumer(
|
||||
builder: (context, ref, child) {
|
||||
final usePageTapZones = ref.watch(
|
||||
usePageTapZonesStateProvider,
|
||||
);
|
||||
return _gestureRightLeft(
|
||||
failedToLoadImage,
|
||||
usePageTapZones,
|
||||
);
|
||||
},
|
||||
),
|
||||
Consumer(
|
||||
builder: (context, ref, child) {
|
||||
final usePageTapZones = ref.watch(
|
||||
usePageTapZonesStateProvider,
|
||||
);
|
||||
return _gestureTopBottom(
|
||||
failedToLoadImage,
|
||||
usePageTapZones,
|
||||
);
|
||||
},
|
||||
),
|
||||
_appBar(),
|
||||
_bottomBar(),
|
||||
_showPage(),
|
||||
|
|
@ -1020,7 +1042,8 @@ class _MangaChapterPageGalleryState
|
|||
});
|
||||
}
|
||||
}
|
||||
if (itemPositions.last.index == pagesLength - 1) {
|
||||
if ((itemPositions.last.index == pagesLength - 1) &&
|
||||
!_isLastPageTransition) {
|
||||
try {
|
||||
ref
|
||||
.watch(
|
||||
|
|
@ -1042,6 +1065,7 @@ class _MangaChapterPageGalleryState
|
|||
}
|
||||
|
||||
void _addLastPageTransition(Chapter chap) {
|
||||
if (_isLastPageTransition) return;
|
||||
try {
|
||||
if (!mounted || (_uChapDataPreload.last.isLastChapter ?? false)) return;
|
||||
final currentLength = _uChapDataPreload.length;
|
||||
|
|
@ -1056,6 +1080,7 @@ class _MangaChapterPageGalleryState
|
|||
if (mounted) {
|
||||
setState(() {
|
||||
_uChapDataPreload.add(transitionPage);
|
||||
_isLastPageTransition = true;
|
||||
});
|
||||
}
|
||||
} catch (_) {}
|
||||
|
|
@ -1195,7 +1220,8 @@ class _MangaChapterPageGalleryState
|
|||
.setCurrentIndex(_uChapDataPreload[index].index!);
|
||||
}
|
||||
|
||||
if (_uChapDataPreload[index].pageIndex! == _uChapDataPreload.length - 1) {
|
||||
if ((_uChapDataPreload[index].pageIndex! == _uChapDataPreload.length - 1) &&
|
||||
!_isLastPageTransition) {
|
||||
try {
|
||||
ref
|
||||
.watch(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
|
||||
/// Page loading states for virtual scrolling
|
||||
enum PageLoadState { notLoaded, loading, loaded, error, cached }
|
||||
enum PageLoadState { notLoaded, loaded, error, cached }
|
||||
|
||||
/// Virtual page information for tracking state
|
||||
class VirtualPageInfo {
|
||||
|
|
@ -26,7 +25,6 @@ class VirtualPageInfo {
|
|||
bool get isVisible =>
|
||||
loadState == PageLoadState.loaded || loadState == PageLoadState.cached;
|
||||
bool get needsLoading => loadState == PageLoadState.notLoaded;
|
||||
bool get isLoading => loadState == PageLoadState.loading;
|
||||
bool get hasError => loadState == PageLoadState.error;
|
||||
|
||||
void markAccessed() {
|
||||
|
|
@ -98,9 +96,6 @@ class VirtualPageManager extends ChangeNotifier {
|
|||
/// Get page count
|
||||
int get pageCount => _originalPages.length;
|
||||
|
||||
/// Get current visible index
|
||||
int get currentVisibleIndex => _currentVisibleIndex;
|
||||
|
||||
/// Get page info for a specific index
|
||||
VirtualPageInfo? getPageInfo(int index) {
|
||||
if (index < 0 || index >= _originalPages.length) return null;
|
||||
|
|
@ -130,13 +125,6 @@ class VirtualPageManager extends ChangeNotifier {
|
|||
return distance <= config.preloadDistance;
|
||||
}
|
||||
|
||||
/// Get priority for a page (higher = more important)
|
||||
int getPagePriority(int index) {
|
||||
final distance = (index - _currentVisibleIndex).abs();
|
||||
if (distance == 0) return 1000; // Current page has highest priority
|
||||
return max(0, 100 - distance * 10);
|
||||
}
|
||||
|
||||
/// Schedule preloading for nearby pages
|
||||
void _schedulePreloading() {
|
||||
_preloadQueue.clear();
|
||||
|
|
@ -150,43 +138,6 @@ class VirtualPageManager extends ChangeNotifier {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process preload queue
|
||||
_processPreloadQueue();
|
||||
}
|
||||
|
||||
/// Process the preload queue
|
||||
void _processPreloadQueue() {
|
||||
final sortedQueue = _preloadQueue.toList()
|
||||
..sort((a, b) => getPagePriority(b).compareTo(getPagePriority(a)));
|
||||
|
||||
for (final index in sortedQueue.take(3)) {
|
||||
// Limit concurrent loading
|
||||
_loadPage(index);
|
||||
}
|
||||
}
|
||||
|
||||
/// Load a specific page
|
||||
Future<void> _loadPage(int index) async {
|
||||
final pageInfo = _pageInfoMap[index];
|
||||
if (pageInfo == null || pageInfo.isLoading) return;
|
||||
|
||||
pageInfo.loadState = PageLoadState.loading;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
// For now, we just mark as loaded since the actual image loading
|
||||
// is handled by the ImageView widgets
|
||||
await Future.delayed(const Duration(milliseconds: 10));
|
||||
|
||||
pageInfo.loadState = PageLoadState.loaded;
|
||||
pageInfo.markAccessed();
|
||||
} catch (error) {
|
||||
pageInfo.loadState = PageLoadState.error;
|
||||
pageInfo.error = error;
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Perform memory cleanup
|
||||
|
|
@ -238,11 +189,6 @@ class VirtualPageManager extends ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
/// Force load a page immediately
|
||||
Future<void> forceLoadPage(int index) async {
|
||||
await _loadPage(index);
|
||||
}
|
||||
|
||||
/// Get memory usage statistics
|
||||
Map<String, dynamic> getMemoryStats() {
|
||||
final loadedCount = _pageInfoMap.values
|
||||
|
|
@ -262,24 +208,4 @@ class VirtualPageManager extends ChangeNotifier {
|
|||
'preloadQueueSize': _preloadQueue.length,
|
||||
};
|
||||
}
|
||||
|
||||
/// Preload a range of pages
|
||||
Future<void> preloadRange(int startIndex, int endIndex) async {
|
||||
for (int i = startIndex; i <= endIndex && i < _originalPages.length; i++) {
|
||||
if (i >= 0) {
|
||||
await _loadPage(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear all cached pages
|
||||
void clearCache() {
|
||||
for (final pageInfo in _pageInfoMap.values) {
|
||||
if (pageInfo.loadState != PageLoadState.loading) {
|
||||
pageInfo.loadState = PageLoadState.notLoaded;
|
||||
pageInfo.error = null;
|
||||
}
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/utils/riverpod.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:photo_view/photo_view_gallery.dart';
|
||||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
|
|
@ -10,12 +9,6 @@ import 'package:mangayomi/models/chapter.dart';
|
|||
import 'package:mangayomi/modules/manga/reader/virtual_scrolling/virtual_page_manager.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/virtual_scrolling/virtual_manga_list.dart';
|
||||
|
||||
/// Provides virtual page manager instances
|
||||
final virtualPageManagerProvider =
|
||||
Provider.family<VirtualPageManager, List<UChapDataPreload>>((ref, pages) {
|
||||
return VirtualPageManager(pages: pages);
|
||||
});
|
||||
|
||||
/// Main widget for virtual reading that replaces ScrollablePositionedList
|
||||
class VirtualReaderView extends ConsumerStatefulWidget {
|
||||
final List<UChapDataPreload> pages;
|
||||
|
|
@ -155,69 +148,3 @@ class _VirtualReaderViewState extends ConsumerState<VirtualReaderView> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Mixin to add virtual page manager capabilities to existing widgets
|
||||
mixin VirtualPageManagerMixin<T extends ConsumerStatefulWidget>
|
||||
on ConsumerState<T> {
|
||||
VirtualPageManager? _virtualPageManager;
|
||||
|
||||
VirtualPageManager get virtualPageManager {
|
||||
_virtualPageManager ??= VirtualPageManager(pages: getPages());
|
||||
return _virtualPageManager!;
|
||||
}
|
||||
|
||||
/// Override this method to provide the pages list
|
||||
List<UChapDataPreload> getPages();
|
||||
|
||||
/// Call this when pages change
|
||||
void updateVirtualPages(List<UChapDataPreload> newPages) {
|
||||
_virtualPageManager?.dispose();
|
||||
_virtualPageManager = VirtualPageManager(pages: newPages);
|
||||
}
|
||||
|
||||
/// Call this when the visible page changes
|
||||
void updateVisiblePage(int index) {
|
||||
virtualPageManager.updateVisibleIndex(index);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_virtualPageManager?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration provider for virtual page manager
|
||||
final virtualPageConfigProvider = Provider<VirtualPageConfig>((ref) {
|
||||
// Get user preferences for virtual scrolling configuration
|
||||
final preloadAmount = ref.watch(readerPagePreloadAmountStateProvider);
|
||||
|
||||
return VirtualPageConfig(
|
||||
preloadDistance: preloadAmount,
|
||||
maxCachedPages: preloadAmount * 3,
|
||||
cacheTimeout: const Duration(minutes: 5),
|
||||
enableMemoryOptimization: true,
|
||||
);
|
||||
});
|
||||
|
||||
/// Provider for page preload amount (renamed to avoid conflicts)
|
||||
final readerPagePreloadAmountStateProvider = StateProvider<int>(() => 3);
|
||||
|
||||
/// Extension to convert ReaderMode to virtual scrolling parameters
|
||||
extension ReaderModeExtension on ReaderMode {
|
||||
bool get isContinuous {
|
||||
return this == ReaderMode.verticalContinuous ||
|
||||
this == ReaderMode.webtoon ||
|
||||
this == ReaderMode.horizontalContinuous;
|
||||
}
|
||||
|
||||
Axis get scrollDirection {
|
||||
return this == ReaderMode.horizontalContinuous
|
||||
? Axis.horizontal
|
||||
: Axis.vertical;
|
||||
}
|
||||
|
||||
bool get isHorizontalContinuous {
|
||||
return this == ReaderMode.horizontalContinuous;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue