206 lines
6.3 KiB
Dart
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)
|
|
],
|
|
);
|
|
}
|
|
}
|