mirror of
https://github.com/immich-app/immich.git
synced 2025-07-31 15:08:44 -04:00
chore: hero animations (#19860)
* remove herocontrollerscope * handle heroOffset in new timeline --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
70b73145f1
commit
7d8f56b483
@ -23,12 +23,12 @@ import 'package:immich_mobile/providers/theme.provider.dart';
|
|||||||
import 'package:immich_mobile/routing/app_navigation_observer.dart';
|
import 'package:immich_mobile/routing/app_navigation_observer.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:immich_mobile/services/background.service.dart';
|
import 'package:immich_mobile/services/background.service.dart';
|
||||||
|
import 'package:immich_mobile/services/deep_link.service.dart';
|
||||||
import 'package:immich_mobile/services/local_notification.service.dart';
|
import 'package:immich_mobile/services/local_notification.service.dart';
|
||||||
import 'package:immich_mobile/theme/dynamic_theme.dart';
|
import 'package:immich_mobile/theme/dynamic_theme.dart';
|
||||||
import 'package:immich_mobile/theme/theme_data.dart';
|
import 'package:immich_mobile/theme/theme_data.dart';
|
||||||
import 'package:immich_mobile/utils/bootstrap.dart';
|
import 'package:immich_mobile/utils/bootstrap.dart';
|
||||||
import 'package:immich_mobile/utils/cache/widgets_binding.dart';
|
import 'package:immich_mobile/utils/cache/widgets_binding.dart';
|
||||||
import 'package:immich_mobile/services/deep_link.service.dart';
|
|
||||||
import 'package:immich_mobile/utils/download.dart';
|
import 'package:immich_mobile/utils/download.dart';
|
||||||
import 'package:immich_mobile/utils/http_ssl_options.dart';
|
import 'package:immich_mobile/utils/http_ssl_options.dart';
|
||||||
import 'package:immich_mobile/utils/migration.dart';
|
import 'package:immich_mobile/utils/migration.dart';
|
||||||
@ -253,7 +253,8 @@ class ImmichAppState extends ConsumerState<ImmichApp>
|
|||||||
),
|
),
|
||||||
routerConfig: router.config(
|
routerConfig: router.config(
|
||||||
deepLinkBuilder: _deepLinkBuilder,
|
deepLinkBuilder: _deepLinkBuilder,
|
||||||
navigatorObservers: () => [AppNavigationObserver(ref: ref)],
|
navigatorObservers: () =>
|
||||||
|
[AppNavigationObserver(ref: ref), HeroController()],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -4,13 +4,13 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/providers/album/album.provider.dart';
|
import 'package:immich_mobile/providers/album/album.provider.dart';
|
||||||
|
import 'package:immich_mobile/providers/asset.provider.dart';
|
||||||
import 'package:immich_mobile/providers/asset_viewer/scroll_notifier.provider.dart';
|
import 'package:immich_mobile/providers/asset_viewer/scroll_notifier.provider.dart';
|
||||||
|
import 'package:immich_mobile/providers/haptic_feedback.provider.dart';
|
||||||
import 'package:immich_mobile/providers/multiselect.provider.dart';
|
import 'package:immich_mobile/providers/multiselect.provider.dart';
|
||||||
import 'package:immich_mobile/providers/search/search_input_focus.provider.dart';
|
import 'package:immich_mobile/providers/search/search_input_focus.provider.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
|
||||||
import 'package:immich_mobile/providers/asset.provider.dart';
|
|
||||||
import 'package:immich_mobile/providers/haptic_feedback.provider.dart';
|
|
||||||
import 'package:immich_mobile/providers/tab.provider.dart';
|
import 'package:immich_mobile/providers/tab.provider.dart';
|
||||||
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class TabControllerPage extends HookConsumerWidget {
|
class TabControllerPage extends HookConsumerWidget {
|
||||||
@ -158,10 +158,6 @@ class TabControllerPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
final tabsRouter = AutoTabsRouter.of(context);
|
final tabsRouter = AutoTabsRouter.of(context);
|
||||||
final heroedChild = HeroControllerScope(
|
|
||||||
controller: HeroController(),
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: tabsRouter.activeIndex == 0,
|
canPop: tabsRouter.activeIndex == 0,
|
||||||
onPopInvokedWithResult: (didPop, _) =>
|
onPopInvokedWithResult: (didPop, _) =>
|
||||||
@ -173,10 +169,10 @@ class TabControllerPage extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
navigationRail(tabsRouter),
|
navigationRail(tabsRouter),
|
||||||
const VerticalDivider(),
|
const VerticalDivider(),
|
||||||
Expanded(child: heroedChild),
|
Expanded(child: child),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: heroedChild,
|
: child,
|
||||||
bottomNavigationBar: multiselectEnabled || isScreenLandscape
|
bottomNavigationBar: multiselectEnabled || isScreenLandscape
|
||||||
? null
|
? null
|
||||||
: bottomNavigationBar(tabsRouter),
|
: bottomNavigationBar(tabsRouter),
|
||||||
|
@ -127,10 +127,6 @@ class TabShellPage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
final tabsRouter = AutoTabsRouter.of(context);
|
final tabsRouter = AutoTabsRouter.of(context);
|
||||||
final heroedChild = HeroControllerScope(
|
|
||||||
controller: HeroController(),
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: tabsRouter.activeIndex == 0,
|
canPop: tabsRouter.activeIndex == 0,
|
||||||
onPopInvokedWithResult: (didPop, _) =>
|
onPopInvokedWithResult: (didPop, _) =>
|
||||||
@ -142,10 +138,10 @@ class TabShellPage extends ConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
navigationRail(tabsRouter),
|
navigationRail(tabsRouter),
|
||||||
const VerticalDivider(),
|
const VerticalDivider(),
|
||||||
Expanded(child: heroedChild),
|
Expanded(child: child),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: heroedChild,
|
: child,
|
||||||
bottomNavigationBar: _BottomNavigationBar(
|
bottomNavigationBar: _BottomNavigationBar(
|
||||||
tabsRouter: tabsRouter,
|
tabsRouter: tabsRouter,
|
||||||
destinations: navigationDestinations,
|
destinations: navigationDestinations,
|
||||||
|
@ -71,6 +71,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
|||||||
StreamSubscription? reloadSubscription;
|
StreamSubscription? reloadSubscription;
|
||||||
|
|
||||||
late Platform platform;
|
late Platform platform;
|
||||||
|
late final int heroOffset;
|
||||||
late PhotoViewControllerValue initialPhotoViewState;
|
late PhotoViewControllerValue initialPhotoViewState;
|
||||||
bool? hasDraggedDown;
|
bool? hasDraggedDown;
|
||||||
bool isSnapping = false;
|
bool isSnapping = false;
|
||||||
@ -98,6 +99,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
|||||||
_onAssetChanged(widget.initialIndex);
|
_onAssetChanged(widget.initialIndex);
|
||||||
});
|
});
|
||||||
reloadSubscription = EventStream.shared.listen(_onEvent);
|
reloadSubscription = EventStream.shared.listen(_onEvent);
|
||||||
|
heroOffset = TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -487,7 +489,8 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
|||||||
return PhotoViewGalleryPageOptions(
|
return PhotoViewGalleryPageOptions(
|
||||||
key: ValueKey(asset.heroTag),
|
key: ValueKey(asset.heroTag),
|
||||||
imageProvider: getFullImageProvider(asset, size: size),
|
imageProvider: getFullImageProvider(asset, size: size),
|
||||||
heroAttributes: PhotoViewHeroAttributes(tag: asset.heroTag),
|
heroAttributes:
|
||||||
|
PhotoViewHeroAttributes(tag: '${asset.heroTag}_$heroOffset'),
|
||||||
filterQuality: FilterQuality.high,
|
filterQuality: FilterQuality.high,
|
||||||
tightMode: true,
|
tightMode: true,
|
||||||
initialScale: PhotoViewComputedScale.contained * 0.999,
|
initialScale: PhotoViewComputedScale.contained * 0.999,
|
||||||
@ -521,7 +524,8 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
|||||||
onDragUpdate: _onDragUpdate,
|
onDragUpdate: _onDragUpdate,
|
||||||
onDragEnd: _onDragEnd,
|
onDragEnd: _onDragEnd,
|
||||||
onTapDown: _onTapDown,
|
onTapDown: _onTapDown,
|
||||||
heroAttributes: PhotoViewHeroAttributes(tag: asset.heroTag),
|
heroAttributes:
|
||||||
|
PhotoViewHeroAttributes(tag: '${asset.heroTag}_$heroOffset'),
|
||||||
filterQuality: FilterQuality.high,
|
filterQuality: FilterQuality.high,
|
||||||
initialScale: PhotoViewComputedScale.contained * 0.99,
|
initialScale: PhotoViewComputedScale.contained * 0.99,
|
||||||
maxScale: 1.0,
|
maxScale: 1.0,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
@ -25,6 +26,8 @@ class ThumbnailTile extends ConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final heroOffset = TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
|
||||||
|
|
||||||
final assetContainerColor = context.isDarkTheme
|
final assetContainerColor = context.isDarkTheme
|
||||||
? context.primaryColor.darken(amount: 0.4)
|
? context.primaryColor.darken(amount: 0.4)
|
||||||
: context.primaryColor.lighten(amount: 0.75);
|
: context.primaryColor.lighten(amount: 0.75);
|
||||||
@ -64,7 +67,7 @@ class ThumbnailTile extends ConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Hero(
|
child: Hero(
|
||||||
tag: asset.heroTag,
|
tag: '${asset.heroTag}_$heroOffset',
|
||||||
child: Thumbnail(
|
child: Thumbnail(
|
||||||
asset: asset,
|
asset: asset,
|
||||||
fit: fit,
|
fit: fit,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user