relatica/lib/screens/gallery_screen.dart
2023-01-29 17:21:47 -05:00

147 lines
4.7 KiB
Dart

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:provider/provider.dart';
import '../controls/standard_appbar.dart';
import '../globals.dart';
import '../serializers/friendica/image_entry_friendica_extensions.dart';
import '../services/gallery_service.dart';
import '../services/network_status_service.dart';
import 'image_viewer_screen.dart';
class GalleryScreen extends StatelessWidget {
static const thumbnailDimension = 350.0;
static final _logger = Logger('$GalleryScreen');
final String galleryName;
const GalleryScreen({super.key, required this.galleryName});
@override
Widget build(BuildContext context) {
_logger.finest('Building');
final nss = getIt<NetworkStatusService>();
final service = context.watch<GalleryService>();
final body = service.getGallery(galleryName).fold(
onSuccess: (galleryData) =>
buildBody(context, service, galleryData.count),
onError: (error) => buildErrorBody(error.message),
);
return Scaffold(
appBar: StandardAppBar.build(context, galleryName, actions: [
ValueListenableBuilder(
valueListenable: nss.imageGalleryLoadingStatus,
builder: (context2, executing, _) {
if (executing) {
final theme = Theme.of(context);
final size = theme.appBarTheme.actionsIconTheme?.size ??
theme.iconTheme.size ??
24;
return Center(
child: SizedBox(
width: size,
height: size,
child: CircularProgressIndicator(
color: Theme.of(context).canvasColor),
),
);
}
return IconButton(
onPressed: () async => await service.updateGalleryImageList(
galleryName: galleryName,
withNextPage: false,
nextPageOnly: false,
),
icon: Icon(
Icons.refresh,
));
}),
]),
body: body,
);
}
Widget buildErrorBody(String error) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Error getting images for gallery: $error'),
],
),
);
}
Widget buildBody(
BuildContext context,
GalleryService service,
int expectedPhotoCount,
) {
final imageResult = service.getGalleryImageList(galleryName);
if (imageResult.isFailure) {
return buildErrorBody(imageResult.error.message);
}
final images = imageResult.value;
final attachments = images.map((i) => i.toMediaAttachment()).toList();
if (images.isEmpty && service.loaded) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Text('No images'),
],
),
);
}
if (images.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Text('Loading images'),
],
),
);
}
return GridView.builder(
itemCount: images.length,
padding: const EdgeInsets.all(5.0),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: thumbnailDimension),
itemBuilder: (context, index) {
final image = images[index];
if (images.length < expectedPhotoCount &&
index == images.length - 1) {
service.updateGalleryImageList(
galleryName: galleryName,
withNextPage: true,
nextPageOnly: true,
);
}
return Padding(
padding: const EdgeInsets.all(2.0),
child: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ImageViewerScreen(
attachments: attachments,
initialIndex: index,
);
}));
},
child: CachedNetworkImage(
width: thumbnailDimension,
height: thumbnailDimension,
imageUrl: image.thumbnailUrl,
),
),
);
});
}
}