mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-23 01:06:21 +01:00
Support sorting albums by filename
This commit is contained in:
parent
083263c561
commit
32bef588a1
9 changed files with 521 additions and 1 deletions
|
@ -98,6 +98,13 @@ class Album with EquatableMixin {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (jsonVersion < 8) {
|
||||||
|
result = upgraderFactory?.buildV7()?.call(result);
|
||||||
|
if (result == null) {
|
||||||
|
_log.info("[fromJson] Version $jsonVersion not compatible");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (jsonVersion > version) {
|
if (jsonVersion > version) {
|
||||||
_log.warning(
|
_log.warning(
|
||||||
"[fromJson] Reading album with newer version: $jsonVersion > $version");
|
"[fromJson] Reading album with newer version: $jsonVersion > $version");
|
||||||
|
@ -221,7 +228,7 @@ class Album with EquatableMixin {
|
||||||
final int savedVersion;
|
final int savedVersion;
|
||||||
|
|
||||||
/// versioning of this class, use to upgrade old persisted album
|
/// versioning of this class, use to upgrade old persisted album
|
||||||
static const version = 7;
|
static const version = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AlbumShare with EquatableMixin {
|
class AlbumShare with EquatableMixin {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/entity/album/item.dart';
|
import 'package:nc_photos/entity/album/item.dart';
|
||||||
|
@ -17,6 +18,9 @@ abstract class AlbumSortProvider with EquatableMixin {
|
||||||
return AlbumNullSortProvider.fromJson(content.cast<String, dynamic>());
|
return AlbumNullSortProvider.fromJson(content.cast<String, dynamic>());
|
||||||
case AlbumTimeSortProvider._type:
|
case AlbumTimeSortProvider._type:
|
||||||
return AlbumTimeSortProvider.fromJson(content.cast<String, dynamic>());
|
return AlbumTimeSortProvider.fromJson(content.cast<String, dynamic>());
|
||||||
|
case AlbumFilenameSortProvider._type:
|
||||||
|
return AlbumFilenameSortProvider.fromJson(
|
||||||
|
content.cast<String, dynamic>());
|
||||||
default:
|
default:
|
||||||
_log.shout("[fromJson] Unknown type: $type");
|
_log.shout("[fromJson] Unknown type: $type");
|
||||||
throw ArgumentError.value(type, "type");
|
throw ArgumentError.value(type, "type");
|
||||||
|
@ -29,6 +33,8 @@ abstract class AlbumSortProvider with EquatableMixin {
|
||||||
return AlbumNullSortProvider._type;
|
return AlbumNullSortProvider._type;
|
||||||
} else if (this is AlbumTimeSortProvider) {
|
} else if (this is AlbumTimeSortProvider) {
|
||||||
return AlbumTimeSortProvider._type;
|
return AlbumTimeSortProvider._type;
|
||||||
|
} else if (this is AlbumFilenameSortProvider) {
|
||||||
|
return AlbumFilenameSortProvider._type;
|
||||||
} else {
|
} else {
|
||||||
throw StateError("Unknwon subtype");
|
throw StateError("Unknwon subtype");
|
||||||
}
|
}
|
||||||
|
@ -157,3 +163,54 @@ class AlbumTimeSortProvider extends AlbumReversibleSortProvider {
|
||||||
|
|
||||||
static const _type = "time";
|
static const _type = "time";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sort based on the name of the files
|
||||||
|
class AlbumFilenameSortProvider extends AlbumReversibleSortProvider {
|
||||||
|
const AlbumFilenameSortProvider({
|
||||||
|
required bool isAscending,
|
||||||
|
}) : super(isAscending: isAscending);
|
||||||
|
|
||||||
|
factory AlbumFilenameSortProvider.fromJson(JsonObj json) {
|
||||||
|
return AlbumFilenameSortProvider(
|
||||||
|
isAscending: json["isAscending"] ?? true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
toString() => "$runtimeType {"
|
||||||
|
"super: ${super.toString()}, "
|
||||||
|
"}";
|
||||||
|
|
||||||
|
@override
|
||||||
|
sort(List<AlbumItem> items) {
|
||||||
|
String? prevFilename;
|
||||||
|
return items
|
||||||
|
.map((e) {
|
||||||
|
if (e is AlbumFileItem) {
|
||||||
|
// take the file name
|
||||||
|
prevFilename = e.file.filename;
|
||||||
|
}
|
||||||
|
// for non file items, use the sibling file's name
|
||||||
|
return Tuple2(prevFilename, e);
|
||||||
|
})
|
||||||
|
.stableSorted((x, y) {
|
||||||
|
if (x.item1 == null && y.item1 == null) {
|
||||||
|
return 0;
|
||||||
|
} else if (x.item1 == null) {
|
||||||
|
return -1;
|
||||||
|
} else if (y.item1 == null) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
if (isAscending) {
|
||||||
|
return compareNatural(x.item1!, y.item1!);
|
||||||
|
} else {
|
||||||
|
return compareNatural(y.item1!, x.item1!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map((e) => e.item2)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const _type = "filename";
|
||||||
|
}
|
||||||
|
|
|
@ -224,6 +224,24 @@ class AlbumUpgraderV6 implements AlbumUpgrader {
|
||||||
final String? logFilePath;
|
final String? logFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Upgrade v7 Album to v8
|
||||||
|
class AlbumUpgraderV7 implements AlbumUpgrader {
|
||||||
|
const AlbumUpgraderV7({
|
||||||
|
this.logFilePath,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
call(JsonObj json) {
|
||||||
|
_log.fine("[call] Upgrade v7 Album for file: $logFilePath");
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
static final _log = Logger("entity.album.upgrader.AlbumUpgraderV7");
|
||||||
|
|
||||||
|
/// File path for logging only
|
||||||
|
final String? logFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
abstract class AlbumUpgraderFactory {
|
abstract class AlbumUpgraderFactory {
|
||||||
const AlbumUpgraderFactory();
|
const AlbumUpgraderFactory();
|
||||||
|
|
||||||
|
@ -233,6 +251,7 @@ abstract class AlbumUpgraderFactory {
|
||||||
AlbumUpgraderV4? buildV4();
|
AlbumUpgraderV4? buildV4();
|
||||||
AlbumUpgraderV5? buildV5();
|
AlbumUpgraderV5? buildV5();
|
||||||
AlbumUpgraderV6? buildV6();
|
AlbumUpgraderV6? buildV6();
|
||||||
|
AlbumUpgraderV7? buildV7();
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultAlbumUpgraderFactory extends AlbumUpgraderFactory {
|
class DefaultAlbumUpgraderFactory extends AlbumUpgraderFactory {
|
||||||
|
@ -264,6 +283,9 @@ class DefaultAlbumUpgraderFactory extends AlbumUpgraderFactory {
|
||||||
@override
|
@override
|
||||||
buildV6() => AlbumUpgraderV6(logFilePath: logFilePath);
|
buildV6() => AlbumUpgraderV6(logFilePath: logFilePath);
|
||||||
|
|
||||||
|
@override
|
||||||
|
buildV7() => AlbumUpgraderV7(logFilePath: logFilePath);
|
||||||
|
|
||||||
final Account account;
|
final Account account;
|
||||||
final File? albumFile;
|
final File? albumFile;
|
||||||
|
|
||||||
|
|
|
@ -607,6 +607,14 @@
|
||||||
"@sortOptionTimeDescendingLabel": {
|
"@sortOptionTimeDescendingLabel": {
|
||||||
"description": "Sort by time, in descending order"
|
"description": "Sort by time, in descending order"
|
||||||
},
|
},
|
||||||
|
"sortOptionFilenameAscendingLabel": "Filename",
|
||||||
|
"@sortOptionFilenameAscendingLabel": {
|
||||||
|
"description": "Sort by filename, in ascending order"
|
||||||
|
},
|
||||||
|
"sortOptionFilenameDescendingLabel": "Filename (descending)",
|
||||||
|
"@sortOptionFilenameDescendingLabel": {
|
||||||
|
"description": "Sort by filename, in descending order"
|
||||||
|
},
|
||||||
"sortOptionAlbumNameLabel": "Album name",
|
"sortOptionAlbumNameLabel": "Album name",
|
||||||
"@sortOptionAlbumNameLabel": {
|
"@sortOptionAlbumNameLabel": {
|
||||||
"description": "Sort by album name, in ascending order"
|
"description": "Sort by album name, in ascending order"
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
"settingsExperimentalDescription",
|
"settingsExperimentalDescription",
|
||||||
"settingsExperimentalPageTitle",
|
"settingsExperimentalPageTitle",
|
||||||
"rootPickerSkipConfirmationDialogContent2",
|
"rootPickerSkipConfirmationDialogContent2",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"sortOptionManualLabel",
|
"sortOptionManualLabel",
|
||||||
"helpButtonLabel",
|
"helpButtonLabel",
|
||||||
"collectionSharingLabel",
|
"collectionSharingLabel",
|
||||||
|
@ -135,6 +137,8 @@
|
||||||
"settingsExperimentalPageTitle",
|
"settingsExperimentalPageTitle",
|
||||||
"rootPickerSkipConfirmationDialogContent2",
|
"rootPickerSkipConfirmationDialogContent2",
|
||||||
"timeSecondInputHint",
|
"timeSecondInputHint",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"sortOptionManualLabel",
|
"sortOptionManualLabel",
|
||||||
"helpButtonLabel",
|
"helpButtonLabel",
|
||||||
"slideshowTooltip",
|
"slideshowTooltip",
|
||||||
|
@ -275,6 +279,8 @@
|
||||||
"captureLogSuccessNotification",
|
"captureLogSuccessNotification",
|
||||||
"rootPickerSkipConfirmationDialogContent2",
|
"rootPickerSkipConfirmationDialogContent2",
|
||||||
"timeSecondInputHint",
|
"timeSecondInputHint",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"sortOptionAlbumNameLabel",
|
"sortOptionAlbumNameLabel",
|
||||||
"sortOptionAlbumNameDescendingLabel",
|
"sortOptionAlbumNameDescendingLabel",
|
||||||
"sortOptionManualLabel",
|
"sortOptionManualLabel",
|
||||||
|
@ -412,6 +418,8 @@
|
||||||
"settingsMiscellaneousPageTitle",
|
"settingsMiscellaneousPageTitle",
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
"rootPickerSkipConfirmationDialogContent2",
|
"rootPickerSkipConfirmationDialogContent2",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"helpButtonLabel",
|
"helpButtonLabel",
|
||||||
"backgroundServiceStopping",
|
"backgroundServiceStopping",
|
||||||
"metadataTaskPauseLowBatteryNotification",
|
"metadataTaskPauseLowBatteryNotification",
|
||||||
|
@ -433,6 +441,8 @@
|
||||||
"settingsMiscellaneousTitle",
|
"settingsMiscellaneousTitle",
|
||||||
"settingsMiscellaneousPageTitle",
|
"settingsMiscellaneousPageTitle",
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"enhanceSuperResolution4xTitle",
|
"enhanceSuperResolution4xTitle",
|
||||||
"enhanceStyleTransferTitle"
|
"enhanceStyleTransferTitle"
|
||||||
],
|
],
|
||||||
|
@ -446,6 +456,8 @@
|
||||||
"settingsMiscellaneousTitle",
|
"settingsMiscellaneousTitle",
|
||||||
"settingsMiscellaneousPageTitle",
|
"settingsMiscellaneousPageTitle",
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"helpTooltip",
|
"helpTooltip",
|
||||||
"helpButtonLabel",
|
"helpButtonLabel",
|
||||||
"removeFromAlbumTooltip",
|
"removeFromAlbumTooltip",
|
||||||
|
@ -471,6 +483,8 @@
|
||||||
"settingsMiscellaneousTitle",
|
"settingsMiscellaneousTitle",
|
||||||
"settingsMiscellaneousPageTitle",
|
"settingsMiscellaneousPageTitle",
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"createCollectionTooltip",
|
"createCollectionTooltip",
|
||||||
"createCollectionDialogAlbumLabel",
|
"createCollectionDialogAlbumLabel",
|
||||||
"createCollectionDialogAlbumDescription",
|
"createCollectionDialogAlbumDescription",
|
||||||
|
@ -514,6 +528,8 @@
|
||||||
"settingsMiscellaneousTitle",
|
"settingsMiscellaneousTitle",
|
||||||
"settingsMiscellaneousPageTitle",
|
"settingsMiscellaneousPageTitle",
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"enhanceTooltip",
|
"enhanceTooltip",
|
||||||
"enhanceButtonLabel",
|
"enhanceButtonLabel",
|
||||||
"enhanceIntroDialogTitle",
|
"enhanceIntroDialogTitle",
|
||||||
|
@ -536,6 +552,8 @@
|
||||||
"settingsMiscellaneousTitle",
|
"settingsMiscellaneousTitle",
|
||||||
"settingsMiscellaneousPageTitle",
|
"settingsMiscellaneousPageTitle",
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"enhanceTooltip",
|
"enhanceTooltip",
|
||||||
"enhanceButtonLabel",
|
"enhanceButtonLabel",
|
||||||
"enhanceIntroDialogTitle",
|
"enhanceIntroDialogTitle",
|
||||||
|
@ -558,6 +576,8 @@
|
||||||
"settingsMiscellaneousTitle",
|
"settingsMiscellaneousTitle",
|
||||||
"settingsMiscellaneousPageTitle",
|
"settingsMiscellaneousPageTitle",
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"enhanceTooltip",
|
"enhanceTooltip",
|
||||||
"enhanceButtonLabel",
|
"enhanceButtonLabel",
|
||||||
"enhanceIntroDialogTitle",
|
"enhanceIntroDialogTitle",
|
||||||
|
@ -580,6 +600,8 @@
|
||||||
"settingsMiscellaneousTitle",
|
"settingsMiscellaneousTitle",
|
||||||
"settingsMiscellaneousPageTitle",
|
"settingsMiscellaneousPageTitle",
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
|
"sortOptionFilenameAscendingLabel",
|
||||||
|
"sortOptionFilenameDescendingLabel",
|
||||||
"enhanceTooltip",
|
"enhanceTooltip",
|
||||||
"enhanceButtonLabel",
|
"enhanceButtonLabel",
|
||||||
"enhanceIntroDialogTitle",
|
"enhanceIntroDialogTitle",
|
||||||
|
|
|
@ -575,6 +575,24 @@ class _AlbumBrowserState extends State<AlbumBrowser>
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
FancyOptionPickerItem(
|
||||||
|
label: L10n.global().sortOptionFilenameAscendingLabel,
|
||||||
|
isSelected: sortProvider is AlbumFilenameSortProvider &&
|
||||||
|
sortProvider.isAscending,
|
||||||
|
onSelect: () {
|
||||||
|
_onEditSortFilenamePressed();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FancyOptionPickerItem(
|
||||||
|
label: L10n.global().sortOptionFilenameDescendingLabel,
|
||||||
|
isSelected: sortProvider is AlbumFilenameSortProvider &&
|
||||||
|
!sortProvider.isAscending,
|
||||||
|
onSelect: () {
|
||||||
|
_onEditSortFilenameDescendingPressed();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
if (sortProvider is AlbumNullSortProvider)
|
if (sortProvider is AlbumNullSortProvider)
|
||||||
FancyOptionPickerItem(
|
FancyOptionPickerItem(
|
||||||
label: L10n.global().sortOptionManualLabel,
|
label: L10n.global().sortOptionManualLabel,
|
||||||
|
@ -606,6 +624,24 @@ class _AlbumBrowserState extends State<AlbumBrowser>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onEditSortFilenamePressed() {
|
||||||
|
_editAlbum = _editAlbum!.copyWith(
|
||||||
|
sortProvider: const AlbumFilenameSortProvider(isAscending: true),
|
||||||
|
);
|
||||||
|
setState(() {
|
||||||
|
_transformItems();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onEditSortFilenameDescendingPressed() {
|
||||||
|
_editAlbum = _editAlbum!.copyWith(
|
||||||
|
sortProvider: const AlbumFilenameSortProvider(isAscending: false),
|
||||||
|
);
|
||||||
|
setState(() {
|
||||||
|
_transformItems();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void _onEditAddTextPressed() {
|
void _onEditAddTextPressed() {
|
||||||
showDialog<String>(
|
showDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
|
@ -499,6 +499,24 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
FancyOptionPickerItem(
|
||||||
|
label: L10n.global().sortOptionFilenameAscendingLabel,
|
||||||
|
isSelected: sortProvider is AlbumFilenameSortProvider &&
|
||||||
|
sortProvider.isAscending,
|
||||||
|
onSelect: () {
|
||||||
|
_onEditSortFilenamePressed();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FancyOptionPickerItem(
|
||||||
|
label: L10n.global().sortOptionFilenameDescendingLabel,
|
||||||
|
isSelected: sortProvider is AlbumFilenameSortProvider &&
|
||||||
|
!sortProvider.isAscending,
|
||||||
|
onSelect: () {
|
||||||
|
_onEditSortFilenameDescendingPressed();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -522,6 +540,24 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onEditSortFilenamePressed() {
|
||||||
|
_editAlbum = _editAlbum!.copyWith(
|
||||||
|
sortProvider: const AlbumFilenameSortProvider(isAscending: true),
|
||||||
|
);
|
||||||
|
setState(() {
|
||||||
|
_transformItems(_sortedItems);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onEditSortFilenameDescendingPressed() {
|
||||||
|
_editAlbum = _editAlbum!.copyWith(
|
||||||
|
sortProvider: const AlbumFilenameSortProvider(isAscending: false),
|
||||||
|
);
|
||||||
|
setState(() {
|
||||||
|
_transformItems(_sortedItems);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _onAlbumUpdatedEvent(AlbumUpdatedEvent ev) async {
|
Future<void> _onAlbumUpdatedEvent(AlbumUpdatedEvent ev) async {
|
||||||
if (ev.album.albumFile!.path == _album?.albumFile?.path) {
|
if (ev.album.albumFile!.path == _album?.albumFile?.path) {
|
||||||
final album = await _updateAlbumPostPopulate(ev.album, _sortedItems);
|
final album = await _updateAlbumPostPopulate(ev.album, _sortedItems);
|
||||||
|
|
|
@ -27,6 +27,19 @@ void main() {
|
||||||
test("head", _timeNonFileHead);
|
test("head", _timeNonFileHead);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group("AlbumFilenameSortProvider", () {
|
||||||
|
group("AlbumFileItem", () {
|
||||||
|
test("ascending", _filenameFileAscending);
|
||||||
|
test("descending", _filenameFileDescending);
|
||||||
|
test("natural", _filenameFileNatural);
|
||||||
|
});
|
||||||
|
group("w/ non AlbumFileItem", () {
|
||||||
|
test("ascending", _filenameNonFileAscending);
|
||||||
|
test("descending", _filenameNonFileDescending);
|
||||||
|
test("head", _filenameNonFileHead);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _timeFromJson() {
|
void _timeFromJson() {
|
||||||
|
@ -217,3 +230,210 @@ void _timeNonFileHead() {
|
||||||
const sort = AlbumTimeSortProvider(isAscending: true);
|
const sort = AlbumTimeSortProvider(isAscending: true);
|
||||||
expect(sort.sort(items), [items[0], items[2], items[1], items[3]]);
|
expect(sort.sort(items), [items[0], items[2], items[1], items[3]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sort files by filename
|
||||||
|
///
|
||||||
|
/// Expect: items sorted
|
||||||
|
void _filenameFileAscending() {
|
||||||
|
final items = (util.FilesBuilder()
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test3.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 1),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test1.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 0),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test2.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 2),
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
.mapWithIndex((i, f) => AlbumFileItem(
|
||||||
|
addedBy: CiString("admin"),
|
||||||
|
addedAt: f.lastModified!,
|
||||||
|
file: f,
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
const sort = AlbumFilenameSortProvider(isAscending: true);
|
||||||
|
expect(sort.sort(items), [items[1], items[2], items[0]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sort files by filename, descending
|
||||||
|
///
|
||||||
|
/// Expect: items sorted
|
||||||
|
void _filenameFileDescending() {
|
||||||
|
final items = (util.FilesBuilder()
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test3.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 1),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test1.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 0),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test2.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 2),
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
.mapWithIndex((i, f) => AlbumFileItem(
|
||||||
|
addedBy: CiString("admin"),
|
||||||
|
addedAt: f.lastModified!,
|
||||||
|
file: f,
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
const sort = AlbumFilenameSortProvider(isAscending: false);
|
||||||
|
expect(sort.sort(items), [items[0], items[2], items[1]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sort files by filename
|
||||||
|
///
|
||||||
|
/// Expect: items sorted in natural order
|
||||||
|
void _filenameFileNatural() {
|
||||||
|
final items = (util.FilesBuilder()
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test033_2.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 1),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test033_1.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 1),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test033_3.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 1),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test11.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 0),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test2.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 2),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test2_999.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 1),
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
.mapWithIndex((i, f) => AlbumFileItem(
|
||||||
|
addedBy: CiString("admin"),
|
||||||
|
addedAt: f.lastModified!,
|
||||||
|
file: f,
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
const sort = AlbumFilenameSortProvider(isAscending: true);
|
||||||
|
expect(
|
||||||
|
sort.sort(items),
|
||||||
|
[items[4], items[5], items[3], items[1], items[0], items[2]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sort files + non files by filename
|
||||||
|
///
|
||||||
|
/// Expect: file sorted, non file stick with the prev file
|
||||||
|
void _filenameNonFileAscending() {
|
||||||
|
final items = (util.FilesBuilder()
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test3.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 1),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test1.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 0),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test2.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 2),
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
.mapWithIndex<AlbumItem>((i, f) => AlbumFileItem(
|
||||||
|
addedBy: CiString("admin"),
|
||||||
|
addedAt: f.lastModified!,
|
||||||
|
file: f,
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
items.insert(
|
||||||
|
2,
|
||||||
|
AlbumLabelItem(
|
||||||
|
addedBy: CiString("admin"),
|
||||||
|
addedAt: DateTime.utc(2020, 1, 2, 3, 4, 5),
|
||||||
|
text: "test",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const sort = AlbumFilenameSortProvider(isAscending: true);
|
||||||
|
expect(sort.sort(items), [items[1], items[2], items[3], items[0]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sort files + non files by filename, descending
|
||||||
|
///
|
||||||
|
/// Expect: file sorted, non file stick with the prev file
|
||||||
|
void _filenameNonFileDescending() {
|
||||||
|
final items = (util.FilesBuilder()
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test3.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 1),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test1.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 0),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test2.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 2),
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
.mapWithIndex<AlbumItem>((i, f) => AlbumFileItem(
|
||||||
|
addedBy: CiString("admin"),
|
||||||
|
addedAt: f.lastModified!,
|
||||||
|
file: f,
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
items.insert(
|
||||||
|
2,
|
||||||
|
AlbumLabelItem(
|
||||||
|
addedBy: CiString("admin"),
|
||||||
|
addedAt: DateTime.utc(2020, 1, 2, 3, 4, 5),
|
||||||
|
text: "test",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const sort = AlbumFilenameSortProvider(isAscending: false);
|
||||||
|
expect(sort.sort(items), [items[0], items[3], items[1], items[2]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sort files + non files by filename, with the head being a non file
|
||||||
|
///
|
||||||
|
/// Expect: file sorted, non file stick at the head
|
||||||
|
void _filenameNonFileHead() {
|
||||||
|
final items = (util.FilesBuilder()
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test3.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 1),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test1.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 0),
|
||||||
|
)
|
||||||
|
..addJpeg(
|
||||||
|
"admin/test2.jpg",
|
||||||
|
lastModified: DateTime.utc(2020, 1, 2, 3, 4, 2),
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
.mapWithIndex<AlbumItem>((i, f) => AlbumFileItem(
|
||||||
|
addedBy: CiString("admin"),
|
||||||
|
addedAt: f.lastModified!,
|
||||||
|
file: f,
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
items.insert(
|
||||||
|
0,
|
||||||
|
AlbumLabelItem(
|
||||||
|
addedBy: CiString("admin"),
|
||||||
|
addedAt: DateTime.utc(2020, 1, 2, 3, 4, 5),
|
||||||
|
text: "test",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const sort = AlbumFilenameSortProvider(isAscending: true);
|
||||||
|
expect(sort.sort(items), [items[0], items[2], items[3], items[1]]);
|
||||||
|
}
|
||||||
|
|
|
@ -292,6 +292,46 @@ void main() {
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("AlbumFilenameSortProvider", () {
|
||||||
|
final json = <String, dynamic>{
|
||||||
|
"version": Album.version,
|
||||||
|
"lastUpdated": "2020-01-02T03:04:05.678901Z",
|
||||||
|
"name": "",
|
||||||
|
"provider": <String, dynamic>{
|
||||||
|
"type": "static",
|
||||||
|
"content": <String, dynamic>{
|
||||||
|
"items": [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"coverProvider": <String, dynamic>{
|
||||||
|
"type": "auto",
|
||||||
|
"content": <String, dynamic>{},
|
||||||
|
},
|
||||||
|
"sortProvider": <String, dynamic>{
|
||||||
|
"type": "filename",
|
||||||
|
"content": <String, dynamic>{
|
||||||
|
"isAscending": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
Album.fromJson(
|
||||||
|
json,
|
||||||
|
upgraderFactory: const _NullAlbumUpgraderFactory(),
|
||||||
|
),
|
||||||
|
Album(
|
||||||
|
lastUpdated: DateTime.utc(2020, 1, 2, 3, 4, 5, 678, 901),
|
||||||
|
name: "",
|
||||||
|
provider: AlbumStaticProvider(
|
||||||
|
items: [],
|
||||||
|
),
|
||||||
|
coverProvider: AlbumAutoCoverProvider(),
|
||||||
|
sortProvider: const AlbumFilenameSortProvider(
|
||||||
|
isAscending: true,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
test("shares", _fromJsonShares);
|
test("shares", _fromJsonShares);
|
||||||
|
|
||||||
test("albumFile", () {
|
test("albumFile", () {
|
||||||
|
@ -580,6 +620,41 @@ void main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("AlbumFilenameSortProvider", () {
|
||||||
|
final album = Album(
|
||||||
|
lastUpdated: DateTime.utc(2020, 1, 2, 3, 4, 5, 678, 901),
|
||||||
|
name: "",
|
||||||
|
provider: AlbumStaticProvider(
|
||||||
|
items: [],
|
||||||
|
),
|
||||||
|
coverProvider: AlbumAutoCoverProvider(),
|
||||||
|
sortProvider: const AlbumFilenameSortProvider(
|
||||||
|
isAscending: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(album.toAppDbJson(), <String, dynamic>{
|
||||||
|
"version": Album.version,
|
||||||
|
"lastUpdated": "2020-01-02T03:04:05.678901Z",
|
||||||
|
"name": "",
|
||||||
|
"provider": <String, dynamic>{
|
||||||
|
"type": "static",
|
||||||
|
"content": <String, dynamic>{
|
||||||
|
"items": [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"coverProvider": <String, dynamic>{
|
||||||
|
"type": "auto",
|
||||||
|
"content": <String, dynamic>{},
|
||||||
|
},
|
||||||
|
"sortProvider": <String, dynamic>{
|
||||||
|
"type": "filename",
|
||||||
|
"content": <String, dynamic>{
|
||||||
|
"isAscending": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test("shares", _toRemoteJsonShares);
|
test("shares", _toRemoteJsonShares);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -831,6 +906,41 @@ void main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("AlbumFilenameSortProvider", () {
|
||||||
|
final album = Album(
|
||||||
|
lastUpdated: DateTime.utc(2020, 1, 2, 3, 4, 5, 678, 901),
|
||||||
|
name: "",
|
||||||
|
provider: AlbumStaticProvider(
|
||||||
|
items: [],
|
||||||
|
),
|
||||||
|
coverProvider: AlbumAutoCoverProvider(),
|
||||||
|
sortProvider: const AlbumFilenameSortProvider(
|
||||||
|
isAscending: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(album.toAppDbJson(), <String, dynamic>{
|
||||||
|
"version": Album.version,
|
||||||
|
"lastUpdated": "2020-01-02T03:04:05.678901Z",
|
||||||
|
"name": "",
|
||||||
|
"provider": <String, dynamic>{
|
||||||
|
"type": "static",
|
||||||
|
"content": <String, dynamic>{
|
||||||
|
"items": [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"coverProvider": <String, dynamic>{
|
||||||
|
"type": "auto",
|
||||||
|
"content": <String, dynamic>{},
|
||||||
|
},
|
||||||
|
"sortProvider": <String, dynamic>{
|
||||||
|
"type": "filename",
|
||||||
|
"content": <String, dynamic>{
|
||||||
|
"isAscending": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test("shares", _toAppDbJsonShares);
|
test("shares", _toAppDbJsonShares);
|
||||||
|
|
||||||
test("albumFile", () {
|
test("albumFile", () {
|
||||||
|
@ -1788,4 +1898,6 @@ class _NullAlbumUpgraderFactory extends AlbumUpgraderFactory {
|
||||||
buildV5() => null;
|
buildV5() => null;
|
||||||
@override
|
@override
|
||||||
buildV6() => null;
|
buildV6() => null;
|
||||||
|
@override
|
||||||
|
buildV7() => null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue