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)
success(granted)
} 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()
}

View file

@ -52,7 +52,9 @@ class MimeTypes {
static const v3gpp = 'video/3gpp';
static const asf = 'video/x-ms-asf';
static const avi = 'video/avi';
static const aviMSVideo = 'video/msvideo';
static const aviVnd = 'video/vnd.avi';
static const aviXMSVideo = 'video/x-msvideo';
static const flv = 'video/flv';
static const flvX = 'video/x-flv';
static const mkv = 'video/mkv';
@ -87,7 +89,7 @@ class MimeTypes {
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 = {
anyImage,
@ -108,7 +110,9 @@ class MimeTypes {
static bool refersToSameType(String a, b) {
switch (a) {
case avi:
case aviMSVideo:
case aviVnd:
case aviXMSVideo:
return [avi, aviVnd].contains(b);
case bmp:
case bmpX:

View file

@ -113,8 +113,11 @@ class _EntryPageViewState extends State<EntryPageView> with SingleTickerProvider
viewerController.startAutopilotAnimation(
vsync: this,
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);
}
});
}
@ -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,
// 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
final boundaries = _magnifierController.scaleBoundaries;
if (boundaries != null) {
_magnifierController.setScaleBoundaries(
_magnifierController.scaleBoundaries.copyWith(
boundaries.copyWith(
childSize: videoDisplaySize,
),
);
}
},
child: ValueListenableBuilder<ImageInfo?>(
valueListenable: _videoCoverInfoNotifier,

View file

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

View file

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

View file

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

View file

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