Ver Fonte

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

Neeraj Gupta há 1 ano atrás
pai
commit
5f9b0d11f2

+ 5 - 1
mobile/lib/ui/viewer/gallery/component/group/lazy_group_gallery.dart

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

+ 27 - 0
mobile/lib/ui/viewer/gallery/component/group/type.dart

@@ -25,6 +25,18 @@ extension GroupTypeExtension on GroupType {
   String getTitle(BuildContext context, EnteFile file, {EnteFile? lastFile}) {
   String getTitle(BuildContext context, EnteFile file, {EnteFile? lastFile}) {
     if (this == GroupType.day) {
     if (this == GroupType.day) {
       return _getDayTitle(context, file.creationTime!);
       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");
     throw UnimplementedError("not implemented for $this");
   }
   }
@@ -33,6 +45,21 @@ extension GroupTypeExtension on GroupType {
     switch (this) {
     switch (this) {
       case GroupType.day:
       case GroupType.day:
         return areFromSameDay(first.creationTime!, second.creationTime!);
         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:
       default:
         throw UnimplementedError("not implemented for $this");
         throw UnimplementedError("not implemented for $this");
     }
     }

+ 6 - 5
mobile/lib/ui/viewer/gallery/gallery.dart

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

+ 16 - 0
mobile/lib/utils/date_time_util.dart

@@ -28,6 +28,22 @@ bool areFromSameDay(int firstCreationTime, int secondCreationTime) {
       firstDate.day == secondDate.day;
       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:
 // Create link default names:
 // Same day: "Dec 19, 2022"
 // Same day: "Dec 19, 2022"
 // Same month: "Dec 19 - 22, 2022"
 // Same month: "Dec 19 - 22, 2022"