albums: group by content type
This commit is contained in:
parent
b82f7c2163
commit
eb6c9969f7
10 changed files with 123 additions and 31 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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,
|
||||||
];
|
];
|
||||||
|
|
63
lib/widgets/filter_grids/common/enums.dart
Normal file
63
lib/widgets/filter_grids/common/enums.dart
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
|
|
@ -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"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue