diff --git a/lib/widgets/album/collection_drawer.dart b/lib/widgets/album/collection_drawer.dart index 654ee80cf..168b74386 100644 --- a/lib/widgets/album/collection_drawer.dart +++ b/lib/widgets/album/collection_drawer.dart @@ -74,12 +74,6 @@ class _CollectionDrawerState extends State { title: 'All media', filter: null, ); - final imageEntry = _FilteredCollectionNavTile( - source: source, - leading: const Icon(AIcons.image), - title: 'Images', - filter: MimeFilter(MimeTypes.ANY_IMAGE), - ); final videoEntry = _FilteredCollectionNavTile( source: source, leading: const Icon(AIcons.video), @@ -92,182 +86,17 @@ class _CollectionDrawerState extends State { title: 'Favourites', filter: FavouriteFilter(), ); - final buildAlbumEntry = (String album) { - final uniqueName = source.getUniqueAlbumName(album); - return _FilteredCollectionNavTile( - source: source, - leading: IconUtils.getAlbumIcon(context: context, album: album), - title: uniqueName, - trailing: androidFileUtils.isOnRemovableStorage(album) - ? const Icon( - AIcons.removableStorage, - size: 16, - color: Colors.grey, - ) - : null, - dense: true, - filter: AlbumFilter(album, uniqueName), - ); - }; - final buildTagEntry = (String tag) => _FilteredCollectionNavTile( - source: source, - leading: Icon( - AIcons.tag, - color: stringToColor(tag), - ), - title: tag, - dense: true, - filter: TagFilter(tag), - ); - final buildLocationEntry = (LocationLevel level, String location) { - String title; - String flag; - if (level == LocationLevel.country) { - final split = location.split(';'); - String countryCode; - if (split.isNotEmpty) title = split[0]; - if (split.length > 1) countryCode = split[1]; - flag = LocationFilter.countryCodeToFlag(countryCode); - } else { - title = location; - } - return _FilteredCollectionNavTile( - source: source, - leading: flag != null - ? Text( - flag, - style: TextStyle(fontSize: IconTheme.of(context).size), - ) - : Icon( - AIcons.location, - color: stringToColor(title), - ), - title: title, - dense: true, - filter: LocationFilter(level, location), - ); - }; - - final regularAlbums = [], appAlbums = [], specialAlbums = []; - for (var album in source.sortedAlbums) { - switch (androidFileUtils.getAlbumType(album)) { - case AlbumType.Default: - regularAlbums.add(album); - break; - case AlbumType.App: - appAlbums.add(album); - break; - default: - specialAlbums.add(album); - break; - } - } - final countries = source.sortedCountries; - final places = source.sortedPlaces; - final tags = source.sortedTags; final drawerItems = [ header, allMediaEntry, - imageEntry, videoEntry, favouriteEntry, - if (specialAlbums.isNotEmpty) ...[ - const Divider(), - ...specialAlbums.map(buildAlbumEntry), - ], - if (appAlbums.isNotEmpty || regularAlbums.isNotEmpty) - SafeArea( - top: false, - bottom: false, - child: ExpansionTile( - leading: const Icon(AIcons.album), - title: Row( - children: [ - const Text('Albums'), - const Spacer(), - Text( - '${appAlbums.length + regularAlbums.length}', - style: TextStyle( - color: (_albumsExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6), - ), - ), - ], - ), - onExpansionChanged: (expanded) => setState(() => _albumsExpanded = expanded), - children: [ - ...appAlbums.map(buildAlbumEntry), - if (appAlbums.isNotEmpty && regularAlbums.isNotEmpty) const Divider(), - ...regularAlbums.map(buildAlbumEntry), - ], - ), - ), - if (countries.isNotEmpty) - SafeArea( - top: false, - bottom: false, - child: ExpansionTile( - leading: const Icon(AIcons.location), - title: Row( - children: [ - const Text('Countries'), - const Spacer(), - Text( - '${countries.length}', - style: TextStyle( - color: (_countriesExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6), - ), - ), - ], - ), - onExpansionChanged: (expanded) => setState(() => _countriesExpanded = expanded), - children: countries.map((s) => buildLocationEntry(LocationLevel.country, s)).toList(), - ), - ), - if (places.isNotEmpty) - SafeArea( - top: false, - bottom: false, - child: ExpansionTile( - leading: const Icon(AIcons.location), - title: Row( - children: [ - const Text('Places'), - const Spacer(), - Text( - '${places.length}', - style: TextStyle( - color: (_placesExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6), - ), - ), - ], - ), - onExpansionChanged: (expanded) => setState(() => _placesExpanded = expanded), - children: places.map((s) => buildLocationEntry(LocationLevel.place, s)).toList(), - ), - ), - if (tags.isNotEmpty) - SafeArea( - top: false, - bottom: false, - child: ExpansionTile( - leading: const Icon(AIcons.tag), - title: Row( - children: [ - const Text('Tags'), - const Spacer(), - Text( - '${tags.length}', - style: TextStyle( - color: (_tagsExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6), - ), - ), - ], - ), - onExpansionChanged: (expanded) => setState(() => _tagsExpanded = expanded), - children: tags.map(buildTagEntry).toList(), - ), - ), + _buildSpecialAlbumSection(), + _buildRegularAlbumSection(), + _buildCountrySection(), + _buildPlaceSection(), + _buildTagSection(), if (kDebugMode) ...[ const Divider(), SafeArea( @@ -303,6 +132,219 @@ class _CollectionDrawerState extends State { ); } + Widget _buildAlbumEntry(String album, {bool dense = true}) { + final uniqueName = source.getUniqueAlbumName(album); + return _FilteredCollectionNavTile( + source: source, + leading: IconUtils.getAlbumIcon(context: context, album: album), + title: uniqueName, + trailing: androidFileUtils.isOnRemovableStorage(album) + ? const Icon( + AIcons.removableStorage, + size: 16, + color: Colors.grey, + ) + : null, + dense: dense, + filter: AlbumFilter(album, uniqueName), + ); + } + + Widget _buildLocationEntry(LocationLevel level, String location) { + String title; + String flag; + if (level == LocationLevel.country) { + final split = location.split(';'); + String countryCode; + if (split.isNotEmpty) title = split[0]; + if (split.length > 1) countryCode = split[1]; + flag = LocationFilter.countryCodeToFlag(countryCode); + } else { + title = location; + } + return _FilteredCollectionNavTile( + source: source, + leading: flag != null + ? Text( + flag, + style: TextStyle(fontSize: IconTheme.of(context).size), + ) + : Icon( + AIcons.location, + color: stringToColor(title), + ), + title: title, + dense: true, + filter: LocationFilter(level, location), + ); + } + + Widget _buildTagEntry(String tag) => _FilteredCollectionNavTile( + source: source, + leading: Icon( + AIcons.tag, + color: stringToColor(tag), + ), + title: tag, + dense: true, + filter: TagFilter(tag), + ); + + Widget _buildSpecialAlbumSection() { + return StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) { + final specialAlbums = source.sortedAlbums.where((album) { + final type = androidFileUtils.getAlbumType(album); + return type != AlbumType.Default && type != AlbumType.App; + }); + + if (specialAlbums.isEmpty) return const SizedBox.shrink(); + return Column( + children: [ + const Divider(), + ...specialAlbums.map((album) => _buildAlbumEntry(album, dense: false)), + ], + ); + }); + } + + Widget _buildRegularAlbumSection() { + return StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) { + final regularAlbums = [], appAlbums = []; + for (var album in source.sortedAlbums) { + switch (androidFileUtils.getAlbumType(album)) { + case AlbumType.Default: + regularAlbums.add(album); + break; + case AlbumType.App: + appAlbums.add(album); + break; + default: + break; + } + } + if (appAlbums.isEmpty && regularAlbums.isEmpty) return const SizedBox.shrink(); + return SafeArea( + top: false, + bottom: false, + child: ExpansionTile( + leading: const Icon(AIcons.album), + title: Row( + children: [ + const Text('Albums'), + const Spacer(), + Text( + '${appAlbums.length + regularAlbums.length}', + style: TextStyle( + color: (_albumsExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6), + ), + ), + ], + ), + onExpansionChanged: (expanded) => setState(() => _albumsExpanded = expanded), + children: [ + ...appAlbums.map(_buildAlbumEntry), + if (appAlbums.isNotEmpty && regularAlbums.isNotEmpty) const Divider(), + ...regularAlbums.map(_buildAlbumEntry), + ], + ), + ); + }); + } + + Widget _buildCountrySection() { + return StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) { + final countries = source.sortedCountries; + if (countries.isEmpty) return const SizedBox.shrink(); + return SafeArea( + top: false, + bottom: false, + child: ExpansionTile( + leading: const Icon(AIcons.location), + title: Row( + children: [ + const Text('Countries'), + const Spacer(), + Text( + '${countries.length}', + style: TextStyle( + color: (_countriesExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6), + ), + ), + ], + ), + onExpansionChanged: (expanded) => setState(() => _countriesExpanded = expanded), + children: countries.map((s) => _buildLocationEntry(LocationLevel.country, s)).toList(), + ), + ); + }); + } + + Widget _buildPlaceSection() { + return StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) { + final places = source.sortedPlaces; + if (places.isEmpty) return const SizedBox.shrink(); + return SafeArea( + top: false, + bottom: false, + child: ExpansionTile( + leading: const Icon(AIcons.location), + title: Row( + children: [ + const Text('Places'), + const Spacer(), + Text( + '${places.length}', + style: TextStyle( + color: (_placesExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6), + ), + ), + ], + ), + onExpansionChanged: (expanded) => setState(() => _placesExpanded = expanded), + children: places.map((s) => _buildLocationEntry(LocationLevel.place, s)).toList(), + ), + ); + }); + } + + Widget _buildTagSection() { + return StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) { + final tags = source.sortedTags; + if (tags.isEmpty) return const SizedBox.shrink(); + return SafeArea( + top: false, + bottom: false, + child: ExpansionTile( + leading: const Icon(AIcons.tag), + title: Row( + children: [ + const Text('Tags'), + const Spacer(), + Text( + '${tags.length}', + style: TextStyle( + color: (_tagsExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6), + ), + ), + ], + ), + onExpansionChanged: (expanded) => setState(() => _tagsExpanded = expanded), + children: tags.map(_buildTagEntry).toList(), + ), + ); + }); + } + void _goToDebug(BuildContext context) { Navigator.pop(context); Navigator.push(