mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-04-20 23:22:07 +00:00
separated some classes from reader_view
This commit is contained in:
parent
25f7402f35
commit
5b56578029
17 changed files with 223 additions and 316 deletions
|
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/image_view_paged.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/circular_progress_indicator_animate_rotate.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/transition_view_paged.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/reader_screen.dart';
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'package:extended_image/extended_image.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/image_view_paged.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/circular_progress_indicator_animate_rotate.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/transition_view_vertical.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/reader_screen.dart';
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'package:extended_image/extended_image.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/color_filter_widget.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/providers/reader_state_provider.dart';
|
||||
import 'package:mangayomi/utils/extensions/others.dart';
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'package:extended_image/extended_image.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/color_filter_widget.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/providers/reader_state_provider.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/src/rust/api/image.dart';
|
||||
import 'package:mangayomi/src/rust/frb_generated.dart';
|
||||
import 'package:mangayomi/utils/extensions/others.dart';
|
||||
|
|
|
|||
|
|
@ -12,14 +12,16 @@ import 'package:mangayomi/eval/model/m_bridge.dart';
|
|||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/page.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/modules/anime/widgets/desktop.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/crop_borders_provider.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/btn_chapter_list_dialog.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/double_columm_view_center.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/color_filter_provider.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/color_filter_widget.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/custom_popup_menu_button.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/custom_value_indicator_shape.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/providers/reader_state_provider.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
|
|
@ -1633,7 +1635,7 @@ class _MangaChapterPageGalleryState
|
|||
return SliderTheme(
|
||||
data: SliderTheme.of(context).copyWith(
|
||||
valueIndicatorShape:
|
||||
_CustomValueIndicatorShape(
|
||||
CustomValueIndicatorShape(
|
||||
tranform: _isReverseHorizontal,
|
||||
),
|
||||
overlayShape:
|
||||
|
|
@ -2504,190 +2506,3 @@ class _MangaChapterPageGalleryState
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UChapDataPreload {
|
||||
Chapter? chapter;
|
||||
Directory? directory;
|
||||
PageUrl? pageUrl;
|
||||
bool? isLocale;
|
||||
Uint8List? archiveImage;
|
||||
int? index;
|
||||
GetChapterPagesModel? chapterUrlModel;
|
||||
int? pageIndex;
|
||||
Uint8List? cropImage;
|
||||
bool isTransitionPage;
|
||||
Chapter? nextChapter;
|
||||
String? mangaName;
|
||||
bool? isLastChapter;
|
||||
|
||||
UChapDataPreload(
|
||||
this.chapter,
|
||||
this.directory,
|
||||
this.pageUrl,
|
||||
this.isLocale,
|
||||
this.archiveImage,
|
||||
this.index,
|
||||
this.chapterUrlModel,
|
||||
this.pageIndex, {
|
||||
this.cropImage,
|
||||
this.isTransitionPage = false,
|
||||
this.nextChapter,
|
||||
this.mangaName,
|
||||
this.isLastChapter = false,
|
||||
});
|
||||
|
||||
UChapDataPreload.transition({
|
||||
required Chapter currentChapter,
|
||||
required this.nextChapter,
|
||||
required String this.mangaName,
|
||||
required int this.pageIndex,
|
||||
this.isLastChapter = false,
|
||||
}) : chapter = currentChapter,
|
||||
isTransitionPage = true,
|
||||
directory = null,
|
||||
pageUrl = null,
|
||||
isLocale = null,
|
||||
archiveImage = null,
|
||||
index = null,
|
||||
chapterUrlModel = null,
|
||||
cropImage = null;
|
||||
}
|
||||
|
||||
class CustomPopupMenuButton<T> extends StatelessWidget {
|
||||
final String label;
|
||||
final String title;
|
||||
final ValueChanged<T> onSelected;
|
||||
final T value;
|
||||
final List<T> list;
|
||||
final String Function(T) itemText;
|
||||
const CustomPopupMenuButton({
|
||||
super.key,
|
||||
required this.label,
|
||||
required this.title,
|
||||
required this.onSelected,
|
||||
required this.value,
|
||||
required this.list,
|
||||
required this.itemText,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: PopupMenuButton(
|
||||
popUpAnimationStyle: popupAnimationStyle,
|
||||
tooltip: "",
|
||||
offset: Offset.fromDirection(1),
|
||||
color: Colors.black,
|
||||
onSelected: onSelected,
|
||||
itemBuilder: (context) => [
|
||||
for (var d in list)
|
||||
PopupMenuItem(
|
||||
value: d,
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: d == value ? Colors.white : Colors.transparent,
|
||||
),
|
||||
const SizedBox(width: 7),
|
||||
Text(
|
||||
itemText(d),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).textTheme.bodyLarge!.color!.withValues(alpha: 0.9),
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(title),
|
||||
const SizedBox(width: 20),
|
||||
const Icon(Icons.keyboard_arrow_down_outlined),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomValueIndicatorShape extends SliderComponentShape {
|
||||
final _indicatorShape = const PaddleSliderValueIndicatorShape();
|
||||
final bool tranform;
|
||||
const _CustomValueIndicatorShape({this.tranform = false});
|
||||
@override
|
||||
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
|
||||
return const Size(40, 40);
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(
|
||||
PaintingContext context,
|
||||
Offset center, {
|
||||
required Animation<double> activationAnimation,
|
||||
required Animation<double> enableAnimation,
|
||||
required bool isDiscrete,
|
||||
required TextPainter labelPainter,
|
||||
required RenderBox parentBox,
|
||||
required SliderThemeData sliderTheme,
|
||||
required TextDirection textDirection,
|
||||
required double value,
|
||||
required double textScaleFactor,
|
||||
required Size sizeWithOverflow,
|
||||
}) {
|
||||
final textSpan = TextSpan(
|
||||
text: labelPainter.text?.toPlainText(),
|
||||
style: sliderTheme.valueIndicatorTextStyle,
|
||||
);
|
||||
|
||||
final textPainter = TextPainter(
|
||||
text: textSpan,
|
||||
textAlign: labelPainter.textAlign,
|
||||
textDirection: textDirection,
|
||||
);
|
||||
|
||||
textPainter.layout();
|
||||
|
||||
context.canvas.save();
|
||||
context.canvas.translate(center.dx, center.dy);
|
||||
context.canvas.scale(tranform ? -1.0 : 1.0, 1.0);
|
||||
context.canvas.translate(-center.dx, -center.dy);
|
||||
|
||||
_indicatorShape.paint(
|
||||
context,
|
||||
center,
|
||||
activationAnimation: activationAnimation,
|
||||
enableAnimation: enableAnimation,
|
||||
labelPainter: textPainter,
|
||||
parentBox: parentBox,
|
||||
sliderTheme: sliderTheme,
|
||||
value: value,
|
||||
textScaleFactor: textScaleFactor,
|
||||
sizeWithOverflow: sizeWithOverflow,
|
||||
isDiscrete: isDiscrete,
|
||||
textDirection: textDirection,
|
||||
);
|
||||
|
||||
context.canvas.restore();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
54
lib/modules/manga/reader/u_chap_data_preload.dart
Normal file
54
lib/modules/manga/reader/u_chap_data_preload.dart
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/page.dart';
|
||||
import 'package:mangayomi/services/get_chapter_pages.dart';
|
||||
|
||||
class UChapDataPreload {
|
||||
Chapter? chapter;
|
||||
Directory? directory;
|
||||
PageUrl? pageUrl;
|
||||
bool? isLocale;
|
||||
Uint8List? archiveImage;
|
||||
int? index;
|
||||
GetChapterPagesModel? chapterUrlModel;
|
||||
int? pageIndex;
|
||||
Uint8List? cropImage;
|
||||
bool isTransitionPage;
|
||||
Chapter? nextChapter;
|
||||
String? mangaName;
|
||||
bool? isLastChapter;
|
||||
|
||||
UChapDataPreload(
|
||||
this.chapter,
|
||||
this.directory,
|
||||
this.pageUrl,
|
||||
this.isLocale,
|
||||
this.archiveImage,
|
||||
this.index,
|
||||
this.chapterUrlModel,
|
||||
this.pageIndex, {
|
||||
this.cropImage,
|
||||
this.isTransitionPage = false,
|
||||
this.nextChapter,
|
||||
this.mangaName,
|
||||
this.isLastChapter = false,
|
||||
});
|
||||
|
||||
UChapDataPreload.transition({
|
||||
required Chapter currentChapter,
|
||||
required this.nextChapter,
|
||||
required String this.mangaName,
|
||||
required int this.pageIndex,
|
||||
this.isLastChapter = false,
|
||||
}) : chapter = currentChapter,
|
||||
isTransitionPage = true,
|
||||
directory = null,
|
||||
pageUrl = null,
|
||||
isLocale = null,
|
||||
archiveImage = null,
|
||||
index = null,
|
||||
chapterUrlModel = null,
|
||||
cropImage = null;
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
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:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/virtual_scrolling/virtual_page_manager.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart' as reader;
|
||||
import 'package:mangayomi/modules/manga/reader/image_view_vertical.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/double_columm_view_vertical.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/transition_view_vertical.dart';
|
||||
|
|
@ -21,7 +21,7 @@ class VirtualMangaList extends ConsumerStatefulWidget {
|
|||
final double minCacheExtent;
|
||||
final int initialScrollIndex;
|
||||
final ScrollPhysics physics;
|
||||
final Function(reader.UChapDataPreload data) onLongPressData;
|
||||
final Function(UChapDataPreload data) onLongPressData;
|
||||
final Function(bool) onFailedToLoadImage;
|
||||
final BackgroundColor backgroundColor;
|
||||
final bool isDoublePageMode;
|
||||
|
|
@ -215,7 +215,7 @@ class _VirtualMangaListState extends ConsumerState<VirtualMangaList> {
|
|||
final int index1 = index * 2 - 1;
|
||||
final int index2 = index1 + 1;
|
||||
|
||||
final List<reader.UChapDataPreload?> datas = index == 0
|
||||
final List<UChapDataPreload?> datas = index == 0
|
||||
? [widget.pageManager.getOriginalPage(0), null]
|
||||
: [
|
||||
index1 < widget.pageManager.pageCount
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'dart:async';
|
|||
import 'dart:math';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart' as reader;
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
|
||||
/// Page loading states for virtual scrolling
|
||||
enum PageLoadState { notLoaded, loading, loaded, error, cached }
|
||||
|
|
@ -10,7 +10,7 @@ enum PageLoadState { notLoaded, loading, loaded, error, cached }
|
|||
/// Virtual page information for tracking state
|
||||
class VirtualPageInfo {
|
||||
final int index;
|
||||
final reader.UChapDataPreload originalData;
|
||||
final UChapDataPreload originalData;
|
||||
PageLoadState loadState;
|
||||
DateTime? lastAccessTime;
|
||||
Object? error;
|
||||
|
|
@ -56,7 +56,7 @@ class VirtualPageConfig {
|
|||
|
||||
/// Manages virtual page loading and memory optimization
|
||||
class VirtualPageManager extends ChangeNotifier {
|
||||
final List<reader.UChapDataPreload> _originalPages;
|
||||
final List<UChapDataPreload> _originalPages;
|
||||
final VirtualPageConfig config;
|
||||
final Map<int, VirtualPageInfo> _pageInfoMap = {};
|
||||
final Set<int> _preloadQueue = {};
|
||||
|
|
@ -65,7 +65,7 @@ class VirtualPageManager extends ChangeNotifier {
|
|||
Timer? _cleanupTimer;
|
||||
|
||||
VirtualPageManager({
|
||||
required List<reader.UChapDataPreload> pages,
|
||||
required List<UChapDataPreload> pages,
|
||||
this.config = const VirtualPageConfig(),
|
||||
}) : _originalPages = List.from(pages) {
|
||||
_initializePages();
|
||||
|
|
@ -108,7 +108,7 @@ class VirtualPageManager extends ChangeNotifier {
|
|||
}
|
||||
|
||||
/// Get original page data
|
||||
reader.UChapDataPreload? getOriginalPage(int index) {
|
||||
UChapDataPreload? getOriginalPage(int index) {
|
||||
if (index < 0 || index >= _originalPages.length) return null;
|
||||
return _originalPages[index];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +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:photo_view/photo_view.dart';
|
||||
import 'package:photo_view/photo_view_gallery.dart';
|
||||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
|
|
@ -7,11 +8,10 @@ import 'package:mangayomi/models/settings.dart';
|
|||
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';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart' as reader;
|
||||
|
||||
/// Provides virtual page manager instances
|
||||
final virtualPageManagerProvider =
|
||||
Provider.family<VirtualPageManager, List<reader.UChapDataPreload>>((
|
||||
Provider.family<VirtualPageManager, List<UChapDataPreload>>((
|
||||
ref,
|
||||
pages,
|
||||
) {
|
||||
|
|
@ -20,7 +20,7 @@ final virtualPageManagerProvider =
|
|||
|
||||
/// Main widget for virtual reading that replaces ScrollablePositionedList
|
||||
class VirtualReaderView extends ConsumerStatefulWidget {
|
||||
final List<reader.UChapDataPreload> pages;
|
||||
final List<UChapDataPreload> pages;
|
||||
final ItemScrollController itemScrollController;
|
||||
final ScrollOffsetController scrollOffsetController;
|
||||
final ItemPositionsListener itemPositionsListener;
|
||||
|
|
@ -28,7 +28,7 @@ class VirtualReaderView extends ConsumerStatefulWidget {
|
|||
final double minCacheExtent;
|
||||
final int initialScrollIndex;
|
||||
final ScrollPhysics physics;
|
||||
final Function(reader.UChapDataPreload data) onLongPressData;
|
||||
final Function(UChapDataPreload data) onLongPressData;
|
||||
final Function(bool) onFailedToLoadImage;
|
||||
final BackgroundColor backgroundColor;
|
||||
final bool isDoublePageMode;
|
||||
|
|
@ -169,10 +169,10 @@ mixin VirtualPageManagerMixin<T extends ConsumerStatefulWidget>
|
|||
}
|
||||
|
||||
/// Override this method to provide the pages list
|
||||
List<reader.UChapDataPreload> getPages();
|
||||
List<UChapDataPreload> getPages();
|
||||
|
||||
/// Call this when pages change
|
||||
void updateVirtualPages(List<reader.UChapDataPreload> newPages) {
|
||||
void updateVirtualPages(List<UChapDataPreload> newPages) {
|
||||
_virtualPageManager?.dispose();
|
||||
_virtualPageManager = VirtualPageManager(pages: newPages);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/utils/global_style.dart';
|
||||
|
||||
class CustomPopupMenuButton<T> extends StatelessWidget {
|
||||
final String label;
|
||||
final String title;
|
||||
final ValueChanged<T> onSelected;
|
||||
final T value;
|
||||
final List<T> list;
|
||||
final String Function(T) itemText;
|
||||
const CustomPopupMenuButton({
|
||||
super.key,
|
||||
required this.label,
|
||||
required this.title,
|
||||
required this.onSelected,
|
||||
required this.value,
|
||||
required this.list,
|
||||
required this.itemText,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: PopupMenuButton(
|
||||
popUpAnimationStyle: popupAnimationStyle,
|
||||
tooltip: "",
|
||||
offset: Offset.fromDirection(1),
|
||||
color: Colors.black,
|
||||
onSelected: onSelected,
|
||||
itemBuilder: (context) => [
|
||||
for (var d in list)
|
||||
PopupMenuItem(
|
||||
value: d,
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: d == value ? Colors.white : Colors.transparent,
|
||||
),
|
||||
const SizedBox(width: 7),
|
||||
Text(
|
||||
itemText(d),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).textTheme.bodyLarge!.color!.withValues(alpha: 0.9),
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(title),
|
||||
const SizedBox(width: 20),
|
||||
const Icon(Icons.keyboard_arrow_down_outlined),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomValueIndicatorShape extends SliderComponentShape {
|
||||
final _indicatorShape = const PaddleSliderValueIndicatorShape();
|
||||
final bool tranform;
|
||||
const CustomValueIndicatorShape({this.tranform = false});
|
||||
@override
|
||||
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
|
||||
return const Size(40, 40);
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(
|
||||
PaintingContext context,
|
||||
Offset center, {
|
||||
required Animation<double> activationAnimation,
|
||||
required Animation<double> enableAnimation,
|
||||
required bool isDiscrete,
|
||||
required TextPainter labelPainter,
|
||||
required RenderBox parentBox,
|
||||
required SliderThemeData sliderTheme,
|
||||
required TextDirection textDirection,
|
||||
required double value,
|
||||
required double textScaleFactor,
|
||||
required Size sizeWithOverflow,
|
||||
}) {
|
||||
final textSpan = TextSpan(
|
||||
text: labelPainter.text?.toPlainText(),
|
||||
style: sliderTheme.valueIndicatorTextStyle,
|
||||
);
|
||||
|
||||
final textPainter = TextPainter(
|
||||
text: textSpan,
|
||||
textAlign: labelPainter.textAlign,
|
||||
textDirection: textDirection,
|
||||
);
|
||||
|
||||
textPainter.layout();
|
||||
|
||||
context.canvas.save();
|
||||
context.canvas.translate(center.dx, center.dy);
|
||||
context.canvas.scale(tranform ? -1.0 : 1.0, 1.0);
|
||||
context.canvas.translate(-center.dx, -center.dy);
|
||||
|
||||
_indicatorShape.paint(
|
||||
context,
|
||||
center,
|
||||
activationAnimation: activationAnimation,
|
||||
enableAnimation: enableAnimation,
|
||||
labelPainter: textPainter,
|
||||
parentBox: parentBox,
|
||||
sliderTheme: sliderTheme,
|
||||
value: value,
|
||||
textScaleFactor: textScaleFactor,
|
||||
sizeWithOverflow: sizeWithOverflow,
|
||||
isDiscrete: isDiscrete,
|
||||
textDirection: textDirection,
|
||||
);
|
||||
|
||||
context.canvas.restore();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/chapter_transition_page.dart';
|
||||
|
||||
class TransitionViewPaged extends ConsumerWidget {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/chapter_transition_page.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/page.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/modules/anime/widgets/desktop.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/btn_chapter_list_dialog.dart';
|
||||
|
|
@ -22,9 +21,7 @@ import 'package:mangayomi/services/get_html_content.dart';
|
|||
import 'package:mangayomi/utils/extensions/dom_extensions.dart';
|
||||
import 'package:mangayomi/utils/utils.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
||||
import 'package:mangayomi/services/get_chapter_pages.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/utils/global_style.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
|
||||
|
|
@ -759,104 +756,3 @@ class _NovelWebViewState extends ConsumerState<NovelWebView>
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class UChapDataPreload {
|
||||
Chapter? chapter;
|
||||
Directory? directory;
|
||||
PageUrl? pageUrl;
|
||||
bool? isLocale;
|
||||
Uint8List? archiveImage;
|
||||
int? index;
|
||||
GetChapterPagesModel? chapterUrlModel;
|
||||
int? pageIndex;
|
||||
Uint8List? cropImage;
|
||||
UChapDataPreload(
|
||||
this.chapter,
|
||||
this.directory,
|
||||
this.pageUrl,
|
||||
this.isLocale,
|
||||
this.archiveImage,
|
||||
this.index,
|
||||
this.chapterUrlModel,
|
||||
this.pageIndex, {
|
||||
this.cropImage,
|
||||
});
|
||||
}
|
||||
|
||||
class CustomPopupMenuButton<T> extends StatelessWidget {
|
||||
final String label;
|
||||
final String title;
|
||||
final ValueChanged<T> onSelected;
|
||||
final T value;
|
||||
final List<T> list;
|
||||
final String Function(T) itemText;
|
||||
const CustomPopupMenuButton({
|
||||
super.key,
|
||||
required this.label,
|
||||
required this.title,
|
||||
required this.onSelected,
|
||||
required this.value,
|
||||
required this.list,
|
||||
required this.itemText,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: PopupMenuButton(
|
||||
popUpAnimationStyle: popupAnimationStyle,
|
||||
tooltip: "",
|
||||
offset: Offset.fromDirection(1),
|
||||
color: Colors.black,
|
||||
onSelected: onSelected,
|
||||
itemBuilder: (context) => [
|
||||
for (var d in list)
|
||||
PopupMenuItem(
|
||||
value: d,
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check,
|
||||
color: d == value ? Colors.white : Colors.transparent,
|
||||
),
|
||||
const SizedBox(width: 7),
|
||||
Text(
|
||||
itemText(d),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).textTheme.bodyLarge!.color!.withValues(alpha: 0.9),
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(title),
|
||||
const SizedBox(width: 20),
|
||||
const Icon(Icons.keyboard_arrow_down_outlined),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/eval/javascript/http.dart';
|
||||
|
|
@ -9,7 +10,6 @@ import 'package:mangayomi/models/chapter.dart';
|
|||
import 'package:mangayomi/models/page.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/modules/manga/archive_reader/providers/archive_reader_providers.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
import 'package:mangayomi/utils/utils.dart';
|
||||
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import 'dart:ui';
|
|||
import 'package:extended_image/extended_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/providers/reader_state_provider.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
|
|
|
|||
Loading…
Reference in a new issue