proxibuy/lib/presentation/ui/widgets/dialog/image_gallary.dart

181 lines
6.0 KiB
Dart

import 'package:carousel_slider/carousel_controller.dart';
import 'package:flutter/material.dart';
import 'package:proxibuy/presentation/ui/theme/responsive.dart';
import 'package:proxibuy/presentation/ui/widgets/carousel/carousel_slider_widget.dart';
// TutorialOverlay
class ImageGallary extends ModalRoute<void> {
final List<String> urls;
final String initialUrl;
final CarouselSliderController carouselSliderController =
CarouselSliderController();
ImageGallary({required this.urls, required this.initialUrl});
@override
Duration get transitionDuration => Duration(milliseconds: 500);
@override
bool get opaque => false;
@override
bool get barrierDismissible => true;
@override
Color get barrierColor => Colors.black.withAlpha(210);
@override
String get barrierLabel => 'Images';
@override
bool get maintainState => true;
@override
Widget buildPage(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
return Material(
type: MaterialType.transparency,
child: SafeArea(
child: _buildOverlayContent(context),
),
);
}
late final ValueNotifier<String> initialImage = ValueNotifier(initialUrl);
Widget _buildOverlayContent(BuildContext context) {
double viewportFraction =
(1 / (urls.length * (MediaQuery.sizeOf(context).width / 1300)));
return Stack(
children: [
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints: BoxConstraints(
maxHeight: MediaQuery.sizeOf(context).height / 2),
child: ValueListenableBuilder(
valueListenable: initialImage,
builder: (context, value, child) {
return InteractiveViewer(
boundaryMargin: EdgeInsets.all(80),
minScale: 0.5,
maxScale: 4,
panEnabled: true,
child: AspectRatio(
aspectRatio:
Responsive(context).isMobile() ? 1 / 1 : 16 / 9,
child: Container(
margin: const EdgeInsets.all(32.0),
child: GestureDetector(
onHorizontalDragEnd: (details) {
if (details.primaryVelocity! < 0) {
// Swiped left
carouselSliderController.nextPage();
} else if (details.primaryVelocity! > 0) {
// Swiped right
carouselSliderController.previousPage();
}
},
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(
value,
),
),
),
),
),
);
},
),
),
CarouselSliderWidget(
controller: carouselSliderController
..onReady.then(
(value) {
carouselSliderController
.jumpToPage(urls.indexOf(initialImage.value));
},
),
items: urls,
withInds: false,
autoPlay: false,
enableInfiniteScroll: false,
enlargeCenterPage: false,
viewportFraction: viewportFraction,
aspectRatio: 1 / 1,
height: 120,
onPageChanged: (index, reason) {
initialImage.value = urls[index];
},
onPageBuilder: (context, item, index) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.only(
topLeft:
index == 0 ? Radius.circular(16) : Radius.zero,
bottomLeft:
index == 0 ? Radius.circular(16) : Radius.zero,
bottomRight: index == urls.length - 1
? Radius.circular(16)
: Radius.zero,
topRight: index == urls.length - 1
? Radius.circular(16)
: Radius.zero)),
padding: EdgeInsets.all(16),
child: InkWell(
onTap: () {
carouselSliderController.animateToPage(index);
},
child: SizedBox(
child: Image.network(
item,
fit: BoxFit.cover,
),
),
),
);
},
),
],
),
Positioned(
top: 32,
left: 32,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(8)),
padding: EdgeInsets.all(8),
child: Icon(Icons.arrow_back_ios_new_rounded),
),
),
),
],
);
}
@override
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
// You can add your own animations for the overlay content
return FadeTransition(
opacity: animation,
child: ScaleTransition(
scale: animation,
child: child,
),
);
}
}