import 'package:aves/main.dart'; import 'package:aves/model/image_entry.dart'; import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/services/viewer_service.dart'; import 'package:aves/widgets/collection/grid/list_known_extent.dart'; import 'package:aves/widgets/collection/grid/list_section_layout.dart'; import 'package:aves/widgets/common/scaling.dart'; import 'package:aves/widgets/collection/thumbnail/decorated.dart'; import 'package:aves/widgets/common/behaviour/routes.dart'; import 'package:aves/widgets/fullscreen/fullscreen_page.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; // Use a `SliverList` instead of multiple `SliverGrid` because having one `SliverGrid` per section does not scale up. // With the multiple `SliverGrid` solution, thumbnails at the beginning of each sections are built even though they are offscreen // because of `RenderSliverMultiBoxAdaptor.addInitialChild` called by `RenderSliverGrid.performLayout` (line 547), as of Flutter v1.17.0. class CollectionListSliver extends StatelessWidget { const CollectionListSliver(); @override Widget build(BuildContext context) { final sectionLayouts = Provider.of(context).sectionLayouts; final childCount = sectionLayouts.isEmpty ? 0 : sectionLayouts.last.lastIndex + 1; return SliverKnownExtentList( sectionLayouts: sectionLayouts, delegate: SliverChildBuilderDelegate( (context, index) { if (index >= childCount) return null; final sectionLayout = sectionLayouts.firstWhere((section) => section.hasChild(index), orElse: () => null); return sectionLayout?.builder(context, index) ?? SizedBox.shrink(); }, childCount: childCount, addAutomaticKeepAlives: false, ), ); } } class GridThumbnail extends StatelessWidget { final CollectionLens collection; final ImageEntry entry; final double tileExtent; final ValueNotifier isScrollingNotifier; const GridThumbnail({ Key key, this.collection, @required this.entry, @required this.tileExtent, this.isScrollingNotifier, }) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( key: ValueKey(entry.uri), onTap: () { if (AvesApp.mode == AppMode.main) { if (collection.isBrowsing) { _goToFullscreen(context); } else if (collection.isSelecting) { collection.toggleSelection(entry); } } else if (AvesApp.mode == AppMode.pick) { ViewerService.pick(entry.uri); } }, onLongPress: () { if (AvesApp.mode == AppMode.main) { collection.toggleSelection(entry); } }, child: MetaData( metaData: ScalerMetadata(entry), child: DecoratedThumbnail( entry: entry, extent: tileExtent, collection: collection, isScrollingNotifier: isScrollingNotifier, ), ), ); } void _goToFullscreen(BuildContext context) { Navigator.push( context, TransparentMaterialPageRoute( settings: RouteSettings(name: MultiFullscreenPage.routeName), pageBuilder: (c, a, sa) => MultiFullscreenPage( collection: collection, initialEntry: entry, ), ), ); } }