[mob] Gallery: Support grouping by day/week/month/year

This commit is contained in:
Neeraj Gupta 2024-05-04 12:31:08 +05:30
parent e75be714d9
commit 5f9b0d11f2
4 changed files with 54 additions and 6 deletions

View file

@ -187,7 +187,11 @@ class _LazyGroupGalleryState extends State<LazyGroupGallery> {
children: [
if (widget.enableFileGrouping)
GroupHeaderWidget(
title: groupType.getTitle(context, _filesInGroup[0]),
title: groupType.getTitle(
context,
_filesInGroup[0],
lastFile: _filesInGroup.last,
),
gridSize: widget.photoGridSize,
),
Expanded(child: Container()),

View file

@ -25,6 +25,18 @@ extension GroupTypeExtension on GroupType {
String getTitle(BuildContext context, EnteFile file, {EnteFile? lastFile}) {
if (this == GroupType.day) {
return _getDayTitle(context, file.creationTime!);
} else if (this == GroupType.week) {
// return weeks starting date to end date based on file
final date = DateTime.fromMicrosecondsSinceEpoch(file.creationTime!);
final startOfWeek = date.subtract(Duration(days: date.weekday - 1));
final endOfWeek = startOfWeek.add(const Duration(days: 6));
return "${DateFormat.MMMd(Localizations.localeOf(context).languageCode).format(startOfWeek)} - ${DateFormat.MMMd(Localizations.localeOf(context).languageCode).format(endOfWeek)}, ${endOfWeek.year}";
} else if (this == GroupType.year) {
final date = DateTime.fromMicrosecondsSinceEpoch(file.creationTime!);
return DateFormat.y(Localizations.localeOf(context).languageCode)
.format(date);
} else {
throw UnimplementedError("not implemented for $this");
}
throw UnimplementedError("not implemented for $this");
}
@ -33,6 +45,21 @@ extension GroupTypeExtension on GroupType {
switch (this) {
case GroupType.day:
return areFromSameDay(first.creationTime!, second.creationTime!);
case GroupType.month:
return DateTime.fromMicrosecondsSinceEpoch(first.creationTime!).year ==
DateTime.fromMicrosecondsSinceEpoch(second.creationTime!)
.year &&
DateTime.fromMicrosecondsSinceEpoch(first.creationTime!).month ==
DateTime.fromMicrosecondsSinceEpoch(second.creationTime!).month;
case GroupType.year:
return DateTime.fromMicrosecondsSinceEpoch(first.creationTime!).year ==
DateTime.fromMicrosecondsSinceEpoch(second.creationTime!).year;
case GroupType.week:
final firstDate =
DateTime.fromMicrosecondsSinceEpoch(first.creationTime!);
final secondDate =
DateTime.fromMicrosecondsSinceEpoch(second.creationTime!);
return areDatesInSameWeek(firstDate, secondDate);
default:
throw UnimplementedError("not implemented for $this");
}

View file

@ -12,10 +12,10 @@ import 'package:photos/models/file/file.dart';
import 'package:photos/models/file_load_result.dart';
import 'package:photos/models/selected_files.dart';
import 'package:photos/ui/common/loading_widget.dart';
import "package:photos/ui/viewer/gallery/component/group/type.dart";
import "package:photos/ui/viewer/gallery/component/multiple_groups_gallery_view.dart";
import 'package:photos/ui/viewer/gallery/empty_state.dart';
import "package:photos/ui/viewer/gallery/state/gallery_context_state.dart";
import 'package:photos/utils/date_time_util.dart';
import "package:photos/utils/debouncer.dart";
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
@ -59,6 +59,7 @@ class Gallery extends StatefulWidget {
// add a Function variable to get sort value in bool
final SortAscFn? sortAsyncFn;
final GroupType groupType;
const Gallery({
required this.asyncLoader,
@ -73,6 +74,7 @@ class Gallery extends StatefulWidget {
this.emptyState = const EmptyState(),
this.scrollBottomSafeArea = 120.0,
this.albumName = '',
this.groupType = GroupType.day,
this.enableFileGrouping = true,
this.loadingWidget = const EnteLoadingWidget(),
this.disableScroll = false,
@ -248,6 +250,7 @@ class GalleryState extends State<Gallery> {
return GalleryContextState(
sortOrderAsc: _sortOrderAsc,
inSelectionMode: widget.inSelectionMode,
type: widget.groupType,
child: MultipleGroupsGalleryView(
itemScroller: _itemScroller,
groupedFiles: currentGroupedFiles,
@ -273,13 +276,11 @@ class GalleryState extends State<Gallery> {
List<List<EnteFile>> _groupFiles(List<EnteFile> files) {
List<EnteFile> dailyFiles = [];
final List<List<EnteFile>> resultGroupedFiles = [];
for (int index = 0; index < files.length; index++) {
if (index > 0 &&
!areFromSameDay(
files[index - 1].creationTime!,
files[index].creationTime!,
)) {
!widget.groupType.areFromSameGroup(files[index - 1], files[index])) {
resultGroupedFiles.add(dailyFiles);
dailyFiles = [];
}

View file

@ -28,6 +28,22 @@ bool areFromSameDay(int firstCreationTime, int secondCreationTime) {
firstDate.day == secondDate.day;
}
bool areDatesInSameWeek(DateTime date1, DateTime date2) {
final int dayOfWeek1 = date1.weekday;
final int dayOfWeek2 = date2.weekday;
// Calculate the start and end dates of the week for both dates
final DateTime startOfWeek1 = date1.subtract(Duration(days: dayOfWeek1 - 1));
final DateTime endOfWeek1 = startOfWeek1.add(Duration(days: 6));
final DateTime startOfWeek2 = date2.subtract(Duration(days: dayOfWeek2 - 1));
final DateTime endOfWeek2 = startOfWeek2.add(Duration(days: 6));
// Check if the two dates fall within the same week range
if ((date1.isAfter(startOfWeek2) && date1.isBefore(endOfWeek2)) ||
(date2.isAfter(startOfWeek1) && date2.isBefore(endOfWeek1))) {
return true;
}
return false;
}
// Create link default names:
// Same day: "Dec 19, 2022"
// Same month: "Dec 19 - 22, 2022"