minor fixes

This commit is contained in:
Thibault Deckers 2022-11-21 20:15:32 +01:00
parent fdd9e00939
commit 093b967e26
7 changed files with 125 additions and 77 deletions

View file

@ -96,7 +96,7 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any
val granted = PermissionManager.requestMediaFileAccess(activity, uris, mimeTypes) val granted = PermissionManager.requestMediaFileAccess(activity, uris, mimeTypes)
success(granted) success(granted)
} catch (e: Exception) { } catch (e: Exception) {
error("requestMediaFileAccess-request", "failed to request access to uris=$uris", e.message) error("requestMediaFileAccess-request", "failed to request access to ${uris.size} uris=$uris", e.message)
} }
endOfStream() endOfStream()
} }

View file

@ -52,7 +52,9 @@ class MimeTypes {
static const v3gpp = 'video/3gpp'; static const v3gpp = 'video/3gpp';
static const asf = 'video/x-ms-asf'; static const asf = 'video/x-ms-asf';
static const avi = 'video/avi'; static const avi = 'video/avi';
static const aviMSVideo = 'video/msvideo';
static const aviVnd = 'video/vnd.avi'; static const aviVnd = 'video/vnd.avi';
static const aviXMSVideo = 'video/x-msvideo';
static const flv = 'video/flv'; static const flv = 'video/flv';
static const flvX = 'video/x-flv'; static const flvX = 'video/x-flv';
static const mkv = 'video/mkv'; static const mkv = 'video/mkv';
@ -87,7 +89,7 @@ class MimeTypes {
static const Set<String> _knownOpaqueImages = {jpeg}; static const Set<String> _knownOpaqueImages = {jpeg};
static const Set<String> _knownVideos = {v3gpp, asf, avi, aviVnd, flv, flvX, mkv, mkvX, mov, mp2p, mp2t, mp2ts, mp4, mpeg, ogv, realVideo, webm, wmv}; static const Set<String> _knownVideos = {v3gpp, asf, avi, aviMSVideo, aviVnd, aviXMSVideo, flv, flvX, mkv, mkvX, mov, mp2p, mp2t, mp2ts, mp4, mpeg, ogv, realVideo, webm, wmv};
static final Set<String> knownMediaTypes = { static final Set<String> knownMediaTypes = {
anyImage, anyImage,
@ -108,7 +110,9 @@ class MimeTypes {
static bool refersToSameType(String a, b) { static bool refersToSameType(String a, b) {
switch (a) { switch (a) {
case avi: case avi:
case aviMSVideo:
case aviVnd: case aviVnd:
case aviXMSVideo:
return [avi, aviVnd].contains(b); return [avi, aviVnd].contains(b);
case bmp: case bmp:
case bmpX: case bmpX:

View file

@ -113,8 +113,11 @@ class _EntryPageViewState extends State<EntryPageView> with SingleTickerProvider
viewerController.startAutopilotAnimation( viewerController.startAutopilotAnimation(
vsync: this, vsync: this,
onUpdate: ({required scaleLevel}) { onUpdate: ({required scaleLevel}) {
final scale = _magnifierController.scaleBoundaries.scaleForLevel(scaleLevel); final boundaries = _magnifierController.scaleBoundaries;
if (boundaries != null) {
final scale = boundaries.scaleForLevel(scaleLevel);
_magnifierController.update(scale: scale, source: ChangeSource.animation); _magnifierController.update(scale: scale, source: ChangeSource.animation);
}
}); });
} }
@ -318,11 +321,14 @@ class _EntryPageViewState extends State<EntryPageView> with SingleTickerProvider
// while cover is fading out, the same controller is used for both the cover and the video, // while cover is fading out, the same controller is used for both the cover and the video,
// and both fire scale boundaries events, so we make sure that in the end // and both fire scale boundaries events, so we make sure that in the end
// the scale boundaries from the video are used after the cover is gone // the scale boundaries from the video are used after the cover is gone
final boundaries = _magnifierController.scaleBoundaries;
if (boundaries != null) {
_magnifierController.setScaleBoundaries( _magnifierController.setScaleBoundaries(
_magnifierController.scaleBoundaries.copyWith( boundaries.copyWith(
childSize: videoDisplaySize, childSize: videoDisplaySize,
), ),
); );
}
}, },
child: ValueListenableBuilder<ImageInfo?>( child: ValueListenableBuilder<ImageInfo?>(
valueListenable: _videoCoverInfoNotifier, valueListenable: _videoCoverInfoNotifier,

View file

@ -48,7 +48,7 @@ class AvesMagnifierController {
double? get scale => currentState.scale; double? get scale => currentState.scale;
ScaleBoundaries get scaleBoundaries => _scaleBoundaries!; ScaleBoundaries? get scaleBoundaries => _scaleBoundaries;
ScaleStateChange get scaleState => _currentScaleState; ScaleStateChange get scaleState => _currentScaleState;
@ -118,17 +118,20 @@ class AvesMagnifierController {
} }
double? getScaleForScaleState(ScaleState scaleState) { double? getScaleForScaleState(ScaleState scaleState) {
double _clamp(double scale) => scale.clamp(scaleBoundaries.minScale, scaleBoundaries.maxScale); final boundaries = scaleBoundaries;
if (boundaries == null) return null;
double _clamp(double scale) => scale.clamp(boundaries.minScale, boundaries.maxScale);
switch (scaleState) { switch (scaleState) {
case ScaleState.initial: case ScaleState.initial:
case ScaleState.zoomedIn: case ScaleState.zoomedIn:
case ScaleState.zoomedOut: case ScaleState.zoomedOut:
return _clamp(scaleBoundaries.initialScale); return _clamp(boundaries.initialScale);
case ScaleState.covering: case ScaleState.covering:
return _clamp(ScaleLevel.scaleForCovering(scaleBoundaries.viewportSize, scaleBoundaries.childSize)); return _clamp(ScaleLevel.scaleForCovering(boundaries.viewportSize, boundaries.childSize));
case ScaleState.originalSize: case ScaleState.originalSize:
return _clamp(scaleBoundaries.originalScale); return _clamp(boundaries.originalScale);
default: default:
return null; return null;
} }

View file

@ -13,11 +13,7 @@ import 'package:flutter/widgets.dart';
mixin AvesMagnifierControllerDelegate on State<MagnifierCore> { mixin AvesMagnifierControllerDelegate on State<MagnifierCore> {
AvesMagnifierController get controller => widget.controller; AvesMagnifierController get controller => widget.controller;
ScaleBoundaries get scaleBoundaries => controller.scaleBoundaries; ScaleBoundaries? get scaleBoundaries => controller.scaleBoundaries;
Size get childSize => scaleBoundaries.childSize;
Size get viewportSize => scaleBoundaries.viewportSize;
ScaleStateCycle get scaleStateCycle => widget.scaleStateCycle; ScaleStateCycle get scaleStateCycle => widget.scaleStateCycle;
@ -56,8 +52,9 @@ mixin AvesMagnifierControllerDelegate on State<MagnifierCore> {
var nextPosition = Offset.zero; var nextPosition = Offset.zero;
if (nextScaleState == ScaleState.covering || nextScaleState == ScaleState.originalSize) { if (nextScaleState == ScaleState.covering || nextScaleState == ScaleState.originalSize) {
final childFocalPoint = scaleStateChange.childFocalPoint; final childFocalPoint = scaleStateChange.childFocalPoint;
if (childFocalPoint != null) { final boundaries = scaleBoundaries;
nextPosition = scaleBoundaries.childToStatePosition(nextScale!, childFocalPoint); if (childFocalPoint != null && boundaries != null) {
nextPosition = boundaries.childToStatePosition(nextScale!, childFocalPoint);
} }
} }
@ -70,11 +67,14 @@ mixin AvesMagnifierControllerDelegate on State<MagnifierCore> {
} }
void _onMagnifierStateChange(MagnifierState state) { void _onMagnifierStateChange(MagnifierState state) {
final boundaries = scaleBoundaries;
if (boundaries == null) return;
controller.update(position: clampPosition(), source: state.source); controller.update(position: clampPosition(), source: state.source);
if (controller.scale == controller.previousState.scale) return; if (controller.scale == controller.previousState.scale) return;
if (state.source == ChangeSource.internal || state.source == ChangeSource.animation) return; if (state.source == ChangeSource.internal || state.source == ChangeSource.animation) return;
final newScaleState = (scale! > scaleBoundaries.initialScale) ? ScaleState.zoomedIn : ScaleState.zoomedOut; final newScaleState = (scale! > boundaries.initialScale) ? ScaleState.zoomedIn : ScaleState.zoomedOut;
controller.setScaleState(newScaleState, state.source); controller.setScaleState(newScaleState, state.source);
} }
@ -104,9 +104,12 @@ mixin AvesMagnifierControllerDelegate on State<MagnifierCore> {
} }
void updateScaleStateFromNewScale(double newScale, ChangeSource source) { void updateScaleStateFromNewScale(double newScale, ChangeSource source) {
final boundaries = scaleBoundaries;
if (boundaries == null) return;
var newScaleState = ScaleState.initial; var newScaleState = ScaleState.initial;
if (scale != scaleBoundaries.initialScale) { if (scale != boundaries.initialScale) {
newScaleState = (newScale > scaleBoundaries.initialScale) ? ScaleState.zoomedIn : ScaleState.zoomedOut; newScaleState = (newScale > boundaries.initialScale) ? ScaleState.zoomedIn : ScaleState.zoomedOut;
} }
controller.setScaleState(newScaleState, source); controller.setScaleState(newScaleState, source);
} }
@ -136,10 +139,13 @@ mixin AvesMagnifierControllerDelegate on State<MagnifierCore> {
} }
CornersRange cornersX({double? scale}) { CornersRange cornersX({double? scale}) {
final boundaries = scaleBoundaries;
if (boundaries == null) return const CornersRange(0, 0);
final _scale = scale ?? this.scale!; final _scale = scale ?? this.scale!;
final computedWidth = childSize.width * _scale; final computedWidth = boundaries.childSize.width * _scale;
final screenWidth = viewportSize.width; final screenWidth = boundaries.viewportSize.width;
final positionX = basePosition.x; final positionX = basePosition.x;
final widthDiff = computedWidth - screenWidth; final widthDiff = computedWidth - screenWidth;
@ -150,10 +156,13 @@ mixin AvesMagnifierControllerDelegate on State<MagnifierCore> {
} }
CornersRange cornersY({double? scale}) { CornersRange cornersY({double? scale}) {
final boundaries = scaleBoundaries;
if (boundaries == null) return const CornersRange(0, 0);
final _scale = scale ?? this.scale!; final _scale = scale ?? this.scale!;
final computedHeight = childSize.height * _scale; final computedHeight = boundaries.childSize.height * _scale;
final screenHeight = viewportSize.height; final screenHeight = boundaries.viewportSize.height;
final positionY = basePosition.y; final positionY = basePosition.y;
final heightDiff = computedHeight - screenHeight; final heightDiff = computedHeight - screenHeight;
@ -164,14 +173,17 @@ mixin AvesMagnifierControllerDelegate on State<MagnifierCore> {
} }
Offset clampPosition({Offset? position, double? scale}) { Offset clampPosition({Offset? position, double? scale}) {
final boundaries = scaleBoundaries;
if (boundaries == null) return Offset.zero;
final _scale = scale ?? this.scale!; final _scale = scale ?? this.scale!;
final _position = position ?? this.position; final _position = position ?? this.position;
final computedWidth = childSize.width * _scale; final computedWidth = boundaries.childSize.width * _scale;
final computedHeight = childSize.height * _scale; final computedHeight = boundaries.childSize.height * _scale;
final screenWidth = viewportSize.width; final screenWidth = boundaries.viewportSize.width;
final screenHeight = viewportSize.height; final screenHeight = boundaries.viewportSize.height;
var finalX = 0.0; var finalX = 0.0;
if (screenWidth < computedWidth) { if (screenWidth < computedWidth) {

View file

@ -112,6 +112,9 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
} }
void onScaleUpdate(ScaleUpdateDetails details) { void onScaleUpdate(ScaleUpdateDetails details) {
final boundaries = scaleBoundaries;
if (boundaries == null) return;
double newScale; double newScale;
if (_doubleTap) { if (_doubleTap) {
// quick scale, aka one finger zoom // quick scale, aka one finger zoom
@ -131,7 +134,7 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
final scaleFocalPoint = _doubleTap ? _startFocalPoint! : details.focalPoint; final scaleFocalPoint = _doubleTap ? _startFocalPoint! : details.focalPoint;
final panPositionDelta = scaleFocalPoint - _lastViewportFocalPosition!; final panPositionDelta = scaleFocalPoint - _lastViewportFocalPosition!;
final scalePositionDelta = scaleBoundaries.viewportToStatePosition(controller, scaleFocalPoint) * (scale! / newScale - 1); final scalePositionDelta = boundaries.viewportToStatePosition(controller, scaleFocalPoint) * (scale! / newScale - 1);
final newPosition = position + panPositionDelta + scalePositionDelta; final newPosition = position + panPositionDelta + scalePositionDelta;
updateScaleStateFromNewScale(newScale, ChangeSource.gesture); updateScaleStateFromNewScale(newScale, ChangeSource.gesture);
@ -145,10 +148,13 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
} }
void onScaleEnd(ScaleEndDetails details) { void onScaleEnd(ScaleEndDetails details) {
final boundaries = scaleBoundaries;
if (boundaries == null) return;
final _position = controller.position; final _position = controller.position;
final _scale = controller.scale!; final _scale = controller.scale!;
final maxScale = scaleBoundaries.maxScale; final maxScale = boundaries.maxScale;
final minScale = scaleBoundaries.minScale; final minScale = boundaries.minScale;
// animate back to min/max scale if gesture yielded a scale exceeding them // animate back to min/max scale if gesture yielded a scale exceeding them
if (_scale > maxScale || _scale < minScale) { if (_scale > maxScale || _scale < minScale) {
@ -202,21 +208,30 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
final onTap = widget.onTap; final onTap = widget.onTap;
if (onTap == null) return; if (onTap == null) return;
final boundaries = scaleBoundaries;
if (boundaries == null) return;
final viewportTapPosition = details.localPosition; final viewportTapPosition = details.localPosition;
final viewportSize = boundaries.viewportSize;
final alignment = Alignment(viewportTapPosition.dx / viewportSize.width, viewportTapPosition.dy / viewportSize.height); final alignment = Alignment(viewportTapPosition.dx / viewportSize.width, viewportTapPosition.dy / viewportSize.height);
final childTapPosition = scaleBoundaries.viewportToChildPosition(controller, viewportTapPosition); final childTapPosition = boundaries.viewportToChildPosition(controller, viewportTapPosition);
onTap(context, controller.currentState, alignment, childTapPosition); onTap(context, controller.currentState, alignment, childTapPosition);
} }
void onDoubleTap(TapDownDetails details) { void onDoubleTap(TapDownDetails details) {
final boundaries = scaleBoundaries;
if (boundaries == null) return;
final viewportTapPosition = details.localPosition; final viewportTapPosition = details.localPosition;
if (widget.onDoubleTap != null) { final onDoubleTap = widget.onDoubleTap;
final viewportSize = scaleBoundaries.viewportSize; if (onDoubleTap != null) {
final viewportSize = boundaries.viewportSize;
final alignment = Alignment(viewportTapPosition.dx / viewportSize.width, viewportTapPosition.dy / viewportSize.height); final alignment = Alignment(viewportTapPosition.dx / viewportSize.width, viewportTapPosition.dy / viewportSize.height);
if (widget.onDoubleTap?.call(alignment) == true) return; if (onDoubleTap.call(alignment) == true) return;
} }
final childTapPosition = scaleBoundaries.viewportToChildPosition(controller, viewportTapPosition); final childTapPosition = boundaries.viewportToChildPosition(controller, viewportTapPosition);
nextScaleState(ChangeSource.gesture, childFocalPoint: childTapPosition); nextScaleState(ChangeSource.gesture, childFocalPoint: childTapPosition);
} }
@ -245,7 +260,7 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
/// Check if scale is equal to initial after scale animation update /// Check if scale is equal to initial after scale animation update
void onAnimationStatusCompleted() { void onAnimationStatusCompleted() {
if (controller.scaleState.state != ScaleState.initial && scale == scaleBoundaries.initialScale) { if (controller.scaleState.state != ScaleState.initial && scale == scaleBoundaries?.initialScale) {
controller.setScaleState(ScaleState.initial, ChangeSource.animation); controller.setScaleState(ScaleState.initial, ChangeSource.animation);
} }
} }
@ -267,7 +282,8 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
stream: controller.stateStream, stream: controller.stateStream,
initialData: controller.previousState, initialData: controller.previousState,
builder: (context, snapshot) { builder: (context, snapshot) {
if (!snapshot.hasData) return Container(); final boundaries = scaleBoundaries;
if (!snapshot.hasData || boundaries == null) return const SizedBox();
final magnifierState = snapshot.data!; final magnifierState = snapshot.data!;
final position = magnifierState.position; final position = magnifierState.position;
@ -275,7 +291,7 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
Widget child = CustomSingleChildLayout( Widget child = CustomSingleChildLayout(
delegate: _CenterWithOriginalSizeDelegate( delegate: _CenterWithOriginalSizeDelegate(
scaleBoundaries.childSize, boundaries.childSize,
basePosition, basePosition,
applyScale, applyScale,
), ),
@ -299,7 +315,8 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
onTapUp: widget.onTap == null ? null : onTap, onTapUp: widget.onTap == null ? null : onTap,
child: child, child: child,
); );
}); },
);
} }
} }

View file

@ -9,8 +9,11 @@ mixin CornerHitDetector on AvesMagnifierControllerDelegate {
// so be sure to compare with `precisionErrorTolerance` // so be sure to compare with `precisionErrorTolerance`
_CornerHit _hitCornersX() { _CornerHit _hitCornersX() {
final childWidth = scaleBoundaries.childSize.width * scale!; final boundaries = scaleBoundaries;
final viewportWidth = scaleBoundaries.viewportSize.width; if (boundaries == null) return const _CornerHit(false, false);
final childWidth = boundaries.childSize.width * scale!;
final viewportWidth = boundaries.viewportSize.width;
if (viewportWidth + precisionErrorTolerance >= childWidth) { if (viewportWidth + precisionErrorTolerance >= childWidth) {
return const _CornerHit(true, true); return const _CornerHit(true, true);
} }
@ -20,8 +23,11 @@ mixin CornerHitDetector on AvesMagnifierControllerDelegate {
} }
_CornerHit _hitCornersY() { _CornerHit _hitCornersY() {
final childHeight = scaleBoundaries.childSize.height * scale!; final boundaries = scaleBoundaries;
final viewportHeight = scaleBoundaries.viewportSize.height; if (boundaries == null) return const _CornerHit(false, false);
final childHeight = boundaries.childSize.height * scale!;
final viewportHeight = boundaries.viewportSize.height;
if (viewportHeight + precisionErrorTolerance >= childHeight) { if (viewportHeight + precisionErrorTolerance >= childHeight) {
return const _CornerHit(true, true); return const _CornerHit(true, true);
} }