aves_mio1/lib/widgets/viewer/view/conductor.dart
FabioMich66 084fa184da
Some checks failed
Quality check / Flutter analysis (push) Has been cancelled
Quality check / CodeQL analysis (java-kotlin) (push) Has been cancelled
ok con video e foto in galleria aves
2026-03-17 12:19:38 +01:00

89 lines
2.9 KiB
Dart

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<ViewStateController> _controllers = [];
Size _viewportSize = Size.zero;
static const maxControllerCount = 3;
ViewStateConductor() {
if (kFlutterMemoryAllocationsEnabled) {
LeakTracking.dispatchObjectCreated(
library: 'aves',
className: '$ViewStateConductor',
object: this,
);
}
}
Future<void> 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<ViewState>(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 = <int>{
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();
});
}
}