THATMobile/lib/core/components/image/show_image.dart
2026-02-26 10:39:42 +07:00

206 lines
6.3 KiB
Dart

import 'package:baseproject/assets/images.dart';
import 'package:baseproject/core/common/loading.dart';
import 'package:baseproject/core/common/message.dart';
import 'package:baseproject/core/components/constants_widget.dart';
import 'package:baseproject/core/theme/custom_color.dart';
import 'package:baseproject/features/model/file/attach_file_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';
import 'package:gal/gal.dart';
Widget _buildDelete(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
child: Container(
padding: const EdgeInsets.all(4),
decoration: const BoxDecoration(
shape: BoxShape.circle,
),
child: const Icon(
Icons.close,
size: 20,
),
),
);
}
Widget _builSaveImage(String url) {
return Positioned.fill(
bottom: 20,
child: Align(
child: GestureDetector(
onTap: () async {
showLoading();
try {
await Gal.putImage(url);
hideLoading();
showSuccessMessage("Tải xuống thành công");
} catch (e) {
hideLoading();
showErrorMessage("Lỗi khi tải xuống: $e");
}
},
child: ConstantWidget.defaultContainer(
color: CustomColor.kBackgroundWhite.withOpacity(0.8),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
ConstantWidget.textBodyDefault("Tải xuống"),
ConstantWidget.widthSpace10,
const Icon(Icons.download)
],
),
),
),
alignment: Alignment.bottomCenter,
),
);
}
void showImages(BuildContext context, List<AttachFileModel> items, {int initialPage = 0}) {
int page = 0;
PageController _controller = PageController(initialPage: initialPage);
showGeneralDialog(
barrierLabel: "Barrier",
barrierDismissible: true,
barrierColor: CustomColor.barrierColor,
transitionDuration: const Duration(milliseconds: 350),
context: context,
pageBuilder: (_, __, ___) {
return Stack(
children: [
PhotoViewGallery.builder(
backgroundDecoration: BoxDecoration(color: CustomColor.barrierColor),
allowImplicitScrolling: false,
scrollPhysics: const BouncingScrollPhysics(),
builder: (BuildContext context, int index) {
return PhotoViewGalleryPageOptions(
imageProvider: NetworkImage(items[index].url),
initialScale: PhotoViewComputedScale.contained * 0.8,
heroAttributes: PhotoViewHeroAttributes(tag: items[index].title),
);
},
itemCount: items.length,
loadingBuilder: (context, event) => Center(
child: SizedBox(
width: 20.0,
height: 20.0,
child: CircularProgressIndicator(
value: event == null ? 0 : event.cumulativeBytesLoaded / (event.expectedTotalBytes ?? 1),
),
),
),
// backgroundDecoration: widget.backgroundDecoration,
pageController: _controller,
onPageChanged: (index) {
page = index;
},
),
Positioned(
child: _buildDelete(context),
right: 10,
top: 50,
),
_builSaveImage(items[page].url)
],
);
},
// transitionBuilder: (_, Animation<double> anim, __, Widget child) {
// return SlideTransition(
// position: Tween<Offset>(begin: const Offset(0, 1), end: const Offset(0, 0)).animate(anim),
// child: child,
// );
// },
);
}
void showImage(BuildContext context, String url) {
showGeneralDialog(
barrierLabel: "Barrier",
barrierDismissible: true,
barrierColor: CustomColor.barrierColor,
transitionDuration: const Duration(milliseconds: 350),
context: context,
pageBuilder: (_, __, ___) {
return ShowImageWidget(url: url);
},
// transitionBuilder: (_, Animation<double> anim, __, Widget child) {
// return SlideTransition(
// position: Tween<Offset>(begin: const Offset(0, 1), end: const Offset(0, 0)).animate(anim),
// child: child,
// );
// },
);
}
class ShowImageWidget extends StatelessWidget {
final String url;
const ShowImageWidget({Key? key, required this.url}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => Navigator.pop(context),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 40),
alignment: Alignment.center,
child: _buildPhotoView(context, url),
),
);
// return Dialog(
// child: Container(
// height: MediaQuery.of(context).size.height * 1 / 2,
// child: Center(
// child: Hero(
// tag: url,
// child: BNDImage(imageUrl: url, fit: BoxFit.fitWidth),
// ),
// ),
// ),
// );
}
Widget _buildImageDefault() {
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(Images.imageDefault),
fit: BoxFit.contain,
),
),
);
}
Widget _buildPhotoView(BuildContext context, String imageUrl) {
return Stack(
children: [
PhotoView(
imageProvider: NetworkImage(imageUrl),
loadingBuilder: (_, __) => const SpinKitCircle(
color: Colors.white,
size: 50.0,
),
errorBuilder: (_, __, ___) => _buildImageDefault(),
backgroundDecoration: const BoxDecoration(color: Colors.transparent),
maxScale: PhotoViewComputedScale.covered * 4.0,
minScale: PhotoViewComputedScale.contained * 1,
// onTapDown: (_, __, ___) => Navigator.pop(context),
// initialScale: PhotoViewComputedScale.covered,
),
Positioned(
child: _buildDelete(context),
right: 10,
top: 50,
),
_builSaveImage(imageUrl)
],
);
}
}