mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 21:48:14 -08:00
120 lines
4.4 KiB
Dart
120 lines
4.4 KiB
Dart
import 'dart:io';
|
|
import 'dart:math' as math;
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:extended_image/extended_image.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import 'package:fladder/providers/settings/book_viewer_settings_provider.dart';
|
|
import 'package:fladder/screens/book_viewer/book_viewer_controls.dart';
|
|
|
|
class BookViewerReader extends ConsumerWidget {
|
|
final int index;
|
|
final List<String> pages;
|
|
final BookViewerSettingsModel bookViewSettings;
|
|
final Function() previousPage;
|
|
final Function() nextPage;
|
|
final BookViewController viewController;
|
|
final double lastScale;
|
|
final Function(double value) newScale;
|
|
const BookViewerReader({
|
|
required this.index,
|
|
required this.pages,
|
|
required this.bookViewSettings,
|
|
required this.previousPage,
|
|
required this.nextPage,
|
|
required this.viewController,
|
|
required this.lastScale,
|
|
required this.newScale,
|
|
super.key,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
double? initScale({
|
|
required Size imageSize,
|
|
required Size size,
|
|
double? initialScale,
|
|
}) {
|
|
final double n1 = imageSize.height / imageSize.width;
|
|
final double n2 = size.height / size.width;
|
|
if (n1 > n2) {
|
|
final FittedSizes fittedSizes = applyBoxFit(BoxFit.cover, imageSize, size);
|
|
//final Size sourceSize = fittedSizes.source;
|
|
final Size destinationSize = fittedSizes.destination;
|
|
return size.width / destinationSize.width;
|
|
} else if (n1 / n2 < 1 / 4) {
|
|
final FittedSizes fittedSizes = applyBoxFit(BoxFit.cover, imageSize, size);
|
|
//final Size sourceSize = fittedSizes.source;
|
|
final Size destinationSize = fittedSizes.destination;
|
|
return size.height / destinationSize.height;
|
|
}
|
|
|
|
return initialScale;
|
|
}
|
|
|
|
return GestureDetector(
|
|
behavior: HitTestBehavior.translucent,
|
|
onTapUp: (tapDetails) {
|
|
double screenWidth = MediaQuery.of(context).size.width;
|
|
double tapPosition = tapDetails.globalPosition.dx;
|
|
double tapPercentage = tapPosition / screenWidth;
|
|
if (tapPercentage < 0.22) {
|
|
bookViewSettings.readDirection == ReadDirection.leftToRight ? previousPage() : nextPage();
|
|
} else if (tapPercentage < 0.88) {
|
|
viewController.toggleControls();
|
|
} else {
|
|
bookViewSettings.readDirection == ReadDirection.leftToRight ? nextPage() : previousPage();
|
|
}
|
|
},
|
|
child: ExtendedImage.file(
|
|
fit: BoxFit.contain,
|
|
imageCacheName: pages[index - 1],
|
|
mode: ExtendedImageMode.gesture,
|
|
initGestureConfigHandler: (state) {
|
|
double? initialScale = !bookViewSettings.keepPageZoom
|
|
? switch (bookViewSettings.initZoomState) {
|
|
InitZoomState.contained => 1.0,
|
|
InitZoomState.covered => 1.75,
|
|
}
|
|
: lastScale;
|
|
|
|
if (state.extendedImageInfo != null) {
|
|
initialScale = initScale(
|
|
size: MediaQuery.sizeOf(context),
|
|
initialScale: initialScale,
|
|
imageSize: Size(
|
|
state.extendedImageInfo!.image.width.toDouble(), state.extendedImageInfo!.image.height.toDouble()));
|
|
}
|
|
|
|
return GestureConfig(
|
|
inertialSpeed: 300,
|
|
inPageView: true,
|
|
initialScale: initialScale!,
|
|
initialAlignment: bookViewSettings.initZoomState == InitZoomState.contained && initialScale == 1.0
|
|
? InitialAlignment.center
|
|
: switch (bookViewSettings.readDirection) {
|
|
ReadDirection.rightToLeft => InitialAlignment.topRight,
|
|
ReadDirection.leftToRight => InitialAlignment.topLeft,
|
|
},
|
|
reverseMousePointerScrollDirection: true,
|
|
maxScale: math.max(initialScale, 5.0),
|
|
minScale: math.min(initialScale, 1),
|
|
animationMaxScale: math.max(initialScale, 5.0),
|
|
gestureDetailsIsChanged: (details) {
|
|
if (bookViewSettings.keepPageZoom) {
|
|
if (lastScale != (details?.totalScale ?? initialScale)) {
|
|
newScale(details?.totalScale ?? 1.0);
|
|
}
|
|
}
|
|
},
|
|
cacheGesture: bookViewSettings.cachePageZoom,
|
|
hitTestBehavior: HitTestBehavior.translucent,
|
|
);
|
|
},
|
|
File(pages[index - 1]),
|
|
),
|
|
);
|
|
}
|
|
}
|