Gallery: Support for group by size

This commit is contained in:
Neeraj Gupta 2024-05-27 18:03:26 +05:30
parent 95bb363aba
commit ac3c6b10a5
3 changed files with 75 additions and 7 deletions

View file

@ -5,7 +5,14 @@ import "package:photos/generated/l10n.dart";
import "package:photos/models/file/file.dart";
import "package:photos/utils/date_time_util.dart";
enum GroupType { day, week, month, size, year }
enum GroupType {
day,
week,
month,
size,
year,
none,
}
extension GroupTypeExtension on GroupType {
String get name {
@ -20,9 +27,25 @@ extension GroupTypeExtension on GroupType {
return "size";
case GroupType.year:
return "year";
case GroupType.none:
return "none";
}
}
bool timeGrouping() {
return this == GroupType.day ||
this == GroupType.week ||
this == GroupType.month ||
this == GroupType.year;
}
bool showGroupHeader() {
if (this == GroupType.size || this == GroupType.none) {
return false;
}
return true;
}
String getTitle(BuildContext context, EnteFile file, {EnteFile? lastFile}) {
if (this == GroupType.day) {
return _getDayTitle(context, file.creationTime!);
@ -41,7 +64,7 @@ extension GroupTypeExtension on GroupType {
return DateFormat.yMMM(Localizations.localeOf(context).languageCode)
.format(date);
} else {
throw UnimplementedError("not implemented for $this");
throw UnimplementedError("getTitle not implemented for $this");
}
}

View file

@ -9,7 +9,10 @@ import "package:photos/models/selected_files.dart";
import "package:photos/ui/common/loading_widget.dart";
import "package:photos/ui/huge_listview/huge_listview.dart";
import 'package:photos/ui/viewer/gallery/component/group/lazy_group_gallery.dart';
import "package:photos/ui/viewer/gallery/component/group/type.dart";
import "package:photos/ui/viewer/gallery/gallery.dart";
import "package:photos/ui/viewer/gallery/state/gallery_context_state.dart";
import "package:photos/utils/data_util.dart";
import "package:photos/utils/local_settings.dart";
import "package:scrollable_positioned_list/scrollable_positioned_list.dart";
@ -65,6 +68,7 @@ class MultipleGroupsGalleryView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final gType = GalleryContextState.of(context)!.type;
return HugeListView<List<EnteFile>>(
controller: itemScroller,
startIndex: 0,
@ -123,10 +127,17 @@ class MultipleGroupsGalleryView extends StatelessWidget {
},
labelTextBuilder: (int index) {
try {
final EnteFile file = groupedFiles[index][0];
if (gType == GroupType.size) {
return file.fileSize != null
? convertBytesToReadableFormat(file.fileSize!)
: "";
}
return DateFormat.yMMM(Localizations.localeOf(context).languageCode)
.format(
DateTime.fromMicrosecondsSinceEpoch(
groupedFiles[index][0].creationTime!,
file.creationTime!,
),
);
} catch (e) {

View file

@ -214,7 +214,9 @@ class GalleryState extends State<Gallery> {
// gallery reload
bool _onFilesLoaded(List<EnteFile> files) {
final updatedGroupedFiles =
widget.enableFileGrouping ? _groupFiles(files) : [files];
widget.enableFileGrouping && widget.groupType.timeGrouping()
? _groupBasedOnTime(files)
: _genericGroupForPerf(files);
if (currentGroupedFiles.length != updatedGroupedFiles.length ||
currentGroupedFiles.isEmpty) {
if (mounted) {
@ -261,20 +263,52 @@ class GalleryState extends State<Gallery> {
tagPrefix: widget.tagPrefix,
scrollBottomSafeArea: widget.scrollBottomSafeArea,
limitSelectionToOne: widget.limitSelectionToOne,
enableFileGrouping: widget.enableFileGrouping,
enableFileGrouping:
widget.enableFileGrouping && widget.groupType.showGroupHeader(),
logTag: _logTag,
logger: _logger,
reloadEvent: widget.reloadEvent,
header: widget.header,
footer: widget.footer,
selectedFiles: widget.selectedFiles,
showSelectAllByDefault: widget.showSelectAllByDefault,
showSelectAllByDefault:
widget.showSelectAllByDefault && widget.groupType.showGroupHeader(),
isScrollablePositionedList: widget.isScrollablePositionedList,
),
);
}
List<List<EnteFile>> _groupFiles(List<EnteFile> files) {
// create groups of 200 files for performance
List<List<EnteFile>> _genericGroupForPerf(List<EnteFile> files) {
if (widget.groupType == GroupType.size) {
// sort files by fileSize on the bases of _sortOrderAsc
files.sort((a, b) {
if (_sortOrderAsc) {
return a.fileSize!.compareTo(b.fileSize!);
} else {
return b.fileSize!.compareTo(a.fileSize!);
}
});
}
final List<List<EnteFile>> resultGroupedFiles = [];
List<EnteFile> singleGroupFile = [];
const int groupSize = 40;
for (int i = 0; i < files.length; i += 1) {
singleGroupFile.add(files[i]);
if (singleGroupFile.length == groupSize) {
resultGroupedFiles.add(singleGroupFile);
singleGroupFile = [];
}
}
if (singleGroupFile.isNotEmpty) {
resultGroupedFiles.add(singleGroupFile);
}
_logger.info('Grouped files into ${resultGroupedFiles.length} groups');
return resultGroupedFiles;
}
List<List<EnteFile>> _groupBasedOnTime(List<EnteFile> files) {
List<EnteFile> dailyFiles = [];
final List<List<EnteFile>> resultGroupedFiles = [];