ente/lib/ui/map/map_pull_up_gallery.dart

157 lines
5.6 KiB
Dart

import "dart:async";
import "package:flutter/material.dart";
import "package:logging/logging.dart";
import "package:photos/core/event_bus.dart";
import "package:photos/events/local_photos_updated_event.dart";
import "package:photos/models/file.dart";
import "package:photos/models/file_load_result.dart";
import "package:photos/models/selected_files.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/common/loading_widget.dart";
import "package:photos/ui/viewer/gallery/gallery.dart";
class MapPullUpGallery extends StatelessWidget {
final _selectedFiles = SelectedFiles();
final StreamController<List<File>> visibleImages;
final double bottomSheetDraggableAreaHeight;
static const gridCrossAxisSpacing = 4.0;
static const gridMainAxisSpacing = 4.0;
static const gridPadding = 2.0;
static const gridCrossAxisCount = 4;
MapPullUpGallery(
this.visibleImages,
this.bottomSheetDraggableAreaHeight, {
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final Logger logger = Logger("_MapPullUpGalleryState");
final textTheme = getEnteTextTheme(context);
const double initialChildSize = 0.25;
return DraggableScrollableSheet(
expand: false,
initialChildSize: initialChildSize,
minChildSize: initialChildSize,
maxChildSize: 0.8,
snap: true,
snapSizes: const [0.5],
builder: (context, scrollController) {
return Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
color: getEnteColorScheme(context).backgroundElevated,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
DraggableHeader(
scrollController: scrollController,
bottomSheetDraggableAreaHeight: bottomSheetDraggableAreaHeight,
),
Expanded(
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
switchInCurve: Curves.easeInOutExpo,
switchOutCurve: Curves.easeInOutExpo,
child: StreamBuilder<List<File>>(
stream: visibleImages.stream,
builder: (
BuildContext context,
AsyncSnapshot<List<File>> snapshot,
) {
if (!snapshot.hasData) {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.2,
child: const EnteLoadingWidget(),
);
}
final images = snapshot.data!;
logger.info("Visible images: ${images.length}");
if (images.isEmpty) {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.2,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"No photos found here",
style: textTheme.large,
),
const SizedBox(height: 4),
Text(
"Zoom out to see photos",
style: textTheme.smallFaint,
)
],
),
),
);
}
return Gallery(
asyncLoader: (
creationStartTime,
creationEndTime, {
limit,
asc,
}) async {
FileLoadResult result;
result = FileLoadResult(images, false);
return result;
},
reloadEvent: Bus.instance.on<LocalPhotosUpdatedEvent>(),
tagPrefix: "map_gallery",
showSelectAllByDefault: true,
selectedFiles: _selectedFiles,
isScrollablePositionedList: false,
);
},
),
),
)
],
),
);
},
);
}
}
class DraggableHeader extends StatelessWidget {
const DraggableHeader({
Key? key,
required this.scrollController,
required this.bottomSheetDraggableAreaHeight,
}) : super(key: key);
static const indicatorHeight = 4.0;
final ScrollController scrollController;
final double bottomSheetDraggableAreaHeight;
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
physics: const ClampingScrollPhysics(),
controller: scrollController,
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(
vertical: bottomSheetDraggableAreaHeight / 2 - indicatorHeight / 2,
),
child: Container(
height: indicatorHeight,
width: 72,
decoration: BoxDecoration(
color: getEnteColorScheme(context).fillBase,
borderRadius: const BorderRadius.all(Radius.circular(2)),
),
),
),
),
);
}
}