collection: prevent hero when navigating from drawer
This commit is contained in:
parent
104373a186
commit
accfb2c57b
8 changed files with 37 additions and 21 deletions
|
@ -21,6 +21,7 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel
|
|||
EntryGroupFactor groupFactor;
|
||||
EntrySortFactor sortFactor;
|
||||
final AChangeNotifier filterChangeNotifier = AChangeNotifier();
|
||||
int id;
|
||||
bool listenToSource;
|
||||
|
||||
List<AvesEntry> _filteredEntries;
|
||||
|
@ -33,10 +34,12 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel
|
|||
Iterable<CollectionFilter> filters,
|
||||
@required EntryGroupFactor groupFactor,
|
||||
@required EntrySortFactor sortFactor,
|
||||
this.id,
|
||||
this.listenToSource = true,
|
||||
}) : filters = {if (filters != null) ...filters.where((f) => f != null)},
|
||||
groupFactor = groupFactor ?? EntryGroupFactor.month,
|
||||
sortFactor = sortFactor ?? EntrySortFactor.date {
|
||||
id ??= hashCode;
|
||||
if (listenToSource) {
|
||||
_subscriptions.add(source.eventBus.on<EntryAddedEvent>().listen((e) => _refresh()));
|
||||
_subscriptions.add(source.eventBus.on<EntryRemovedEvent>().listen((e) => onEntryRemoved(e.entries)));
|
||||
|
|
|
@ -54,16 +54,20 @@ class InteractiveThumbnail extends StatelessWidget {
|
|||
context,
|
||||
TransparentMaterialPageRoute(
|
||||
settings: RouteSettings(name: EntryViewerPage.routeName),
|
||||
pageBuilder: (c, a, sa) => EntryViewerPage(
|
||||
collection: CollectionLens(
|
||||
pageBuilder: (c, a, sa) {
|
||||
final viewerCollection = CollectionLens(
|
||||
source: collection.source,
|
||||
filters: collection.filters,
|
||||
groupFactor: collection.groupFactor,
|
||||
sortFactor: collection.sortFactor,
|
||||
id: collection.id,
|
||||
listenToSource: false,
|
||||
),
|
||||
initialEntry: entry,
|
||||
),
|
||||
);
|
||||
return EntryViewerPage(
|
||||
collection: viewerCollection,
|
||||
initialEntry: entry,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,17 +27,21 @@ class DecoratedThumbnail extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// hero tag should include a collection identifier, so that it animates
|
||||
// between different views of the entry in the same collection (e.g. thumbnails <-> viewer)
|
||||
// but not between different collection instances, even with the same attributes (e.g. reloading collection page via drawer)
|
||||
final heroTag = hashValues(collection?.id, entry);
|
||||
var child = entry.isSvg
|
||||
? VectorImageThumbnail(
|
||||
entry: entry,
|
||||
extent: extent,
|
||||
canHero: true,
|
||||
heroTag: heroTag,
|
||||
)
|
||||
: RasterImageThumbnail(
|
||||
entry: entry,
|
||||
extent: extent,
|
||||
isScrollingNotifier: isScrollingNotifier,
|
||||
canHero: true,
|
||||
heroTag: heroTag,
|
||||
);
|
||||
|
||||
child = Stack(
|
||||
|
|
|
@ -10,14 +10,14 @@ class RasterImageThumbnail extends StatefulWidget {
|
|||
final AvesEntry entry;
|
||||
final double extent;
|
||||
final ValueNotifier<bool> isScrollingNotifier;
|
||||
final bool canHero;
|
||||
final Object heroTag;
|
||||
|
||||
const RasterImageThumbnail({
|
||||
Key key,
|
||||
@required this.entry,
|
||||
@required this.extent,
|
||||
this.isScrollingNotifier,
|
||||
this.canHero = false,
|
||||
this.heroTag,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -124,9 +124,9 @@ class _RasterImageThumbnailState extends State<RasterImageThumbnail> {
|
|||
height: extent,
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
return widget.canHero
|
||||
return widget.heroTag != null
|
||||
? Hero(
|
||||
tag: entry,
|
||||
tag: widget.heroTag,
|
||||
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) {
|
||||
return TransitionImage(
|
||||
image: entry.getBestThumbnail(extent),
|
||||
|
|
|
@ -10,13 +10,13 @@ import 'package:provider/provider.dart';
|
|||
class VectorImageThumbnail extends StatelessWidget {
|
||||
final AvesEntry entry;
|
||||
final double extent;
|
||||
final bool canHero;
|
||||
final Object heroTag;
|
||||
|
||||
const VectorImageThumbnail({
|
||||
Key key,
|
||||
@required this.entry,
|
||||
@required this.extent,
|
||||
this.canHero = false,
|
||||
this.heroTag,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -63,9 +63,9 @@ class VectorImageThumbnail extends StatelessWidget {
|
|||
);
|
||||
},
|
||||
);
|
||||
return canHero
|
||||
return heroTag != null
|
||||
? Hero(
|
||||
tag: entry,
|
||||
tag: heroTag,
|
||||
transitionOnUserGestures: true,
|
||||
child: child,
|
||||
)
|
||||
|
|
|
@ -77,7 +77,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
|
|||
super.initState();
|
||||
final entry = widget.initialEntry;
|
||||
// opening hero, with viewer as target
|
||||
_heroInfoNotifier.value = HeroInfo(entry);
|
||||
_heroInfoNotifier.value = HeroInfo(collection?.id, entry);
|
||||
_entryNotifier.value = entry;
|
||||
_currentHorizontalPage = max(0, entries.indexOf(entry));
|
||||
_currentVerticalPage = ValueNotifier(imagePage);
|
||||
|
@ -421,7 +421,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
|
|||
}
|
||||
|
||||
// closing hero, with viewer as source
|
||||
final heroInfo = HeroInfo(_entryNotifier.value);
|
||||
final heroInfo = HeroInfo(collection?.id, _entryNotifier.value);
|
||||
if (_heroInfoNotifier.value != heroInfo) {
|
||||
_heroInfoNotifier.value = heroInfo;
|
||||
// we post closing the viewer page so that hero animation source is ready
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
import 'package:aves/model/entry.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class HeroInfo {
|
||||
// hero tag should include a collection identifier, so that it animates
|
||||
// between different views of the entry in the same collection (e.g. thumbnails <-> viewer)
|
||||
// but not between different collection instances, even with the same attributes (e.g. reloading collection page via drawer)
|
||||
final int collectionId;
|
||||
final AvesEntry entry;
|
||||
|
||||
const HeroInfo(this.entry);
|
||||
const HeroInfo(this.collectionId, this.entry);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType) return false;
|
||||
return other is HeroInfo && other.entry == entry;
|
||||
return other is HeroInfo && other.collectionId == collectionId && other.entry == entry;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => entry.hashCode;
|
||||
int get hashCode => hashValues(collectionId, entry);
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ class _EntryPageViewState extends State<EntryPageView> {
|
|||
|
||||
return Consumer<HeroInfo>(
|
||||
builder: (context, info, child) => Hero(
|
||||
tag: info?.entry == mainEntry ? mainEntry : hashCode,
|
||||
tag: info?.entry == mainEntry ? hashValues(info.collectionId, mainEntry) : hashCode,
|
||||
transitionOnUserGestures: true,
|
||||
child: child,
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue