diff --git a/lib/widgets/common/magnifier/controller/controller_delegate.dart b/lib/widgets/common/magnifier/controller/controller_delegate.dart index a6a79b3d7..13b94d875 100644 --- a/lib/widgets/common/magnifier/controller/controller_delegate.dart +++ b/lib/widgets/common/magnifier/controller/controller_delegate.dart @@ -31,9 +31,16 @@ mixin MagnifierControllerDelegate on State { final List _subscriptions = []; - void startListeners() { - _subscriptions.add(controller.stateStream.listen(_onMagnifierStateChange)); - _subscriptions.add(controller.scaleStateChangeStream.listen(_onScaleStateChange)); + void registerDelegate(MagnifierCore widget) { + _subscriptions.add(widget.controller.stateStream.listen(_onMagnifierStateChange)); + _subscriptions.add(widget.controller.scaleStateChangeStream.listen(_onScaleStateChange)); + } + + void unregisterDelegate(MagnifierCore oldWidget) { + _animateScale = null; + _subscriptions + ..forEach((sub) => sub.cancel()) + ..clear(); } void _onScaleStateChange(ScaleStateChange scaleStateChange) { @@ -181,14 +188,6 @@ mixin MagnifierControllerDelegate on State { return Offset(finalX, finalY); } - - @override - void dispose() { - _animateScale = null; - _subscriptions.forEach((sub) => sub.cancel()); - _subscriptions.clear(); - super.dispose(); - } } /// Simple class to store a min and a max value diff --git a/lib/widgets/common/magnifier/core/core.dart b/lib/widgets/common/magnifier/core/core.dart index a84051e1c..214cb5089 100644 --- a/lib/widgets/common/magnifier/core/core.dart +++ b/lib/widgets/common/magnifier/core/core.dart @@ -12,30 +12,25 @@ import 'package:flutter/widgets.dart'; /// Internal widget in which controls all animations lifecycle, core responses /// to user gestures, updates to the controller state and mounts the entire Layout class MagnifierCore extends StatefulWidget { + final MagnifierController controller; + final ScaleStateCycle scaleStateCycle; + final bool applyScale; + final double panInertia; + final MagnifierTapCallback? onTap; + final Widget child; + const MagnifierCore({ Key? key, - required this.child, - required this.onTap, required this.controller, required this.scaleStateCycle, required this.applyScale, this.panInertia = .2, + required this.onTap, + required this.child, }) : super(key: key); - final Widget child; - - final MagnifierController controller; - final ScaleStateCycle scaleStateCycle; - - final MagnifierTapCallback? onTap; - - final bool applyScale; - final double panInertia; - @override - State createState() { - return _MagnifierCoreState(); - } + State createState() => _MagnifierCoreState(); } class _MagnifierCoreState extends State with TickerProviderStateMixin, MagnifierControllerDelegate, CornerHitDetector { @@ -52,6 +47,45 @@ class _MagnifierCoreState extends State with TickerProviderStateM ScaleBoundaries? cachedScaleBoundaries; + @override + void initState() { + super.initState(); + _scaleAnimationController = AnimationController(vsync: this) + ..addListener(handleScaleAnimation) + ..addStatusListener(onAnimationStatus); + _positionAnimationController = AnimationController(vsync: this)..addListener(handlePositionAnimate); + _registerWidget(widget); + } + + @override + void didUpdateWidget(covariant MagnifierCore oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.controller != widget.controller) { + _unregisterWidget(oldWidget); + _registerWidget(widget); + } + } + + @override + void dispose() { + _unregisterWidget(widget); + _scaleAnimationController.dispose(); + _positionAnimationController.dispose(); + super.dispose(); + } + + void _registerWidget(MagnifierCore widget) { + registerDelegate(widget); + cachedScaleBoundaries = widget.controller.scaleBoundaries; + setScaleStateUpdateAnimation(animateOnScaleStateUpdate); + } + + void _unregisterWidget(MagnifierCore oldWidget) { + unregisterDelegate(oldWidget); + cachedScaleBoundaries = null; + } + void handleScaleAnimation() { setScale(_scaleAnimation.value, ChangeSource.animation); } @@ -202,33 +236,11 @@ class _MagnifierCoreState extends State with TickerProviderStateM } } - @override - void initState() { - super.initState(); - _scaleAnimationController = AnimationController(vsync: this)..addListener(handleScaleAnimation); - _scaleAnimationController.addStatusListener(onAnimationStatus); - - _positionAnimationController = AnimationController(vsync: this)..addListener(handlePositionAnimate); - - startListeners(); - setScaleStateUpdateAnimation(animateOnScaleStateUpdate); - - cachedScaleBoundaries = widget.controller.scaleBoundaries; - } - void animateOnScaleStateUpdate(double? prevScale, double? nextScale, Offset nextPosition) { animateScale(prevScale, nextScale); animatePosition(controller.position, nextPosition); } - @override - void dispose() { - _scaleAnimationController.removeStatusListener(onAnimationStatus); - _scaleAnimationController.dispose(); - _positionAnimationController.dispose(); - super.dispose(); - } - @override Widget build(BuildContext context) { // Check if we need a recalc on the scale diff --git a/lib/widgets/common/magnifier/magnifier.dart b/lib/widgets/common/magnifier/magnifier.dart index 342a0590a..36ab155cd 100644 --- a/lib/widgets/common/magnifier/magnifier.dart +++ b/lib/widgets/common/magnifier/magnifier.dart @@ -66,8 +66,8 @@ class Magnifier extends StatelessWidget { return MagnifierCore( controller: controller, scaleStateCycle: scaleStateCycle, - onTap: onTap, applyScale: applyScale, + onTap: onTap, child: child, ); }, diff --git a/lib/widgets/viewer/visual/entry_page_view.dart b/lib/widgets/viewer/visual/entry_page_view.dart index 45358c5d4..af99aaad8 100644 --- a/lib/widgets/viewer/visual/entry_page_view.dart +++ b/lib/widgets/viewer/visual/entry_page_view.dart @@ -62,7 +62,7 @@ class _EntryPageViewState extends State { @override void initState() { super.initState(); - _registerWidget(); + _registerWidget(widget); } @override @@ -70,19 +70,20 @@ class _EntryPageViewState extends State { super.didUpdateWidget(oldWidget); if (oldWidget.pageEntry != widget.pageEntry) { - _unregisterWidget(); - _registerWidget(); + _unregisterWidget(oldWidget); + _registerWidget(widget); } } @override void dispose() { - _unregisterWidget(); + _unregisterWidget(widget); widget.onDisposed?.call(); super.dispose(); } - void _registerWidget() { + void _registerWidget(EntryPageView widget) { + final entry = widget.pageEntry; _viewStateNotifier = context.read().getOrCreateController(entry); _magnifierController = MagnifierController(); _subscriptions.add(_magnifierController.stateStream.listen(_onViewStateChanged)); @@ -94,7 +95,7 @@ class _EntryPageViewState extends State { } } - void _unregisterWidget() { + void _unregisterWidget(EntryPageView oldWidget) { _videoCoverStream?.removeListener(_videoCoverStreamListener); _videoCoverStream = null; _videoCoverInfoNotifier.value = null;