From f73c72973a6f0d9e2f2d500cb1646dad90a1d98a Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Fri, 30 Aug 2019 01:03:36 +0900 Subject: [PATCH] home: added albums/tags items to drawer --- lib/main.dart | 2 + lib/model/image_collection.dart | 9 +- lib/widgets/album/all_collection_drawer.dart | 124 ++++++++++-------- .../album/filtered_collection_page.dart | 1 + lib/widgets/fullscreen/image_page.dart | 2 +- lib/widgets/fullscreen/info/info_page.dart | 10 +- lib/widgets/fullscreen/info/xmp_section.dart | 23 +++- 7 files changed, 111 insertions(+), 60 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index febbf0047..f1c7bc0de 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -64,9 +64,11 @@ class _HomePageState extends State { (entryMap) => localMediaCollection.add(ImageEntry.fromMap(entryMap)), onDone: () async { debugPrint('mediastore stream done'); + localMediaCollection.updateAlbums(); await localMediaCollection.loadCatalogMetadata(); setState(() {}); await localMediaCollection.catalogEntries(); + localMediaCollection.updateTags(); setState(() {}); await localMediaCollection.loadAddresses(); await localMediaCollection.locateEntries(); diff --git a/lib/model/image_collection.dart b/lib/model/image_collection.dart index 4be52b990..aa2e5d166 100644 --- a/lib/model/image_collection.dart +++ b/lib/model/image_collection.dart @@ -9,6 +9,7 @@ class ImageCollection with ChangeNotifier { final List _rawEntries; GroupFactor groupFactor = GroupFactor.date; SortFactor sortFactor = SortFactor.date; + Set albums = Set(), tags = Set(); ImageCollection({ @required List entries, @@ -20,9 +21,9 @@ class ImageCollection with ChangeNotifier { int get videoCount => _rawEntries.where((entry) => entry.isVideo).length; - int get albumCount => 42; + int get albumCount => albums.length; - int get tagCount => 42; + int get tagCount => tags.length; Map> get sections { switch (sortFactor) { @@ -75,6 +76,10 @@ class ImageCollection with ChangeNotifier { return success; } + updateAlbums() => albums = _rawEntries.map((entry) => entry.bucketDisplayName).toSet(); + + updateTags() => tags = _rawEntries.expand((entry) => entry.xmpSubjects).toSet(); + loadCatalogMetadata() async { debugPrint('$runtimeType loadCatalogMetadata start'); final start = DateTime.now(); diff --git a/lib/widgets/album/all_collection_drawer.dart b/lib/widgets/album/all_collection_drawer.dart index 10d9c0ea6..dff5d452c 100644 --- a/lib/widgets/album/all_collection_drawer.dart +++ b/lib/widgets/album/all_collection_drawer.dart @@ -1,6 +1,7 @@ import 'package:aves/model/image_collection.dart'; import 'package:aves/model/image_entry.dart'; import 'package:aves/widgets/album/filtered_collection_page.dart'; +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -11,80 +12,99 @@ class AllCollectionDrawer extends StatelessWidget { @override Widget build(BuildContext context) { + final albums = collection.albums.toList()..sort(compareAsciiUpperCaseNatural); + final tags = collection.tags.toList()..sort(compareAsciiUpperCaseNatural); return Drawer( child: ListView( - padding: EdgeInsets.zero, + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), children: [ DrawerHeader( - child: DefaultTextStyle( - style: TextStyle( - color: Colors.white, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( children: [ - Row( - children: [ - CircleAvatar( - child: Padding( - padding: EdgeInsets.only(top: 6.0), - child: SvgPicture.asset( - 'assets/aves_logo.svg', - width: 50, - ), - ), - backgroundColor: Colors.white, - radius: 32, + CircleAvatar( + child: Padding( + padding: EdgeInsets.only(top: 6.0), + child: SvgPicture.asset( + 'assets/aves_logo.svg', + width: 50, ), - SizedBox(width: 16), - Text('Aves', - style: TextStyle( - fontSize: 42, - )), - ], + ), + backgroundColor: Colors.white, + radius: 32, ), - SizedBox(height: 8), - Row( + SizedBox(width: 16), + Text('Aves', + style: TextStyle( + fontSize: 42, + )), + ], + ), + SizedBox(height: 8), + Row( + children: [ + Container( + width: 72, + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text('${collection.imageCount}'), + Text('${collection.videoCount}'), + Text('${collection.albumCount}'), + Text('${collection.tagCount}'), + ], + ), + ), + SizedBox(width: 8), + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - width: 72, - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text('${collection.imageCount}'), - Text('${collection.videoCount}'), - Text('${collection.albumCount}'), - Text('${collection.tagCount}'), - ], - ), - ), - SizedBox(width: 8), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('images'), - Text('videos'), - Text('albums'), - Text('tags'), - ], - ), + Text('images'), + Text('videos'), + Text('albums'), + Text('tags'), ], ), ], - )), + ), + ], + ), decoration: BoxDecoration( color: Theme.of(context).accentColor, ), ), - _buildFilteredCollectionNavTile(context, 'Videos', (entry) => entry.isVideo), + _buildFilteredCollectionNavTile( + context: context, + leading: Icon(Icons.video_library), + title: 'Videos', + filter: (entry) => entry.isVideo, + ), + Divider(), + ...albums.map((album) => _buildFilteredCollectionNavTile( + context: context, + leading: Icon(Icons.photo_library), + title: album, + filter: (entry) => entry.bucketDisplayName == album, + )), + Divider(), + ...tags.map((tag) => _buildFilteredCollectionNavTile( + context: context, + leading: Icon(Icons.label_outline), + title: tag, + filter: (entry) => entry.xmpSubjects.contains(tag), + )), ], ), ); } - _buildFilteredCollectionNavTile(BuildContext context, String title, bool Function(ImageEntry) filter) { + _buildFilteredCollectionNavTile({BuildContext context, Widget leading, String title, bool Function(ImageEntry) filter}) { return ListTile( + leading: leading, title: Text(title), + dense: true, onTap: () { Navigator.pop(context); Navigator.push( diff --git a/lib/widgets/album/filtered_collection_page.dart b/lib/widgets/album/filtered_collection_page.dart index 6b5d3b6e9..5c67770ed 100644 --- a/lib/widgets/album/filtered_collection_page.dart +++ b/lib/widgets/album/filtered_collection_page.dart @@ -22,6 +22,7 @@ class FilteredCollectionPage extends StatelessWidget { floating: true, ), ), + resizeToAvoidBottomInset: false, ); } } diff --git a/lib/widgets/fullscreen/image_page.dart b/lib/widgets/fullscreen/image_page.dart index df0f8e768..374c9110c 100644 --- a/lib/widgets/fullscreen/image_page.dart +++ b/lib/widgets/fullscreen/image_page.dart @@ -163,7 +163,7 @@ class FullscreenBodyState extends State with SingleTickerProvide if (notification is BackUpNotification) goToVerticalPage(0); return false; }, - child: InfoPage(entry: entry), + child: InfoPage(collection: collection, entry: entry), ), ], ), diff --git a/lib/widgets/fullscreen/info/info_page.dart b/lib/widgets/fullscreen/info/info_page.dart index a40aaee88..f34833267 100644 --- a/lib/widgets/fullscreen/info/info_page.dart +++ b/lib/widgets/fullscreen/info/info_page.dart @@ -1,3 +1,4 @@ +import 'package:aves/model/image_collection.dart'; import 'package:aves/model/image_entry.dart'; import 'package:aves/utils/file_utils.dart'; import 'package:aves/widgets/fullscreen/info/location_section.dart'; @@ -7,9 +8,14 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; class InfoPage extends StatefulWidget { + final ImageCollection collection; final ImageEntry entry; - const InfoPage({this.entry}); + const InfoPage({ + Key key, + @required this.collection, + @required this.entry, + }) : super(key: key); @override State createState() => InfoPageState(); @@ -52,7 +58,7 @@ class InfoPageState extends State { InfoRow('Size', formatFilesize(entry.sizeBytes)), InfoRow('Path', entry.path), LocationSection(entry: entry), - XmpTagSection(entry: entry), + XmpTagSection(collection: widget.collection, entry: entry), MetadataSection(entry: entry), ], ), diff --git a/lib/widgets/fullscreen/info/xmp_section.dart b/lib/widgets/fullscreen/info/xmp_section.dart index a1523f973..7f19ee80e 100644 --- a/lib/widgets/fullscreen/info/xmp_section.dart +++ b/lib/widgets/fullscreen/info/xmp_section.dart @@ -1,11 +1,18 @@ +import 'package:aves/model/image_collection.dart'; import 'package:aves/model/image_entry.dart'; +import 'package:aves/widgets/album/filtered_collection_page.dart'; import 'package:aves/widgets/fullscreen/info/info_page.dart'; import 'package:flutter/material.dart'; class XmpTagSection extends AnimatedWidget { + final ImageCollection collection; final ImageEntry entry; - const XmpTagSection({Key key, this.entry}) : super(key: key, listenable: entry); + const XmpTagSection({ + Key key, + @required this.collection, + @required this.entry, + }) : super(key: key, listenable: entry); @override Widget build(BuildContext context) { @@ -20,9 +27,19 @@ class XmpTagSection extends AnimatedWidget { children: tags .map((tag) => Padding( padding: EdgeInsets.symmetric(horizontal: 4.0), - child: Chip( - backgroundColor: Theme.of(context).accentColor, + child: ActionChip( label: Text(tag), + onPressed: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FilteredCollectionPage( + collection: collection, + filter: (entry) => entry.xmpSubjects.contains(tag), + title: tag, + ), + ), + ), + backgroundColor: Theme.of(context).accentColor, ), )) .toList(),