albums: group by content type

This commit is contained in:
Thibault Deckers 2022-09-27 11:39:15 +02:00
parent b82f7c2163
commit eb6c9969f7
10 changed files with 123 additions and 31 deletions

View file

@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added ### Added
- mosaic layout - mosaic layout
- Albums: group by content type
- Slideshow: option for no transition - Slideshow: option for no transition
- Widget: tap action setting - Widget: tap action setting

View file

@ -586,9 +586,12 @@
"sortOrderSmallestFirst": "Smallest first", "sortOrderSmallestFirst": "Smallest first",
"albumGroupTier": "By tier", "albumGroupTier": "By tier",
"albumGroupType": "By type",
"albumGroupVolume": "By storage volume", "albumGroupVolume": "By storage volume",
"albumGroupNone": "Do not group", "albumGroupNone": "Do not group",
"albumMimeTypeMixed": "Mixed",
"albumPickPageTitleCopy": "Copy to Album", "albumPickPageTitleCopy": "Copy to Album",
"albumPickPageTitleExport": "Export to Album", "albumPickPageTitleExport": "Export to Album",
"albumPickPageTitleMove": "Move to Album", "albumPickPageTitleMove": "Move to Album",

View file

@ -2,7 +2,7 @@ enum SourceState { loading, cataloguing, locatingCountries, locatingPlaces, read
enum ChipSortFactor { date, name, count, size } enum ChipSortFactor { date, name, count, size }
enum AlbumChipGroupFactor { none, importance, volume } enum AlbumChipGroupFactor { none, importance, mimeType, volume }
enum EntrySortFactor { date, name, rating, size } enum EntrySortFactor { date, name, rating, size }

View file

@ -124,6 +124,8 @@ extension ExtraAlbumChipGroupFactor on AlbumChipGroupFactor {
switch (this) { switch (this) {
case AlbumChipGroupFactor.importance: case AlbumChipGroupFactor.importance:
return l10n.albumGroupTier; return l10n.albumGroupTier;
case AlbumChipGroupFactor.mimeType:
return l10n.albumGroupType;
case AlbumChipGroupFactor.volume: case AlbumChipGroupFactor.volume:
return l10n.albumGroupVolume; return l10n.albumGroupVolume;
case AlbumChipGroupFactor.none: case AlbumChipGroupFactor.none:
@ -135,6 +137,8 @@ extension ExtraAlbumChipGroupFactor on AlbumChipGroupFactor {
switch (this) { switch (this) {
case AlbumChipGroupFactor.importance: case AlbumChipGroupFactor.importance:
return AIcons.important; return AIcons.important;
case AlbumChipGroupFactor.mimeType:
return AIcons.mimeType;
case AlbumChipGroupFactor.volume: case AlbumChipGroupFactor.volume:
return AIcons.removableStorage; return AIcons.removableStorage;
case AlbumChipGroupFactor.none: case AlbumChipGroupFactor.none:

View file

@ -34,6 +34,7 @@ class AIcons {
static const IconData location = Icons.place_outlined; static const IconData location = Icons.place_outlined;
static const IconData locationUnlocated = Icons.location_off_outlined; static const IconData locationUnlocated = Icons.location_off_outlined;
static const IconData mainStorage = Icons.smartphone_outlined; static const IconData mainStorage = Icons.smartphone_outlined;
static const IconData mimeType = Icons.code_outlined;
static const IconData opacity = Icons.opacity; static const IconData opacity = Icons.opacity;
static const IconData privacy = MdiIcons.shieldAccountOutline; static const IconData privacy = MdiIcons.shieldAccountOutline;
static const IconData rating = Icons.star_border_outlined; static const IconData rating = Icons.star_border_outlined;

View file

@ -118,6 +118,17 @@ class AlbumListPage extends StatelessWidget {
if (sections.containsKey(regularKey)) regularKey: sections[regularKey]!, if (sections.containsKey(regularKey)) regularKey: sections[regularKey]!,
}; };
break; break;
case AlbumChipGroupFactor.mimeType:
final visibleEntries = source.visibleEntries;
sections = groupBy<FilterGridItem<AlbumFilter>, 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: case AlbumChipGroupFactor.volume:
sections = groupBy<FilterGridItem<AlbumFilter>, ChipSectionKey>(unpinnedMapEntries, (kv) { sections = groupBy<FilterGridItem<AlbumFilter>, ChipSectionKey>(unpinnedMapEntries, (kv) {
return StorageVolumeSectionKey(context, androidFileUtils.getStorageVolume(kv.filter.album)); return StorageVolumeSectionKey(context, androidFileUtils.getStorageVolume(kv.filter.album));

View file

@ -59,6 +59,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate<AlbumFilter> with
static const _groupOptions = [ static const _groupOptions = [
AlbumChipGroupFactor.importance, AlbumChipGroupFactor.importance,
AlbumChipGroupFactor.mimeType,
AlbumChipGroupFactor.volume, AlbumChipGroupFactor.volume,
AlbumChipGroupFactor.none, AlbumChipGroupFactor.none,
]; ];

View file

@ -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;
}
}
}

View file

@ -2,6 +2,7 @@ import 'package:aves/model/source/section_keys.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/widgets/common/extensions/build_context.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:equatable/equatable.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -37,38 +38,19 @@ class AlbumImportanceSectionKey extends ChipSectionKey {
Widget get leading => Icon(importance.getIcon()); Widget get leading => Icon(importance.getIcon());
} }
enum AlbumImportance { newAlbum, pinned, special, apps, regular } class MimeTypeSectionKey extends ChipSectionKey {
final AlbumMimeType mimeType;
extension ExtraAlbumImportance on AlbumImportance { MimeTypeSectionKey._private(BuildContext context, this.mimeType) : super(title: mimeType.getText(context));
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() { factory MimeTypeSectionKey.images(BuildContext context) => MimeTypeSectionKey._private(context, AlbumMimeType.images);
switch (this) {
case AlbumImportance.newAlbum: factory MimeTypeSectionKey.videos(BuildContext context) => MimeTypeSectionKey._private(context, AlbumMimeType.videos);
return AIcons.newTier;
case AlbumImportance.pinned: factory MimeTypeSectionKey.mixed(BuildContext context) => MimeTypeSectionKey._private(context, AlbumMimeType.mixed);
return AIcons.pin;
case AlbumImportance.special: @override
return AIcons.important; Widget get leading => Icon(mimeType.getIcon());
case AlbumImportance.apps:
return AIcons.app;
case AlbumImportance.regular:
return AIcons.album;
}
}
} }
class StorageVolumeSectionKey extends ChipSectionKey { class StorageVolumeSectionKey extends ChipSectionKey {

View file

@ -4,6 +4,8 @@
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"tileLayoutMosaic", "tileLayoutMosaic",
"albumGroupType",
"albumMimeTypeMixed",
"settingsWidgetOpenPage" "settingsWidgetOpenPage"
], ],
@ -12,6 +14,8 @@
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"tileLayoutMosaic", "tileLayoutMosaic",
"albumGroupType",
"albumMimeTypeMixed",
"settingsWidgetOpenPage" "settingsWidgetOpenPage"
], ],
@ -33,6 +37,8 @@
"sortOrderLowestFirst", "sortOrderLowestFirst",
"sortOrderLargestFirst", "sortOrderLargestFirst",
"sortOrderSmallestFirst", "sortOrderSmallestFirst",
"albumGroupType",
"albumMimeTypeMixed",
"searchMetadataSectionTitle", "searchMetadataSectionTitle",
"settingsConfirmationAfterMoveToBinItems", "settingsConfirmationAfterMoveToBinItems",
"settingsWidgetOpenPage", "settingsWidgetOpenPage",
@ -42,6 +48,8 @@
"fr": [ "fr": [
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"albumGroupType",
"albumMimeTypeMixed",
"settingsWidgetOpenPage" "settingsWidgetOpenPage"
], ],
@ -50,6 +58,8 @@
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"tileLayoutMosaic", "tileLayoutMosaic",
"albumGroupType",
"albumMimeTypeMixed",
"settingsWidgetOpenPage" "settingsWidgetOpenPage"
], ],
@ -58,6 +68,8 @@
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"tileLayoutMosaic", "tileLayoutMosaic",
"albumGroupType",
"albumMimeTypeMixed",
"settingsWidgetOpenPage" "settingsWidgetOpenPage"
], ],
@ -79,6 +91,8 @@
"sortOrderLowestFirst", "sortOrderLowestFirst",
"sortOrderLargestFirst", "sortOrderLargestFirst",
"sortOrderSmallestFirst", "sortOrderSmallestFirst",
"albumGroupType",
"albumMimeTypeMixed",
"searchMetadataSectionTitle", "searchMetadataSectionTitle",
"settingsConfirmationAfterMoveToBinItems", "settingsConfirmationAfterMoveToBinItems",
"settingsViewerGestureSideTapNext", "settingsViewerGestureSideTapNext",
@ -89,6 +103,8 @@
"ko": [ "ko": [
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"albumGroupType",
"albumMimeTypeMixed",
"settingsWidgetOpenPage" "settingsWidgetOpenPage"
], ],
@ -97,6 +113,8 @@
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"tileLayoutMosaic", "tileLayoutMosaic",
"albumGroupType",
"albumMimeTypeMixed",
"settingsWidgetOpenPage" "settingsWidgetOpenPage"
], ],
@ -105,6 +123,8 @@
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"tileLayoutMosaic", "tileLayoutMosaic",
"albumGroupType",
"albumMimeTypeMixed",
"settingsWidgetOpenPage" "settingsWidgetOpenPage"
], ],
@ -113,6 +133,8 @@
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"tileLayoutMosaic", "tileLayoutMosaic",
"albumGroupType",
"albumMimeTypeMixed",
"settingsWidgetOpenPage" "settingsWidgetOpenPage"
], ],
@ -148,6 +170,8 @@
"sortOrderLowestFirst", "sortOrderLowestFirst",
"sortOrderLargestFirst", "sortOrderLargestFirst",
"sortOrderSmallestFirst", "sortOrderSmallestFirst",
"albumGroupType",
"albumMimeTypeMixed",
"searchMetadataSectionTitle", "searchMetadataSectionTitle",
"settingsConfirmationAfterMoveToBinItems", "settingsConfirmationAfterMoveToBinItems",
"settingsViewerGestureSideTapNext", "settingsViewerGestureSideTapNext",
@ -174,6 +198,8 @@
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"tileLayoutMosaic", "tileLayoutMosaic",
"albumGroupType",
"albumMimeTypeMixed",
"settingsWidgetOpenPage" "settingsWidgetOpenPage"
] ]
} }