Files
eatvio_app/lib/features/chat/presentation/pages/photo_view_screen.dart

126 lines
4.4 KiB
Dart

import 'package:cached_network_image/cached_network_image.dart';
import 'package:dismissible_page/dismissible_page.dart';
import 'package:eatvio_app/core/app_config.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/theme/app_decoration.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';
import 'package:url_launcher/url_launcher.dart';
class PhotoViewScreen extends StatefulWidget {
final List<dynamic> imageUrls;
final int index;
final bool isLocal;
const PhotoViewScreen({
super.key,
required this.imageUrls,
required this.index,
this.isLocal = false,
});
@override
State<PhotoViewScreen> createState() => _PhotoViewScreenState();
}
class _PhotoViewScreenState extends State<PhotoViewScreen> {
late final PageController pageController;
int imageIndex = 0;
@override
void initState() {
imageIndex = widget.index;
pageController = PageController(initialPage: imageIndex);
super.initState();
}
@override
Widget build(BuildContext context) {
return DismissiblePage(
minScale: 1,
onDismissed: () => GoRouter.of(context).pop(),
direction: DismissiblePageDismissDirection.vertical,
isFullScreen: true,
child: PhotoViewGallery.builder(
backgroundDecoration: const BoxDecoration(
color: Colors.transparent,
),
scrollPhysics: const BouncingScrollPhysics(),
builder: (BuildContext context, int index) {
final imageProvider = widget.isLocal
? FileImage(widget.imageUrls[index]) as ImageProvider<Object>
: CachedNetworkImageProvider(widget.imageUrls[index]) as ImageProvider<Object>;
return PhotoViewGalleryPageOptions(
imageProvider: imageProvider,
initialScale: PhotoViewComputedScale.contained,
minScale: PhotoViewComputedScale.contained,
heroAttributes: PhotoViewHeroAttributes(
tag: widget.imageUrls[index],
transitionOnUserGestures: true,
),
errorBuilder: (context, object, stackTrace) {
return Scaffold(
backgroundColor: Colors.black,
body: SafeArea(
child: Column(
children: [
const SizedBox(height: 32),
const Text('Файл'),
const SizedBox(height: 8),
ListTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadiusStyle.circleBorder17,
),
contentPadding: const EdgeInsets.all(16),
onTap: () async {
if (!await launchUrl(Uri.parse(widget.imageUrls[index]))) {
throw Exception('Could not launch ${widget.imageUrls[index]}');
}
},
leading: const Icon(
Icons.file_copy_outlined,
color: Colors.white,
),
trailing: const Icon(
Icons.download_outlined,
color: Colors.white,
),
title: Text(
widget.imageUrls[index].replaceAll('${sl<AppConfig>().baseUrl}/storage/chat_files/', ''),
style: const TextStyle(
color: Colors.white,
fontSize: 12,
),
),
),
],
),
),
);
},
);
},
itemCount: widget.imageUrls.length,
loadingBuilder: (context, event) => Center(
child: SizedBox(
width: 20.0,
height: 20.0,
child: CircularProgressIndicator(
value: event == null ? 0 : event.cumulativeBytesLoaded / event.expectedTotalBytes!,
),
),
),
pageController: pageController,
onPageChanged: (page) {
setState(() {
imageIndex = page;
});
},
),
);
}
}