2023-04-04 09:43:22 +00:00
|
|
|
import "dart:math";
|
|
|
|
|
|
|
|
import "package:flutter/material.dart";
|
|
|
|
import "package:modal_bottom_sheet/modal_bottom_sheet.dart";
|
2023-04-13 10:17:55 +00:00
|
|
|
import "package:photos/core/constants.dart";
|
|
|
|
import "package:photos/core/event_bus.dart";
|
2023-04-04 11:20:53 +00:00
|
|
|
import "package:photos/db/files_db.dart";
|
2023-04-13 10:17:55 +00:00
|
|
|
import "package:photos/events/local_photos_updated_event.dart";
|
2023-04-12 07:16:10 +00:00
|
|
|
import "package:photos/generated/l10n.dart";
|
2023-04-07 09:44:34 +00:00
|
|
|
import "package:photos/models/file.dart";
|
2023-04-04 11:20:53 +00:00
|
|
|
import "package:photos/models/file_load_result.dart";
|
2023-04-05 04:00:18 +00:00
|
|
|
import "package:photos/models/local_entity_data.dart";
|
2023-04-04 09:43:22 +00:00
|
|
|
import "package:photos/models/location_tag/location_tag.dart";
|
2023-04-04 11:20:53 +00:00
|
|
|
import "package:photos/models/selected_files.dart";
|
|
|
|
import "package:photos/services/collections_service.dart";
|
|
|
|
import "package:photos/services/ignored_files_service.dart";
|
2023-04-04 09:43:22 +00:00
|
|
|
import "package:photos/theme/colors.dart";
|
|
|
|
import "package:photos/theme/ente_theme.dart";
|
|
|
|
import "package:photos/ui/components/bottom_of_title_bar_widget.dart";
|
|
|
|
import "package:photos/ui/components/buttons/button_widget.dart";
|
|
|
|
import "package:photos/ui/components/models/button_type.dart";
|
|
|
|
import "package:photos/ui/components/title_bar_title_widget.dart";
|
2023-04-04 11:20:53 +00:00
|
|
|
import "package:photos/ui/viewer/gallery/gallery.dart";
|
2023-04-04 09:43:22 +00:00
|
|
|
|
2023-04-07 09:44:34 +00:00
|
|
|
Future<File?> showPickCenterPointSheet(
|
2023-04-04 09:43:22 +00:00
|
|
|
BuildContext context,
|
2023-04-05 04:00:18 +00:00
|
|
|
LocalEntity<LocationTag> locationTagEntity,
|
2023-04-07 09:44:34 +00:00
|
|
|
) async {
|
|
|
|
return await showBarModalBottomSheet(
|
2023-04-04 09:43:22 +00:00
|
|
|
context: context,
|
|
|
|
builder: (context) {
|
2023-04-05 10:54:39 +00:00
|
|
|
return PickCenterPointWidget(locationTagEntity);
|
2023-04-04 09:43:22 +00:00
|
|
|
},
|
|
|
|
shape: const RoundedRectangleBorder(
|
|
|
|
side: BorderSide(width: 0),
|
|
|
|
borderRadius: BorderRadius.vertical(
|
|
|
|
top: Radius.circular(5),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
topControl: const SizedBox.shrink(),
|
|
|
|
backgroundColor: getEnteColorScheme(context).backgroundElevated,
|
|
|
|
barrierColor: backdropFaintDark,
|
2023-04-04 11:20:53 +00:00
|
|
|
enableDrag: false,
|
2023-04-04 09:43:22 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
class PickCenterPointWidget extends StatelessWidget {
|
2023-04-05 04:00:18 +00:00
|
|
|
final LocalEntity<LocationTag> locationTagEntity;
|
2023-04-04 09:43:22 +00:00
|
|
|
|
|
|
|
const PickCenterPointWidget(
|
2023-04-05 10:54:39 +00:00
|
|
|
this.locationTagEntity, {
|
2023-04-04 09:43:22 +00:00
|
|
|
super.key,
|
|
|
|
});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2023-04-04 11:46:33 +00:00
|
|
|
final ValueNotifier<bool> isFileSelected = ValueNotifier(false);
|
2023-04-04 11:20:53 +00:00
|
|
|
final selectedFiles = SelectedFiles();
|
2023-04-04 11:46:33 +00:00
|
|
|
selectedFiles.addListener(() {
|
|
|
|
isFileSelected.value = selectedFiles.files.isNotEmpty;
|
|
|
|
});
|
|
|
|
|
2023-04-04 09:43:22 +00:00
|
|
|
return Padding(
|
|
|
|
padding: const EdgeInsets.all(0),
|
|
|
|
child: Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
ConstrainedBox(
|
|
|
|
constraints: BoxConstraints(
|
|
|
|
maxWidth: min(428, MediaQuery.of(context).size.width),
|
|
|
|
),
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.fromLTRB(0, 32, 0, 8),
|
|
|
|
child: Column(
|
|
|
|
mainAxisSize: MainAxisSize.max,
|
|
|
|
children: [
|
|
|
|
Expanded(
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
BottomOfTitleBarWidget(
|
2023-04-12 07:16:10 +00:00
|
|
|
title: TitleBarTitleWidget(
|
|
|
|
title: S.of(context).pickCenterPoint,
|
2023-04-04 09:43:22 +00:00
|
|
|
),
|
2023-04-05 04:00:18 +00:00
|
|
|
caption: locationTagEntity.item.name,
|
2023-04-04 09:43:22 +00:00
|
|
|
),
|
2023-04-04 11:20:53 +00:00
|
|
|
Expanded(
|
|
|
|
child: Gallery(
|
|
|
|
asyncLoader: (
|
|
|
|
creationStartTime,
|
|
|
|
creationEndTime, {
|
|
|
|
limit,
|
|
|
|
asc,
|
|
|
|
}) async {
|
|
|
|
final collectionsToHide = CollectionsService
|
|
|
|
.instance
|
|
|
|
.collectionsHiddenFromTimeline();
|
|
|
|
FileLoadResult result;
|
2023-04-13 10:17:55 +00:00
|
|
|
result = await FilesDB.instance
|
|
|
|
.fetchAllUploadedAndSharedFilesWithLocation(
|
|
|
|
galleryLoadStartTime,
|
|
|
|
galleryLoadEndTime,
|
|
|
|
limit: null,
|
|
|
|
asc: false,
|
|
|
|
ignoredCollectionIDs: collectionsToHide,
|
|
|
|
);
|
2023-04-04 11:20:53 +00:00
|
|
|
|
2023-04-13 10:17:55 +00:00
|
|
|
// hide ignored files from UI
|
2023-04-04 11:20:53 +00:00
|
|
|
final ignoredIDs =
|
|
|
|
await IgnoredFilesService.instance.ignoredIDs;
|
|
|
|
result.files.removeWhere(
|
|
|
|
(f) =>
|
|
|
|
f.uploadedFileID == null &&
|
|
|
|
IgnoredFilesService.instance
|
|
|
|
.shouldSkipUpload(ignoredIDs, f),
|
|
|
|
);
|
|
|
|
return result;
|
|
|
|
},
|
2023-04-13 10:17:55 +00:00
|
|
|
reloadEvent:
|
|
|
|
Bus.instance.on<LocalPhotosUpdatedEvent>(),
|
2023-04-04 11:20:53 +00:00
|
|
|
tagPrefix: "pick_center_point_gallery",
|
|
|
|
selectedFiles: selectedFiles,
|
|
|
|
limitSelectionToOne: true,
|
|
|
|
),
|
|
|
|
),
|
2023-04-04 09:43:22 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
SafeArea(
|
|
|
|
child: Container(
|
|
|
|
//inner stroke of 1pt + 15 pts of top padding = 16 pts
|
|
|
|
padding: const EdgeInsets.fromLTRB(16, 15, 16, 8),
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
border: Border(
|
|
|
|
top: BorderSide(
|
|
|
|
color: getEnteColorScheme(context).strokeFaint,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
2023-04-04 11:46:33 +00:00
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
ValueListenableBuilder(
|
|
|
|
valueListenable: isFileSelected,
|
|
|
|
builder: (context, bool value, _) {
|
|
|
|
return AnimatedSwitcher(
|
|
|
|
duration: const Duration(milliseconds: 300),
|
|
|
|
switchInCurve: Curves.easeInOutExpo,
|
|
|
|
switchOutCurve: Curves.easeInOutExpo,
|
|
|
|
child: ButtonWidget(
|
|
|
|
key: ValueKey(value),
|
|
|
|
isDisabled: !value,
|
|
|
|
buttonType: ButtonType.neutral,
|
2023-04-12 07:16:10 +00:00
|
|
|
labelText: S.of(context).useSelectedPhoto,
|
2023-04-05 05:23:29 +00:00
|
|
|
onTap: () async {
|
|
|
|
final selectedFile =
|
|
|
|
selectedFiles.files.first;
|
2023-04-07 09:44:34 +00:00
|
|
|
Navigator.pop(context, selectedFile);
|
2023-04-05 05:23:29 +00:00
|
|
|
},
|
2023-04-04 11:46:33 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
const SizedBox(height: 8),
|
2023-04-07 10:11:50 +00:00
|
|
|
ButtonWidget(
|
2023-04-04 11:46:33 +00:00
|
|
|
buttonType: ButtonType.secondary,
|
|
|
|
buttonAction: ButtonAction.cancel,
|
2023-04-12 07:16:10 +00:00
|
|
|
labelText: S.of(context).cancel,
|
2023-04-07 10:11:50 +00:00
|
|
|
onTap: () async {
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
},
|
2023-04-04 11:46:33 +00:00
|
|
|
),
|
|
|
|
],
|
2023-04-04 09:43:22 +00:00
|
|
|
),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|