From eb6c9969f7c7474362d165f9c356f294ddd2bdea Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Tue, 27 Sep 2022 11:39:15 +0200 Subject: [PATCH] albums: group by content type --- CHANGELOG.md | 1 + lib/l10n/app_en.arb | 3 + lib/model/source/enums/enums.dart | 2 +- lib/model/source/enums/view.dart | 4 ++ lib/theme/icons.dart | 1 + lib/widgets/filter_grids/albums_page.dart | 11 ++++ .../common/action_delegates/album_set.dart | 1 + lib/widgets/filter_grids/common/enums.dart | 63 +++++++++++++++++++ .../filter_grids/common/section_keys.dart | 42 ++++--------- untranslated.json | 26 ++++++++ 10 files changed, 123 insertions(+), 31 deletions(-) create mode 100644 lib/widgets/filter_grids/common/enums.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index f69b2590e..c732b6460 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Added - mosaic layout +- Albums: group by content type - Slideshow: option for no transition - Widget: tap action setting diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 5c397e410..f489120dc 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -586,9 +586,12 @@ "sortOrderSmallestFirst": "Smallest first", "albumGroupTier": "By tier", + "albumGroupType": "By type", "albumGroupVolume": "By storage volume", "albumGroupNone": "Do not group", + "albumMimeTypeMixed": "Mixed", + "albumPickPageTitleCopy": "Copy to Album", "albumPickPageTitleExport": "Export to Album", "albumPickPageTitleMove": "Move to Album", diff --git a/lib/model/source/enums/enums.dart b/lib/model/source/enums/enums.dart index 0ad4b5b2f..de1b1faef 100644 --- a/lib/model/source/enums/enums.dart +++ b/lib/model/source/enums/enums.dart @@ -2,7 +2,7 @@ enum SourceState { loading, cataloguing, locatingCountries, locatingPlaces, read enum ChipSortFactor { date, name, count, size } -enum AlbumChipGroupFactor { none, importance, volume } +enum AlbumChipGroupFactor { none, importance, mimeType, volume } enum EntrySortFactor { date, name, rating, size } diff --git a/lib/model/source/enums/view.dart b/lib/model/source/enums/view.dart index 5ed3c8a13..aab4397f7 100644 --- a/lib/model/source/enums/view.dart +++ b/lib/model/source/enums/view.dart @@ -124,6 +124,8 @@ extension ExtraAlbumChipGroupFactor on AlbumChipGroupFactor { switch (this) { case AlbumChipGroupFactor.importance: return l10n.albumGroupTier; + case AlbumChipGroupFactor.mimeType: + return l10n.albumGroupType; case AlbumChipGroupFactor.volume: return l10n.albumGroupVolume; case AlbumChipGroupFactor.none: @@ -135,6 +137,8 @@ extension ExtraAlbumChipGroupFactor on AlbumChipGroupFactor { switch (this) { case AlbumChipGroupFactor.importance: return AIcons.important; + case AlbumChipGroupFactor.mimeType: + return AIcons.mimeType; case AlbumChipGroupFactor.volume: return AIcons.removableStorage; case AlbumChipGroupFactor.none: diff --git a/lib/theme/icons.dart b/lib/theme/icons.dart index 7246282ee..a1c6e59bf 100644 --- a/lib/theme/icons.dart +++ b/lib/theme/icons.dart @@ -34,6 +34,7 @@ class AIcons { static const IconData location = Icons.place_outlined; static const IconData locationUnlocated = Icons.location_off_outlined; static const IconData mainStorage = Icons.smartphone_outlined; + static const IconData mimeType = Icons.code_outlined; static const IconData opacity = Icons.opacity; static const IconData privacy = MdiIcons.shieldAccountOutline; static const IconData rating = Icons.star_border_outlined; diff --git a/lib/widgets/filter_grids/albums_page.dart b/lib/widgets/filter_grids/albums_page.dart index 39160aee4..eade6bd8f 100644 --- a/lib/widgets/filter_grids/albums_page.dart +++ b/lib/widgets/filter_grids/albums_page.dart @@ -118,6 +118,17 @@ class AlbumListPage extends StatelessWidget { if (sections.containsKey(regularKey)) regularKey: sections[regularKey]!, }; break; + case AlbumChipGroupFactor.mimeType: + final visibleEntries = source.visibleEntries; + sections = groupBy, ChipSectionKey>(unpinnedMapEntries, (kv) { + final matches = visibleEntries.where(kv.filter.test); + final hasImage = matches.any((v) => v.isImage); + final hasVideo = matches.any((v) => v.isVideo); + if (hasImage && !hasVideo) return MimeTypeSectionKey.images(context); + if (!hasImage && hasVideo) return MimeTypeSectionKey.videos(context); + return MimeTypeSectionKey.mixed(context); + }); + break; case AlbumChipGroupFactor.volume: sections = groupBy, ChipSectionKey>(unpinnedMapEntries, (kv) { return StorageVolumeSectionKey(context, androidFileUtils.getStorageVolume(kv.filter.album)); diff --git a/lib/widgets/filter_grids/common/action_delegates/album_set.dart b/lib/widgets/filter_grids/common/action_delegates/album_set.dart index 427978119..7854c88f3 100644 --- a/lib/widgets/filter_grids/common/action_delegates/album_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/album_set.dart @@ -59,6 +59,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with static const _groupOptions = [ AlbumChipGroupFactor.importance, + AlbumChipGroupFactor.mimeType, AlbumChipGroupFactor.volume, AlbumChipGroupFactor.none, ]; diff --git a/lib/widgets/filter_grids/common/enums.dart b/lib/widgets/filter_grids/common/enums.dart new file mode 100644 index 000000000..dca3f4a68 --- /dev/null +++ b/lib/widgets/filter_grids/common/enums.dart @@ -0,0 +1,63 @@ +import 'package:aves/theme/icons.dart'; +import 'package:aves/widgets/common/extensions/build_context.dart'; +import 'package:flutter/material.dart'; + +enum AlbumImportance { newAlbum, pinned, special, apps, regular } + +extension ExtraAlbumImportance on AlbumImportance { + String getText(BuildContext context) { + switch (this) { + case AlbumImportance.newAlbum: + return context.l10n.albumTierNew; + case AlbumImportance.pinned: + return context.l10n.albumTierPinned; + case AlbumImportance.special: + return context.l10n.albumTierSpecial; + case AlbumImportance.apps: + return context.l10n.albumTierApps; + case AlbumImportance.regular: + return context.l10n.albumTierRegular; + } + } + + IconData getIcon() { + switch (this) { + case AlbumImportance.newAlbum: + return AIcons.newTier; + case AlbumImportance.pinned: + return AIcons.pin; + case AlbumImportance.special: + return AIcons.important; + case AlbumImportance.apps: + return AIcons.app; + case AlbumImportance.regular: + return AIcons.album; + } + } +} + +enum AlbumMimeType { images, videos, mixed } + +extension ExtraAlbumMimeType on AlbumMimeType { + String getText(BuildContext context) { + switch (this) { + case AlbumMimeType.images: + return context.l10n.drawerCollectionImages; + case AlbumMimeType.videos: + return context.l10n.drawerCollectionVideos; + case AlbumMimeType.mixed: + return context.l10n.albumMimeTypeMixed; + } + } + + IconData getIcon() { + switch (this) { + case AlbumMimeType.images: + return AIcons.image; + case AlbumMimeType.videos: + return AIcons.video; + case AlbumMimeType.mixed: + return AIcons.mimeType; + } + } +} diff --git a/lib/widgets/filter_grids/common/section_keys.dart b/lib/widgets/filter_grids/common/section_keys.dart index d6dec813e..5f700f9c1 100644 --- a/lib/widgets/filter_grids/common/section_keys.dart +++ b/lib/widgets/filter_grids/common/section_keys.dart @@ -2,6 +2,7 @@ import 'package:aves/model/source/section_keys.dart'; import 'package:aves/theme/icons.dart'; import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; +import 'package:aves/widgets/filter_grids/common/enums.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; @@ -37,38 +38,19 @@ class AlbumImportanceSectionKey extends ChipSectionKey { Widget get leading => Icon(importance.getIcon()); } -enum AlbumImportance { newAlbum, pinned, special, apps, regular } +class MimeTypeSectionKey extends ChipSectionKey { + final AlbumMimeType mimeType; -extension ExtraAlbumImportance on AlbumImportance { - String getText(BuildContext context) { - switch (this) { - case AlbumImportance.newAlbum: - return context.l10n.albumTierNew; - case AlbumImportance.pinned: - return context.l10n.albumTierPinned; - case AlbumImportance.special: - return context.l10n.albumTierSpecial; - case AlbumImportance.apps: - return context.l10n.albumTierApps; - case AlbumImportance.regular: - return context.l10n.albumTierRegular; - } - } + MimeTypeSectionKey._private(BuildContext context, this.mimeType) : super(title: mimeType.getText(context)); - IconData getIcon() { - switch (this) { - case AlbumImportance.newAlbum: - return AIcons.newTier; - case AlbumImportance.pinned: - return AIcons.pin; - case AlbumImportance.special: - return AIcons.important; - case AlbumImportance.apps: - return AIcons.app; - case AlbumImportance.regular: - return AIcons.album; - } - } + factory MimeTypeSectionKey.images(BuildContext context) => MimeTypeSectionKey._private(context, AlbumMimeType.images); + + factory MimeTypeSectionKey.videos(BuildContext context) => MimeTypeSectionKey._private(context, AlbumMimeType.videos); + + factory MimeTypeSectionKey.mixed(BuildContext context) => MimeTypeSectionKey._private(context, AlbumMimeType.mixed); + + @override + Widget get leading => Icon(mimeType.getIcon()); } class StorageVolumeSectionKey extends ChipSectionKey { diff --git a/untranslated.json b/untranslated.json index ae8321bff..bfcc646a4 100644 --- a/untranslated.json +++ b/untranslated.json @@ -4,6 +4,8 @@ "widgetOpenPageHome", "widgetOpenPageViewer", "tileLayoutMosaic", + "albumGroupType", + "albumMimeTypeMixed", "settingsWidgetOpenPage" ], @@ -12,6 +14,8 @@ "widgetOpenPageHome", "widgetOpenPageViewer", "tileLayoutMosaic", + "albumGroupType", + "albumMimeTypeMixed", "settingsWidgetOpenPage" ], @@ -33,6 +37,8 @@ "sortOrderLowestFirst", "sortOrderLargestFirst", "sortOrderSmallestFirst", + "albumGroupType", + "albumMimeTypeMixed", "searchMetadataSectionTitle", "settingsConfirmationAfterMoveToBinItems", "settingsWidgetOpenPage", @@ -42,6 +48,8 @@ "fr": [ "widgetOpenPageHome", "widgetOpenPageViewer", + "albumGroupType", + "albumMimeTypeMixed", "settingsWidgetOpenPage" ], @@ -50,6 +58,8 @@ "widgetOpenPageHome", "widgetOpenPageViewer", "tileLayoutMosaic", + "albumGroupType", + "albumMimeTypeMixed", "settingsWidgetOpenPage" ], @@ -58,6 +68,8 @@ "widgetOpenPageHome", "widgetOpenPageViewer", "tileLayoutMosaic", + "albumGroupType", + "albumMimeTypeMixed", "settingsWidgetOpenPage" ], @@ -79,6 +91,8 @@ "sortOrderLowestFirst", "sortOrderLargestFirst", "sortOrderSmallestFirst", + "albumGroupType", + "albumMimeTypeMixed", "searchMetadataSectionTitle", "settingsConfirmationAfterMoveToBinItems", "settingsViewerGestureSideTapNext", @@ -89,6 +103,8 @@ "ko": [ "widgetOpenPageHome", "widgetOpenPageViewer", + "albumGroupType", + "albumMimeTypeMixed", "settingsWidgetOpenPage" ], @@ -97,6 +113,8 @@ "widgetOpenPageHome", "widgetOpenPageViewer", "tileLayoutMosaic", + "albumGroupType", + "albumMimeTypeMixed", "settingsWidgetOpenPage" ], @@ -105,6 +123,8 @@ "widgetOpenPageHome", "widgetOpenPageViewer", "tileLayoutMosaic", + "albumGroupType", + "albumMimeTypeMixed", "settingsWidgetOpenPage" ], @@ -113,6 +133,8 @@ "widgetOpenPageHome", "widgetOpenPageViewer", "tileLayoutMosaic", + "albumGroupType", + "albumMimeTypeMixed", "settingsWidgetOpenPage" ], @@ -148,6 +170,8 @@ "sortOrderLowestFirst", "sortOrderLargestFirst", "sortOrderSmallestFirst", + "albumGroupType", + "albumMimeTypeMixed", "searchMetadataSectionTitle", "settingsConfirmationAfterMoveToBinItems", "settingsViewerGestureSideTapNext", @@ -174,6 +198,8 @@ "widgetOpenPageHome", "widgetOpenPageViewer", "tileLayoutMosaic", + "albumGroupType", + "albumMimeTypeMixed", "settingsWidgetOpenPage" ] }