Sort albums

This commit is contained in:
Ming Ming 2021-09-09 00:23:42 +08:00
parent 7423b1fd51
commit 42b931fa62
4 changed files with 125 additions and 7 deletions

View file

@ -571,6 +571,14 @@
"@sortOptionTimeDescendingLabel": { "@sortOptionTimeDescendingLabel": {
"description": "Sort by time, in descending order" "description": "Sort by time, in descending order"
}, },
"sortOptionAlbumNameLabel": "Album name",
"@sortOptionAlbumNameLabel": {
"description": "Sort by album name, in ascending order"
},
"sortOptionAlbumNameDescendingLabel": "Album name (descending)",
"@sortOptionAlbumNameDescendingLabel": {
"description": "Sort by album name, in descending order"
},
"albumEditDragRearrangeNotification": "Long press and drag an item to rearrange it manually", "albumEditDragRearrangeNotification": "Long press and drag an item to rearrange it manually",
"@albumEditDragRearrangeNotification": { "@albumEditDragRearrangeNotification": {
"description": "Instructions on how to rearrange photos" "description": "Instructions on how to rearrange photos"

View file

@ -15,6 +15,8 @@
"settingsUseBlackInDarkThemeTitle", "settingsUseBlackInDarkThemeTitle",
"settingsUseBlackInDarkThemeTrueDescription", "settingsUseBlackInDarkThemeTrueDescription",
"settingsUseBlackInDarkThemeFalseDescription", "settingsUseBlackInDarkThemeFalseDescription",
"sortOptionAlbumNameLabel",
"sortOptionAlbumNameDescendingLabel",
"listEmptyText", "listEmptyText",
"albumTrashLabel", "albumTrashLabel",
"restoreTooltip", "restoreTooltip",
@ -49,6 +51,11 @@
"unmuteTooltip" "unmuteTooltip"
], ],
"es": [
"sortOptionAlbumNameLabel",
"sortOptionAlbumNameDescendingLabel"
],
"fr": [ "fr": [
"collectionsTooltip", "collectionsTooltip",
"settingsViewerTitle", "settingsViewerTitle",
@ -65,6 +72,8 @@
"settingsUseBlackInDarkThemeTitle", "settingsUseBlackInDarkThemeTitle",
"settingsUseBlackInDarkThemeTrueDescription", "settingsUseBlackInDarkThemeTrueDescription",
"settingsUseBlackInDarkThemeFalseDescription", "settingsUseBlackInDarkThemeFalseDescription",
"sortOptionAlbumNameLabel",
"sortOptionAlbumNameDescendingLabel",
"helpTooltip", "helpTooltip",
"removeFromAlbumTooltip", "removeFromAlbumTooltip",
"fileSharedByDescription", "fileSharedByDescription",
@ -77,5 +86,10 @@
"unsetAlbumCoverFailureNotification", "unsetAlbumCoverFailureNotification",
"muteTooltip", "muteTooltip",
"unmuteTooltip" "unmuteTooltip"
],
"ru": [
"sortOptionAlbumNameLabel",
"sortOptionAlbumNameDescendingLabel"
] ]
} }

View file

@ -38,6 +38,11 @@ class Pref {
Future<bool> setAlbumBrowserZoomLevel(int value) => Future<bool> setAlbumBrowserZoomLevel(int value) =>
_pref.setInt("albumViewerZoomLevel", value); _pref.setInt("albumViewerZoomLevel", value);
int? getHomeAlbumsSort() => _pref.getInt("homeAlbumsSort");
int getHomeAlbumsSortOr(int def) => getHomeAlbumsSort() ?? def;
Future<bool> setHomeAlbumsSort(int value) =>
_pref.setInt("homeAlbumsSort", value);
bool? isEnableExif() => _pref.getBool("isEnableExif"); bool? isEnableExif() => _pref.getBool("isEnableExif");
bool isEnableExifOr([bool def = true]) => isEnableExif() ?? def; bool isEnableExifOr([bool def = true]) => isEnableExif() ?? def;
Future<bool> setEnableExif(bool value) => Future<bool> setEnableExif(bool value) =>

View file

@ -27,6 +27,7 @@ import 'package:nc_photos/widget/album_search_delegate.dart';
import 'package:nc_photos/widget/archive_browser.dart'; import 'package:nc_photos/widget/archive_browser.dart';
import 'package:nc_photos/widget/builder/album_grid_item_builder.dart'; import 'package:nc_photos/widget/builder/album_grid_item_builder.dart';
import 'package:nc_photos/widget/dynamic_album_browser.dart'; import 'package:nc_photos/widget/dynamic_album_browser.dart';
import 'package:nc_photos/widget/fancy_option_picker.dart';
import 'package:nc_photos/widget/home_app_bar.dart'; import 'package:nc_photos/widget/home_app_bar.dart';
import 'package:nc_photos/widget/new_album_dialog.dart'; import 'package:nc_photos/widget/new_album_dialog.dart';
import 'package:nc_photos/widget/page_visibility_mixin.dart'; import 'package:nc_photos/widget/page_visibility_mixin.dart';
@ -172,6 +173,10 @@ class _HomeAlbumsState extends State<HomeAlbums>
), ),
], ],
menuActions: [ menuActions: [
PopupMenuItem(
value: _menuValueSort,
child: Text(L10n.global().sortTooltip),
),
PopupMenuItem( PopupMenuItem(
value: _menuValueImport, value: _menuValueImport,
child: Text(L10n.global().importFoldersTooltip), child: Text(L10n.global().importFoldersTooltip),
@ -179,6 +184,10 @@ class _HomeAlbumsState extends State<HomeAlbums>
], ],
onSelectedMenuActions: (option) { onSelectedMenuActions: (option) {
switch (option) { switch (option) {
case _menuValueSort:
_onSortPressed(context);
break;
case _menuValueImport: case _menuValueImport:
_onAppBarImportPressed(context); _onAppBarImportPressed(context);
break; break;
@ -296,6 +305,56 @@ class _HomeAlbumsState extends State<HomeAlbums>
}); });
} }
void _onSortPressed(BuildContext context) {
showDialog(
context: context,
builder: (context) => FancyOptionPicker(
title: L10n.global().sortOptionDialogTitle,
items: [
FancyOptionPickerItem(
label: L10n.global().sortOptionTimeDescendingLabel,
isSelected: _getSortFromPref() == _Sort.dateDescending,
onSelect: () {
_onSortSelected(_Sort.dateDescending);
Navigator.of(context).pop();
},
),
FancyOptionPickerItem(
label: L10n.global().sortOptionTimeAscendingLabel,
isSelected: _getSortFromPref() == _Sort.dateAscending,
onSelect: () {
_onSortSelected(_Sort.dateAscending);
Navigator.of(context).pop();
},
),
FancyOptionPickerItem(
label: L10n.global().sortOptionAlbumNameLabel,
isSelected: _getSortFromPref() == _Sort.nameAscending,
onSelect: () {
_onSortSelected(_Sort.nameAscending);
Navigator.of(context).pop();
},
),
FancyOptionPickerItem(
label: L10n.global().sortOptionAlbumNameDescendingLabel,
isSelected: _getSortFromPref() == _Sort.nameDescending,
onSelect: () {
_onSortSelected(_Sort.nameDescending);
Navigator.of(context).pop();
},
),
],
),
);
}
void _onSortSelected(_Sort sort) async {
await Pref.inst().setHomeAlbumsSort(sort.index);
setState(() {
_transformItems(_bloc.state.items);
});
}
void _onAppBarImportPressed(BuildContext context) { void _onAppBarImportPressed(BuildContext context) {
Navigator.of(context).pushNamed(AlbumImporter.routeName, Navigator.of(context).pushNamed(AlbumImporter.routeName,
arguments: AlbumImporterArguments(widget.account)); arguments: AlbumImporterArguments(widget.account));
@ -357,16 +416,28 @@ class _HomeAlbumsState extends State<HomeAlbums>
/// Transform an Album list to grid items /// Transform an Album list to grid items
void _transformItems(List<ListAlbumBlocItem> items) { void _transformItems(List<ListAlbumBlocItem> items) {
final sortedAlbums = items final sort = _getSortFromPref();
.map((e) => final isAscending = _isSortAscending(sort);
Tuple2(e.album.provider.latestItemTime ?? e.album.lastUpdated, e)) final sortedAlbums = items.map<Tuple2<dynamic, ListAlbumBlocItem>>((e) {
.sorted((a, b) { switch (sort) {
// then sort in descending order case _Sort.nameAscending:
final tmp = b.item1.compareTo(a.item1); case _Sort.nameDescending:
return Tuple2(e.album.name, e);
case _Sort.dateAscending:
case _Sort.dateDescending:
default:
return Tuple2(
e.album.provider.latestItemTime ?? e.album.lastUpdated, e);
}
}).sorted((a, b) {
final x = isAscending ? a : b;
final y = isAscending ? b : a;
final tmp = x.item1.compareTo(y.item1);
if (tmp != 0) { if (tmp != 0) {
return tmp; return tmp;
} else { } else {
return a.item2.album.name.compareTo(b.item2.album.name); return x.item2.album.name.compareTo(y.item2.album.name);
} }
}).map((e) => e.item2); }).map((e) => e.item2);
itemStreamListItems = [ itemStreamListItems = [
@ -400,6 +471,7 @@ class _HomeAlbumsState extends State<HomeAlbums>
static final _log = Logger("widget.home_albums._HomeAlbumsState"); static final _log = Logger("widget.home_albums._HomeAlbumsState");
static const _menuValueImport = 0; static const _menuValueImport = 0;
static const _menuValueSort = 1;
} }
abstract class _ListItem implements SelectableItem { abstract class _ListItem implements SelectableItem {
@ -528,3 +600,22 @@ class _AlbumListItem extends _ListItem {
final bool isSharedByMe; final bool isSharedByMe;
final bool isSharedToMe; final bool isSharedToMe;
} }
enum _Sort {
dateDescending,
dateAscending,
nameAscending,
nameDescending,
}
_Sort _getSortFromPref() {
try {
return _Sort.values[Pref.inst().getHomeAlbumsSort()!];
} catch (_) {
// default
return _Sort.dateDescending;
}
}
bool _isSortAscending(_Sort sort) =>
sort == _Sort.dateAscending || sort == _Sort.nameAscending;