|
@@ -1,5 +1,6 @@
|
|
|
import 'dart:math';
|
|
|
|
|
|
+import 'package:auto_route/auto_route.dart';
|
|
|
import 'package:flutter/gestures.dart';
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
@@ -52,84 +53,61 @@ class ImmichAssetGrid extends HookConsumerWidget {
|
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
|
var settings = ref.watch(appSettingsServiceProvider);
|
|
|
|
|
|
- // Needs to suppress hero animations when navigating to this widget
|
|
|
- final enableHeroAnimations = useState(false);
|
|
|
- final transitionDuration = ModalRoute.of(context)?.transitionDuration;
|
|
|
-
|
|
|
final perRow = useState(
|
|
|
assetsPerRow ?? settings.getSetting(AppSettingsEnum.tilesPerRow)!,
|
|
|
);
|
|
|
final scaleFactor = useState(7.0 - perRow.value);
|
|
|
final baseScaleFactor = useState(7.0 - perRow.value);
|
|
|
|
|
|
- useEffect(
|
|
|
- () {
|
|
|
- // Wait for transition to complete, then re-enable
|
|
|
- if (transitionDuration == null) {
|
|
|
- // No route transition found, maybe we opened this up first
|
|
|
- enableHeroAnimations.value = true;
|
|
|
- } else {
|
|
|
- // Unfortunately, using the transition animation itself didn't
|
|
|
- // seem to work reliably. So instead, wait until the duration of the
|
|
|
- // animation has elapsed to re-enable the hero animations
|
|
|
- Future.delayed(transitionDuration).then((_) {
|
|
|
- enableHeroAnimations.value = true;
|
|
|
- });
|
|
|
- }
|
|
|
- return null;
|
|
|
- },
|
|
|
- [],
|
|
|
- );
|
|
|
-
|
|
|
- Future<bool> onWillPop() async {
|
|
|
- enableHeroAnimations.value = false;
|
|
|
- return true;
|
|
|
+ /// assets need different hero tags across tabs / modals
|
|
|
+ /// otherwise, hero animations are performed across tabs (looks buggy!)
|
|
|
+ int heroOffset() {
|
|
|
+ const int range = 1152921504606846976; // 2^60
|
|
|
+ final tabScope = TabsRouterScope.of(context);
|
|
|
+ if (tabScope != null) {
|
|
|
+ final int tabIndex = tabScope.controller.activeIndex;
|
|
|
+ return tabIndex * range;
|
|
|
+ }
|
|
|
+ return range * 7;
|
|
|
}
|
|
|
|
|
|
Widget buildAssetGridView(RenderList renderList) {
|
|
|
- return WillPopScope(
|
|
|
- onWillPop: onWillPop,
|
|
|
- child: HeroMode(
|
|
|
- enabled: enableHeroAnimations.value,
|
|
|
- child: RawGestureDetector(
|
|
|
- gestures: {
|
|
|
- CustomScaleGestureRecognizer:
|
|
|
- GestureRecognizerFactoryWithHandlers<
|
|
|
- CustomScaleGestureRecognizer>(
|
|
|
- () => CustomScaleGestureRecognizer(),
|
|
|
- (CustomScaleGestureRecognizer scale) {
|
|
|
- scale.onStart = (details) {
|
|
|
- baseScaleFactor.value = scaleFactor.value;
|
|
|
- };
|
|
|
+ return RawGestureDetector(
|
|
|
+ gestures: {
|
|
|
+ CustomScaleGestureRecognizer: GestureRecognizerFactoryWithHandlers<
|
|
|
+ CustomScaleGestureRecognizer>(
|
|
|
+ () => CustomScaleGestureRecognizer(),
|
|
|
+ (CustomScaleGestureRecognizer scale) {
|
|
|
+ scale.onStart = (details) {
|
|
|
+ baseScaleFactor.value = scaleFactor.value;
|
|
|
+ };
|
|
|
|
|
|
- scale.onUpdate = (details) {
|
|
|
- scaleFactor.value =
|
|
|
- max(min(5.0, baseScaleFactor.value * details.scale), 1.0);
|
|
|
- if (7 - scaleFactor.value.toInt() != perRow.value) {
|
|
|
- perRow.value = 7 - scaleFactor.value.toInt();
|
|
|
- }
|
|
|
- };
|
|
|
- scale.onEnd = (details) {};
|
|
|
- })
|
|
|
- },
|
|
|
- child: ImmichAssetGridView(
|
|
|
- onRefresh: onRefresh,
|
|
|
- assetsPerRow: perRow.value,
|
|
|
- listener: listener,
|
|
|
- showStorageIndicator: showStorageIndicator ??
|
|
|
- settings.getSetting(AppSettingsEnum.storageIndicator),
|
|
|
- renderList: renderList,
|
|
|
- margin: margin,
|
|
|
- selectionActive: selectionActive,
|
|
|
- preselectedAssets: preselectedAssets,
|
|
|
- canDeselect: canDeselect,
|
|
|
- dynamicLayout: dynamicLayout ??
|
|
|
- settings.getSetting(AppSettingsEnum.dynamicLayout),
|
|
|
- showMultiSelectIndicator: showMultiSelectIndicator,
|
|
|
- visibleItemsListener: visibleItemsListener,
|
|
|
- topWidget: topWidget,
|
|
|
- ),
|
|
|
- ),
|
|
|
+ scale.onUpdate = (details) {
|
|
|
+ scaleFactor.value =
|
|
|
+ max(min(5.0, baseScaleFactor.value * details.scale), 1.0);
|
|
|
+ if (7 - scaleFactor.value.toInt() != perRow.value) {
|
|
|
+ perRow.value = 7 - scaleFactor.value.toInt();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ })
|
|
|
+ },
|
|
|
+ child: ImmichAssetGridView(
|
|
|
+ onRefresh: onRefresh,
|
|
|
+ assetsPerRow: perRow.value,
|
|
|
+ listener: listener,
|
|
|
+ showStorageIndicator: showStorageIndicator ??
|
|
|
+ settings.getSetting(AppSettingsEnum.storageIndicator),
|
|
|
+ renderList: renderList,
|
|
|
+ margin: margin,
|
|
|
+ selectionActive: selectionActive,
|
|
|
+ preselectedAssets: preselectedAssets,
|
|
|
+ canDeselect: canDeselect,
|
|
|
+ dynamicLayout: dynamicLayout ??
|
|
|
+ settings.getSetting(AppSettingsEnum.dynamicLayout),
|
|
|
+ showMultiSelectIndicator: showMultiSelectIndicator,
|
|
|
+ visibleItemsListener: visibleItemsListener,
|
|
|
+ topWidget: topWidget,
|
|
|
+ heroOffset: heroOffset(),
|
|
|
),
|
|
|
);
|
|
|
}
|