[mob][photos] Select all MVP

This commit is contained in:
ashilkn
2024-06-14 22:30:02 +05:30
parent 2c3f82023c
commit f04e54f68b
4 changed files with 110 additions and 19 deletions

View File

@@ -13,6 +13,7 @@ import 'package:photos/services/collections_service.dart';
import "package:photos/services/filter/db_filters.dart";
import 'package:photos/ui/viewer/actions/file_selection_overlay_bar.dart';
import 'package:photos/ui/viewer/gallery/gallery.dart';
import "package:photos/ui/viewer/gallery/state/selection_state.dart";
class HomeGalleryWidget extends StatelessWidget {
final Widget? header;
@@ -84,12 +85,16 @@ class HomeGalleryWidget extends StatelessWidget {
reloadDebounceTime: const Duration(seconds: 2),
reloadDebounceExecutionInterval: const Duration(seconds: 5),
);
return Stack(
alignment: Alignment.bottomCenter,
children: [
gallery,
FileSelectionOverlayBar(GalleryType.homepage, selectedFiles),
],
return SelectionState(
selectedFiles: selectedFiles,
// ignore: prefer_const_literals_to_create_immutables
child: Stack(
alignment: Alignment.bottomCenter,
children: [
gallery,
FileSelectionOverlayBar(GalleryType.homepage, selectedFiles),
],
),
);
// return gallery;
}

View File

@@ -4,7 +4,9 @@ import 'package:photos/models/collection/collection.dart';
import 'package:photos/models/gallery_type.dart';
import 'package:photos/models/selected_files.dart';
import "package:photos/theme/effects.dart";
import "package:photos/theme/ente_theme.dart";
import 'package:photos/ui/components/bottom_action_bar/bottom_action_bar_widget.dart';
import "package:photos/ui/viewer/gallery/state/selection_state.dart";
class FileSelectionOverlayBar extends StatefulWidget {
final GalleryType galleryType;
@@ -66,18 +68,25 @@ class _FileSelectionOverlayBarState extends State<FileSelectionOverlayBar> {
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(milliseconds: 400),
firstChild: BottomActionBarWidget(
selectedFiles: widget.selectedFiles,
galleryType: widget.galleryType,
collection: widget.collection,
person: widget.person,
clusterID: widget.clusterID,
onCancel: () {
if (widget.selectedFiles.files.isNotEmpty) {
widget.selectedFiles.clearAll();
}
},
backgroundColor: widget.backgroundColor,
firstChild: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
SelectAllButton(backgroundColor: widget.backgroundColor),
BottomActionBarWidget(
selectedFiles: widget.selectedFiles,
galleryType: widget.galleryType,
collection: widget.collection,
person: widget.person,
clusterID: widget.clusterID,
onCancel: () {
if (widget.selectedFiles.files.isNotEmpty) {
widget.selectedFiles.clearAll();
}
},
backgroundColor: widget.backgroundColor,
),
],
),
secondChild: const SizedBox(width: double.infinity),
);
@@ -90,3 +99,48 @@ class _FileSelectionOverlayBarState extends State<FileSelectionOverlayBar> {
_hasSelectedFilesNotifier.value = widget.selectedFiles.files.isNotEmpty;
}
}
class SelectAllButton extends StatefulWidget {
final Color? backgroundColor;
const SelectAllButton({super.key, required this.backgroundColor});
@override
State<SelectAllButton> createState() => _SelectAllButtonState();
}
class _SelectAllButtonState extends State<SelectAllButton> {
bool _selectAll = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
final selectionState = SelectionState.of(context);
if (_selectAll) {
selectionState?.selectedFiles.clearAll();
} else {
selectionState?.selectedFiles
.selectAll(selectionState.allGalleryFiles!.toSet());
}
_selectAll = !_selectAll;
});
},
child: Container(
color: getEnteColorScheme(context).backgroundElevated2,
padding: const EdgeInsets.all(4),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: [
const Text("All"),
Icon(
_selectAll ? Icons.check_circle : Icons.check_circle_outline,
color:
_selectAll ? getEnteColorScheme(context).strokeMuted : null,
),
],
),
),
);
}
}

View File

@@ -16,6 +16,7 @@ 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/ui/viewer/gallery/state/selection_state.dart";
import "package:photos/utils/debouncer.dart";
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
@@ -173,7 +174,7 @@ class GalleryState extends State<Gallery> {
if (result.hasMore) {
final result = await _loadFiles();
_setFilesAndReload(result.files);
}
} else {}
});
}
@@ -213,6 +214,8 @@ class GalleryState extends State<Gallery> {
// group files into multiple groups and returns `true` if it resulted in a
// gallery reload
bool _onFilesLoaded(List<EnteFile> files) {
SelectionState.of(context)?.allGalleryFiles = files;
final updatedGroupedFiles =
widget.enableFileGrouping && widget.groupType.timeGrouping()
? _groupBasedOnTime(files)

View File

@@ -0,0 +1,29 @@
import "package:flutter/material.dart";
import "package:photos/models/file/file.dart";
import "package:photos/models/selected_files.dart";
// ignore: must_be_immutable
class SelectionState extends InheritedWidget {
final SelectedFiles selectedFiles;
///Should be assigned later in gallery when files are loaded.
///Note: EnteFiles in this list should be references of the same EnteFiles
///that are grouped in gallery, so that when files are added/deleted,
///both lists are in sync.
List<EnteFile>? allGalleryFiles;
SelectionState({
Key? key,
required this.selectedFiles,
required Widget child,
}) : super(key: key, child: child);
static SelectionState? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<SelectionState>();
}
@override
bool updateShouldNotify(covariant InheritedWidget oldWidget) {
return false;
}
}