[mob][photos] Add select all feature to galleries (2)
This commit is contained in:
@@ -13,6 +13,7 @@ import "package:photos/services/search_service.dart";
|
||||
import 'package:photos/ui/viewer/actions/file_selection_overlay_bar.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/selection_state.dart";
|
||||
|
||||
class LargeFilesPagePage extends StatelessWidget {
|
||||
final String tagPrefix;
|
||||
@@ -84,15 +85,18 @@ class LargeFilesPagePage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
gallery,
|
||||
FileSelectionOverlayBar(
|
||||
overlayType,
|
||||
_selectedFiles,
|
||||
),
|
||||
],
|
||||
body: SelectionState(
|
||||
selectedFiles: _selectedFiles,
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
gallery,
|
||||
FileSelectionOverlayBar(
|
||||
overlayType,
|
||||
_selectedFiles,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import 'package:photos/ui/common/bottom_shadow.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/gallery_app_bar_widget.dart';
|
||||
import "package:photos/ui/viewer/gallery/state/selection_state.dart";
|
||||
import 'package:photos/utils/delete_file_util.dart';
|
||||
|
||||
class TrashPage extends StatelessWidget {
|
||||
@@ -65,32 +66,35 @@ class TrashPage extends StatelessWidget {
|
||||
_selectedFiles,
|
||||
),
|
||||
),
|
||||
body: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
gallery,
|
||||
const BottomShadowWidget(
|
||||
offsetDy: 20,
|
||||
),
|
||||
AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
height: filesAreSelected ? 0 : 80,
|
||||
child: AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 100),
|
||||
opacity: filesAreSelected ? 0.0 : 1.0,
|
||||
curve: Curves.easeIn,
|
||||
child: IgnorePointer(
|
||||
ignoring: filesAreSelected,
|
||||
child: const SafeArea(
|
||||
minimum: EdgeInsets.only(bottom: 6),
|
||||
child: BottomButtonsWidget(),
|
||||
body: SelectionState(
|
||||
selectedFiles: _selectedFiles,
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
gallery,
|
||||
const BottomShadowWidget(
|
||||
offsetDy: 20,
|
||||
),
|
||||
AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
height: filesAreSelected ? 0 : 80,
|
||||
child: AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 100),
|
||||
opacity: filesAreSelected ? 0.0 : 1.0,
|
||||
curve: Curves.easeIn,
|
||||
child: IgnorePointer(
|
||||
ignoring: filesAreSelected,
|
||||
child: const SafeArea(
|
||||
minimum: EdgeInsets.only(bottom: 6),
|
||||
child: BottomButtonsWidget(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
FileSelectionOverlayBar(GalleryType.trash, _selectedFiles),
|
||||
],
|
||||
FileSelectionOverlayBar(GalleryType.trash, _selectedFiles),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import 'package:photos/services/ignored_files_service.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/gallery_app_bar_widget.dart';
|
||||
import "package:photos/ui/viewer/gallery/state/selection_state.dart";
|
||||
|
||||
class UnCategorizedPage extends StatelessWidget {
|
||||
final String tagPrefix;
|
||||
@@ -82,15 +83,18 @@ class UnCategorizedPage extends StatelessWidget {
|
||||
collection: collection,
|
||||
),
|
||||
),
|
||||
body: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
gallery,
|
||||
FileSelectionOverlayBar(
|
||||
overlayType,
|
||||
_selectedFiles,
|
||||
),
|
||||
],
|
||||
body: SelectionState(
|
||||
selectedFiles: _selectedFiles,
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
gallery,
|
||||
FileSelectionOverlayBar(
|
||||
overlayType,
|
||||
_selectedFiles,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import "package:photos/ui/components/title_bar_title_widget.dart";
|
||||
import "package:photos/ui/components/title_bar_widget.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";
|
||||
import "package:photos/ui/viewer/location/edit_location_sheet.dart";
|
||||
import "package:photos/utils/dialog_util.dart";
|
||||
|
||||
@@ -231,40 +232,43 @@ class _LocationGalleryWidgetState extends State<LocationGalleryWidget> {
|
||||
key: ValueKey("$centerPoint$selectedRadius"),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
Gallery(
|
||||
loadingWidget: Column(
|
||||
children: [
|
||||
galleryHeaderWidget,
|
||||
EnteLoadingWidget(
|
||||
color: getEnteColorScheme(context).strokeMuted,
|
||||
),
|
||||
],
|
||||
return SelectionState(
|
||||
selectedFiles: _selectedFiles,
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
Gallery(
|
||||
loadingWidget: Column(
|
||||
children: [
|
||||
galleryHeaderWidget,
|
||||
EnteLoadingWidget(
|
||||
color: getEnteColorScheme(context).strokeMuted,
|
||||
),
|
||||
],
|
||||
),
|
||||
header: galleryHeaderWidget,
|
||||
asyncLoader: (
|
||||
creationStartTime,
|
||||
creationEndTime, {
|
||||
limit,
|
||||
asc,
|
||||
}) async {
|
||||
return snapshot.data as FileLoadResult;
|
||||
},
|
||||
reloadEvent: Bus.instance.on<LocalPhotosUpdatedEvent>(),
|
||||
removalEventTypes: const {
|
||||
EventType.deletedFromRemote,
|
||||
EventType.deletedFromEverywhere,
|
||||
},
|
||||
selectedFiles: _selectedFiles,
|
||||
tagPrefix: widget.tagPrefix,
|
||||
),
|
||||
header: galleryHeaderWidget,
|
||||
asyncLoader: (
|
||||
creationStartTime,
|
||||
creationEndTime, {
|
||||
limit,
|
||||
asc,
|
||||
}) async {
|
||||
return snapshot.data as FileLoadResult;
|
||||
},
|
||||
reloadEvent: Bus.instance.on<LocalPhotosUpdatedEvent>(),
|
||||
removalEventTypes: const {
|
||||
EventType.deletedFromRemote,
|
||||
EventType.deletedFromEverywhere,
|
||||
},
|
||||
selectedFiles: _selectedFiles,
|
||||
tagPrefix: widget.tagPrefix,
|
||||
),
|
||||
FileSelectionOverlayBar(
|
||||
GalleryType.locationTag,
|
||||
_selectedFiles,
|
||||
),
|
||||
],
|
||||
FileSelectionOverlayBar(
|
||||
GalleryType.locationTag,
|
||||
_selectedFiles,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Column(
|
||||
|
||||
@@ -15,6 +15,7 @@ import 'package:photos/models/selected_files.dart';
|
||||
import "package:photos/services/machine_learning/face_ml/feedback/cluster_feedback.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";
|
||||
import "package:photos/ui/viewer/people/add_person_action_sheet.dart";
|
||||
import "package:photos/ui/viewer/people/cluster_app_bar.dart";
|
||||
import "package:photos/ui/viewer/people/people_banner.dart";
|
||||
@@ -57,7 +58,8 @@ class _ClusterPageState extends State<ClusterPage> {
|
||||
late final StreamSubscription<LocalPhotosUpdatedEvent> _filesUpdatedEvent;
|
||||
late final StreamSubscription<PeopleChangedEvent> _peopleChangedEvent;
|
||||
|
||||
bool get showNamingBanner => (!userDismissedNamingBanner && widget.showNamingBanner);
|
||||
bool get showNamingBanner =>
|
||||
(!userDismissedNamingBanner && widget.showNamingBanner);
|
||||
|
||||
bool userDismissedNamingBanner = false;
|
||||
|
||||
@@ -66,7 +68,8 @@ class _ClusterPageState extends State<ClusterPage> {
|
||||
super.initState();
|
||||
ClusterFeedbackService.setLastViewedClusterID(widget.clusterID);
|
||||
files = widget.searchResult;
|
||||
_filesUpdatedEvent = Bus.instance.on<LocalPhotosUpdatedEvent>().listen((event) {
|
||||
_filesUpdatedEvent =
|
||||
Bus.instance.on<LocalPhotosUpdatedEvent>().listen((event) {
|
||||
if (event.type == EventType.deletedFromDevice ||
|
||||
event.type == EventType.deletedFromEverywhere ||
|
||||
event.type == EventType.deletedFromRemote ||
|
||||
@@ -111,7 +114,8 @@ class _ClusterPageState extends State<ClusterPage> {
|
||||
final result = files
|
||||
.where(
|
||||
(file) =>
|
||||
file.creationTime! >= creationStartTime && file.creationTime! <= creationEndTime,
|
||||
file.creationTime! >= creationStartTime &&
|
||||
file.creationTime! <= creationEndTime,
|
||||
)
|
||||
.toList();
|
||||
return Future.value(
|
||||
@@ -148,16 +152,19 @@ class _ClusterPageState extends State<ClusterPage> {
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
gallery,
|
||||
FileSelectionOverlayBar(
|
||||
ClusterPage.overlayType,
|
||||
_selectedFiles,
|
||||
clusterID: widget.clusterID,
|
||||
),
|
||||
],
|
||||
child: SelectionState(
|
||||
selectedFiles: _selectedFiles,
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
gallery,
|
||||
FileSelectionOverlayBar(
|
||||
ClusterPage.overlayType,
|
||||
_selectedFiles,
|
||||
clusterID: widget.clusterID,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
showNamingBanner
|
||||
@@ -185,7 +192,8 @@ class _ClusterPageState extends State<ClusterPage> {
|
||||
context,
|
||||
clusterID: widget.clusterID,
|
||||
);
|
||||
if (result != null && result is (PersonEntity, EnteFile)) {
|
||||
if (result != null &&
|
||||
result is (PersonEntity, EnteFile)) {
|
||||
Navigator.pop(context);
|
||||
// ignore: unawaited_futures
|
||||
routeToPage(context, PeoplePage(person: result.$1));
|
||||
|
||||
@@ -17,6 +17,7 @@ import "package:photos/services/machine_learning/face_ml/feedback/cluster_feedba
|
||||
import "package:photos/services/search_service.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";
|
||||
import "package:photos/ui/viewer/people/people_app_bar.dart";
|
||||
import "package:photos/ui/viewer/people/people_banner.dart";
|
||||
import "package:photos/ui/viewer/people/person_cluster_suggestion.dart";
|
||||
@@ -127,44 +128,48 @@ class _PeoplePageState extends State<PeoplePage> {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
Gallery(
|
||||
asyncLoader: (
|
||||
creationStartTime,
|
||||
creationEndTime, {
|
||||
limit,
|
||||
asc,
|
||||
}) async {
|
||||
final result = await loadPersonFiles();
|
||||
return Future.value(
|
||||
FileLoadResult(
|
||||
result,
|
||||
false,
|
||||
),
|
||||
);
|
||||
},
|
||||
reloadEvent: Bus.instance.on<LocalPhotosUpdatedEvent>(),
|
||||
forceReloadEvents: [
|
||||
Bus.instance.on<PeopleChangedEvent>(),
|
||||
],
|
||||
removalEventTypes: const {
|
||||
EventType.deletedFromRemote,
|
||||
EventType.deletedFromEverywhere,
|
||||
EventType.hide,
|
||||
},
|
||||
tagPrefix: widget.tagPrefix + widget.tagPrefix,
|
||||
selectedFiles: _selectedFiles,
|
||||
initialFiles:
|
||||
personFiles.isNotEmpty ? [personFiles.first] : [],
|
||||
),
|
||||
FileSelectionOverlayBar(
|
||||
PeoplePage.overlayType,
|
||||
_selectedFiles,
|
||||
person: widget.person,
|
||||
),
|
||||
],
|
||||
child: SelectionState(
|
||||
selectedFiles: _selectedFiles,
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
Gallery(
|
||||
asyncLoader: (
|
||||
creationStartTime,
|
||||
creationEndTime, {
|
||||
limit,
|
||||
asc,
|
||||
}) async {
|
||||
final result = await loadPersonFiles();
|
||||
return Future.value(
|
||||
FileLoadResult(
|
||||
result,
|
||||
false,
|
||||
),
|
||||
);
|
||||
},
|
||||
reloadEvent:
|
||||
Bus.instance.on<LocalPhotosUpdatedEvent>(),
|
||||
forceReloadEvents: [
|
||||
Bus.instance.on<PeopleChangedEvent>(),
|
||||
],
|
||||
removalEventTypes: const {
|
||||
EventType.deletedFromRemote,
|
||||
EventType.deletedFromEverywhere,
|
||||
EventType.hide,
|
||||
},
|
||||
tagPrefix: widget.tagPrefix + widget.tagPrefix,
|
||||
selectedFiles: _selectedFiles,
|
||||
initialFiles:
|
||||
personFiles.isNotEmpty ? [personFiles.first] : [],
|
||||
),
|
||||
FileSelectionOverlayBar(
|
||||
PeoplePage.overlayType,
|
||||
_selectedFiles,
|
||||
person: widget.person,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
showSuggestionBanner
|
||||
|
||||
Reference in New Issue
Block a user