mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-03-23 07:29:23 +01:00
Reenable hero using the thumbnail
This commit is contained in:
parent
9ab9f11fb5
commit
1fc9de5af2
3 changed files with 130 additions and 24 deletions
|
@ -19,3 +19,44 @@ class CustomizableMaterialPageRoute extends MaterialPageRoute {
|
||||||
}
|
}
|
||||||
|
|
||||||
String getImageHeroTag(FileDescriptor file) => "imageHero(${file.fdPath})";
|
String getImageHeroTag(FileDescriptor file) => "imageHero(${file.fdPath})";
|
||||||
|
|
||||||
|
// copied from flutter
|
||||||
|
Widget defaultHeroFlightShuttleBuilder(
|
||||||
|
BuildContext flightContext,
|
||||||
|
Animation<double> animation,
|
||||||
|
HeroFlightDirection flightDirection,
|
||||||
|
BuildContext fromHeroContext,
|
||||||
|
BuildContext toHeroContext,
|
||||||
|
) {
|
||||||
|
final Hero toHero = toHeroContext.widget as Hero;
|
||||||
|
|
||||||
|
final MediaQueryData? toMediaQueryData = MediaQuery.maybeOf(toHeroContext);
|
||||||
|
final MediaQueryData? fromMediaQueryData =
|
||||||
|
MediaQuery.maybeOf(fromHeroContext);
|
||||||
|
|
||||||
|
if (toMediaQueryData == null || fromMediaQueryData == null) {
|
||||||
|
return toHero.child;
|
||||||
|
}
|
||||||
|
|
||||||
|
final EdgeInsets fromHeroPadding = fromMediaQueryData.padding;
|
||||||
|
final EdgeInsets toHeroPadding = toMediaQueryData.padding;
|
||||||
|
|
||||||
|
return AnimatedBuilder(
|
||||||
|
animation: animation,
|
||||||
|
builder: (BuildContext context, Widget? child) {
|
||||||
|
return MediaQuery(
|
||||||
|
data: toMediaQueryData.copyWith(
|
||||||
|
padding: (flightDirection == HeroFlightDirection.push)
|
||||||
|
? EdgeInsetsTween(
|
||||||
|
begin: fromHeroPadding,
|
||||||
|
end: toHeroPadding,
|
||||||
|
).evaluate(animation)
|
||||||
|
: EdgeInsetsTween(
|
||||||
|
begin: toHeroPadding,
|
||||||
|
end: fromHeroPadding,
|
||||||
|
).evaluate(animation),
|
||||||
|
),
|
||||||
|
child: toHero.child);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
@ -8,9 +9,11 @@ import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/cache_manager_util.dart';
|
import 'package:nc_photos/cache_manager_util.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/entity/local_file.dart';
|
import 'package:nc_photos/entity/local_file.dart';
|
||||||
|
import 'package:nc_photos/flutter_util.dart' as flutter_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/mobile/android/content_uri_image_provider.dart';
|
import 'package:nc_photos/mobile/android/content_uri_image_provider.dart';
|
||||||
import 'package:nc_photos/widget/cached_network_image_mod.dart' as mod;
|
import 'package:nc_photos/widget/cached_network_image_mod.dart' as mod;
|
||||||
|
import 'package:nc_photos/widget/network_thumbnail.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
|
||||||
part 'image_viewer.g.dart';
|
part 'image_viewer.g.dart';
|
||||||
|
@ -113,16 +116,61 @@ class RemoteImageViewer extends StatefulWidget {
|
||||||
@npLog
|
@npLog
|
||||||
class _RemoteImageViewerState extends State<RemoteImageViewer> {
|
class _RemoteImageViewerState extends State<RemoteImageViewer> {
|
||||||
@override
|
@override
|
||||||
build(BuildContext context) => _ImageViewer(
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (mounted) {
|
||||||
|
// needed to get rid of the large image blinking during Hero animation
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return _ImageViewer(
|
||||||
canZoom: widget.canZoom,
|
canZoom: widget.canZoom,
|
||||||
onHeightChanged: widget.onHeightChanged,
|
onHeightChanged: widget.onHeightChanged,
|
||||||
onZoomStarted: widget.onZoomStarted,
|
onZoomStarted: widget.onZoomStarted,
|
||||||
onZoomEnded: widget.onZoomEnded,
|
onZoomEnded: widget.onZoomEnded,
|
||||||
child: mod.CachedNetworkImage(
|
child: Stack(
|
||||||
|
fit: StackFit.passthrough,
|
||||||
|
children: [
|
||||||
|
Hero(
|
||||||
|
tag: flutter_util.getImageHeroTag(widget.file),
|
||||||
|
flightShuttleBuilder: (flightContext, animation, flightDirection,
|
||||||
|
fromHeroContext, toHeroContext) {
|
||||||
|
_isHeroDone = false;
|
||||||
|
animation.addStatusListener(_animationListener);
|
||||||
|
return flutter_util.defaultHeroFlightShuttleBuilder(
|
||||||
|
flightContext,
|
||||||
|
animation,
|
||||||
|
flightDirection,
|
||||||
|
fromHeroContext,
|
||||||
|
toHeroContext,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
cacheManager: ThumbnailCacheManager.inst,
|
||||||
|
imageUrl: NetworkRectThumbnail.imageUrlForFile(
|
||||||
|
widget.account, widget.file),
|
||||||
|
httpHeaders: {
|
||||||
|
"Authorization":
|
||||||
|
Api.getAuthorizationHeaderValue(widget.account),
|
||||||
|
},
|
||||||
|
fadeInDuration: const Duration(),
|
||||||
|
filterQuality: FilterQuality.high,
|
||||||
|
imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (_isHeroDone)
|
||||||
|
mod.CachedNetworkImage(
|
||||||
cacheManager: LargeImageCacheManager.inst,
|
cacheManager: LargeImageCacheManager.inst,
|
||||||
imageUrl: _getImageUrl(widget.account, widget.file),
|
imageUrl: _getImageUrl(widget.account, widget.file),
|
||||||
httpHeaders: {
|
httpHeaders: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
"Authorization":
|
||||||
|
Api.getAuthorizationHeaderValue(widget.account),
|
||||||
},
|
},
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
fadeInDuration: const Duration(),
|
fadeInDuration: const Duration(),
|
||||||
|
@ -136,7 +184,10 @@ class _RemoteImageViewerState extends State<RemoteImageViewer> {
|
||||||
return child;
|
return child;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void _onItemLoaded() {
|
void _onItemLoaded() {
|
||||||
if (!_isLoaded) {
|
if (!_isLoaded) {
|
||||||
|
@ -146,7 +197,19 @@ class _RemoteImageViewerState extends State<RemoteImageViewer> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _animationListener(AnimationStatus status) {
|
||||||
|
if (status == AnimationStatus.completed) {
|
||||||
|
_isHeroDone = true;
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var _isLoaded = false;
|
var _isLoaded = false;
|
||||||
|
// initially set to true such that the large image will show when hero didn't
|
||||||
|
// run (i.e., when swiping in viewer)
|
||||||
|
var _isHeroDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ImageViewer extends StatefulWidget {
|
class _ImageViewer extends StatefulWidget {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/entity/local_file.dart';
|
import 'package:nc_photos/entity/local_file.dart';
|
||||||
|
import 'package:nc_photos/flutter_util.dart' as flutter_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/mobile/android/content_uri_image_provider.dart';
|
import 'package:nc_photos/mobile/android/content_uri_image_provider.dart';
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
|
@ -63,6 +64,7 @@ class PhotoListImageItem extends PhotoListFileItem {
|
||||||
previewUrl: previewUrl,
|
previewUrl: previewUrl,
|
||||||
isGif: file.fdMime == "image/gif",
|
isGif: file.fdMime == "image/gif",
|
||||||
isFavorite: shouldShowFavoriteBadge && file.fdIsFavorite == true,
|
isFavorite: shouldShowFavoriteBadge && file.fdIsFavorite == true,
|
||||||
|
heroKey: flutter_util.getImageHeroTag(file),
|
||||||
);
|
);
|
||||||
|
|
||||||
final Account account;
|
final Account account;
|
||||||
|
|
Loading…
Reference in a new issue