import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/viewer/view_state.dart'; import 'package:aves/widgets/viewer/view/controller.dart'; import 'package:aves_magnifier/aves_magnifier.dart'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; import 'package:leak_tracker/leak_tracker.dart'; class ViewStateConductor { final List _controllers = []; Size _viewportSize = Size.zero; static const maxControllerCount = 3; ViewStateConductor() { if (kFlutterMemoryAllocationsEnabled) { LeakTracking.dispatchObjectCreated( library: 'aves', className: '$ViewStateConductor', object: this, ); } } Future dispose() async { if (kFlutterMemoryAllocationsEnabled) { LeakTracking.dispatchObjectDisposed(object: this); } _controllers.forEach((v) => v.dispose()); _controllers.clear(); } set viewportSize(Size size) => _viewportSize = size; ViewStateController getOrCreateController(AvesEntry entry) { // Identificazione robusta anche per remoti (uri può essere null): // usa SEMPRE (id, pageId) come chiave logica del controller. var controller = getController(entry); if (controller != null) { _controllers.remove(controller); } else { // inizializza lo stato per combaciare lo stato iniziale del magnifier const initialScale = ScaleLevel(ref: ScaleReference.contained); final initialValue = ViewState( position: Offset.zero, scale: ScaleBoundaries( allowOriginalScaleBeyondRange: true, minScale: initialScale, maxScale: initialScale, initialScale: initialScale, viewportSize: _viewportSize, contentSize: entry.displaySize, ).initialScale, viewportSize: _viewportSize, contentSize: entry.displaySize, ); controller = ViewStateController( entry: entry, viewStateNotifier: ValueNotifier(initialValue), ); } _controllers.insert(0, controller); while (_controllers.length > maxControllerCount) { _controllers.removeLast().dispose(); } return controller; } ViewStateController? getController(AvesEntry entry) { // Confronto per (id, pageId) invece di (uri, pageId) return _controllers.firstWhereOrNull( (c) => c.entry.id == entry.id && c.entry.pageId == entry.pageId, ); } void reset(AvesEntry entry) { // Reset per id (gli uri remoti possono essere null, quindi non affidabili) final ids = { entry.id, ...?entry.stackedEntries?.map((e) => e.id), }; final entryControllers = _controllers.where((v) => ids.contains(v.entry.id)).toSet(); entryControllers.forEach((controller) { _controllers.remove(controller); controller.dispose(); }); } }