mirror of
https://github.com/immich-app/immich.git
synced 2025-07-31 15:08:44 -04:00
fix: no hero animation after tab change (#20285)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
parent
d0576697c3
commit
e85655d34c
@ -34,11 +34,13 @@ import 'package:platform/platform.dart';
|
|||||||
class AssetViewerPage extends StatelessWidget {
|
class AssetViewerPage extends StatelessWidget {
|
||||||
final int initialIndex;
|
final int initialIndex;
|
||||||
final TimelineService timelineService;
|
final TimelineService timelineService;
|
||||||
|
final int? heroOffset;
|
||||||
|
|
||||||
const AssetViewerPage({
|
const AssetViewerPage({
|
||||||
super.key,
|
super.key,
|
||||||
required this.initialIndex,
|
required this.initialIndex,
|
||||||
required this.timelineService,
|
required this.timelineService,
|
||||||
|
this.heroOffset,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -47,7 +49,7 @@ class AssetViewerPage extends StatelessWidget {
|
|||||||
// since the Timeline and AssetViewer are on different routes / Widget subtrees.
|
// since the Timeline and AssetViewer are on different routes / Widget subtrees.
|
||||||
return ProviderScope(
|
return ProviderScope(
|
||||||
overrides: [timelineServiceProvider.overrideWithValue(timelineService)],
|
overrides: [timelineServiceProvider.overrideWithValue(timelineService)],
|
||||||
child: AssetViewer(initialIndex: initialIndex),
|
child: AssetViewer(initialIndex: initialIndex, heroOffset: heroOffset),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,11 +57,13 @@ class AssetViewerPage extends StatelessWidget {
|
|||||||
class AssetViewer extends ConsumerStatefulWidget {
|
class AssetViewer extends ConsumerStatefulWidget {
|
||||||
final int initialIndex;
|
final int initialIndex;
|
||||||
final Platform? platform;
|
final Platform? platform;
|
||||||
|
final int? heroOffset;
|
||||||
|
|
||||||
const AssetViewer({
|
const AssetViewer({
|
||||||
super.key,
|
super.key,
|
||||||
required this.initialIndex,
|
required this.initialIndex,
|
||||||
this.platform,
|
this.platform,
|
||||||
|
this.heroOffset,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -108,7 +112,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;
|
heroOffset = widget.heroOffset ?? TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -15,6 +15,7 @@ class ThumbnailTile extends ConsumerWidget {
|
|||||||
this.fit = BoxFit.cover,
|
this.fit = BoxFit.cover,
|
||||||
this.showStorageIndicator = true,
|
this.showStorageIndicator = true,
|
||||||
this.lockSelection = false,
|
this.lockSelection = false,
|
||||||
|
this.heroOffset,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -23,10 +24,11 @@ class ThumbnailTile extends ConsumerWidget {
|
|||||||
final BoxFit fit;
|
final BoxFit fit;
|
||||||
final bool showStorageIndicator;
|
final bool showStorageIndicator;
|
||||||
final bool lockSelection;
|
final bool lockSelection;
|
||||||
|
final int? heroOffset;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final heroOffset = TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
|
final heroIndex = heroOffset ?? TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
|
||||||
|
|
||||||
final assetContainerColor =
|
final assetContainerColor =
|
||||||
context.isDarkTheme ? context.primaryColor.darken(amount: 0.4) : context.primaryColor.lighten(amount: 0.75);
|
context.isDarkTheme ? context.primaryColor.darken(amount: 0.4) : context.primaryColor.lighten(amount: 0.75);
|
||||||
@ -67,7 +69,7 @@ class ThumbnailTile extends ConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Hero(
|
child: Hero(
|
||||||
tag: '${asset.heroTag}_$heroOffset',
|
tag: '${asset.heroTag}_$heroIndex',
|
||||||
child: Thumbnail(
|
child: Thumbnail(
|
||||||
asset: asset,
|
asset: asset,
|
||||||
fit: fit,
|
fit: fit,
|
||||||
|
@ -162,6 +162,7 @@ class _AssetTileWidget extends ConsumerWidget {
|
|||||||
WidgetRef ref,
|
WidgetRef ref,
|
||||||
int assetIndex,
|
int assetIndex,
|
||||||
BaseAsset asset,
|
BaseAsset asset,
|
||||||
|
int? heroOffset,
|
||||||
) async {
|
) async {
|
||||||
final multiSelectState = ref.read(multiSelectProvider);
|
final multiSelectState = ref.read(multiSelectProvider);
|
||||||
|
|
||||||
@ -174,6 +175,7 @@ class _AssetTileWidget extends ConsumerWidget {
|
|||||||
AssetViewerRoute(
|
AssetViewerRoute(
|
||||||
initialIndex: assetIndex,
|
initialIndex: assetIndex,
|
||||||
timelineService: ref.read(timelineServiceProvider),
|
timelineService: ref.read(timelineServiceProvider),
|
||||||
|
heroOffset: heroOffset,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -205,6 +207,8 @@ class _AssetTileWidget 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 lockSelection = _getLockSelectionStatus(ref);
|
final lockSelection = _getLockSelectionStatus(ref);
|
||||||
final showStorageIndicator = ref.watch(
|
final showStorageIndicator = ref.watch(
|
||||||
timelineArgsProvider.select((args) => args.showStorageIndicator),
|
timelineArgsProvider.select((args) => args.showStorageIndicator),
|
||||||
@ -212,12 +216,13 @@ class _AssetTileWidget extends ConsumerWidget {
|
|||||||
|
|
||||||
return RepaintBoundary(
|
return RepaintBoundary(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () => lockSelection ? null : _handleOnTap(context, ref, assetIndex, asset),
|
onTap: () => lockSelection ? null : _handleOnTap(context, ref, assetIndex, asset, heroOffset),
|
||||||
onLongPress: () => lockSelection ? null : _handleOnLongPress(ref, asset),
|
onLongPress: () => lockSelection ? null : _handleOnLongPress(ref, asset),
|
||||||
child: ThumbnailTile(
|
child: ThumbnailTile(
|
||||||
asset,
|
asset,
|
||||||
lockSelection: lockSelection,
|
lockSelection: lockSelection,
|
||||||
showStorageIndicator: showStorageIndicator,
|
showStorageIndicator: showStorageIndicator,
|
||||||
|
heroOffset: heroOffset,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -399,6 +399,7 @@ class AssetViewerRoute extends PageRouteInfo<AssetViewerRouteArgs> {
|
|||||||
Key? key,
|
Key? key,
|
||||||
required int initialIndex,
|
required int initialIndex,
|
||||||
required TimelineService timelineService,
|
required TimelineService timelineService,
|
||||||
|
int? heroOffset,
|
||||||
List<PageRouteInfo>? children,
|
List<PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
AssetViewerRoute.name,
|
AssetViewerRoute.name,
|
||||||
@ -406,6 +407,7 @@ class AssetViewerRoute extends PageRouteInfo<AssetViewerRouteArgs> {
|
|||||||
key: key,
|
key: key,
|
||||||
initialIndex: initialIndex,
|
initialIndex: initialIndex,
|
||||||
timelineService: timelineService,
|
timelineService: timelineService,
|
||||||
|
heroOffset: heroOffset,
|
||||||
),
|
),
|
||||||
initialChildren: children,
|
initialChildren: children,
|
||||||
);
|
);
|
||||||
@ -420,6 +422,7 @@ class AssetViewerRoute extends PageRouteInfo<AssetViewerRouteArgs> {
|
|||||||
key: args.key,
|
key: args.key,
|
||||||
initialIndex: args.initialIndex,
|
initialIndex: args.initialIndex,
|
||||||
timelineService: args.timelineService,
|
timelineService: args.timelineService,
|
||||||
|
heroOffset: args.heroOffset,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -430,6 +433,7 @@ class AssetViewerRouteArgs {
|
|||||||
this.key,
|
this.key,
|
||||||
required this.initialIndex,
|
required this.initialIndex,
|
||||||
required this.timelineService,
|
required this.timelineService,
|
||||||
|
this.heroOffset,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Key? key;
|
final Key? key;
|
||||||
@ -438,9 +442,11 @@ class AssetViewerRouteArgs {
|
|||||||
|
|
||||||
final TimelineService timelineService;
|
final TimelineService timelineService;
|
||||||
|
|
||||||
|
final int? heroOffset;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AssetViewerRouteArgs{key: $key, initialIndex: $initialIndex, timelineService: $timelineService}';
|
return 'AssetViewerRouteArgs{key: $key, initialIndex: $initialIndex, timelineService: $timelineService, heroOffset: $heroOffset}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user