Houshan-Basa/lib/ui/widgets/components/slider/carousle_slider_banners.dart

162 lines
6.1 KiB
Dart

import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hoshan/core/routes/route_generator.dart';
import 'package:hoshan/data/model/banner_model.dart';
import 'package:hoshan/data/model/chat_args.dart';
import 'package:hoshan/ui/screens/main/home_page.dart';
import 'package:hoshan/ui/theme/colors.dart';
import 'package:hoshan/ui/theme/responsive.dart';
import 'package:hoshan/ui/widgets/components/image/network_image.dart';
import 'package:hoshan/ui/widgets/components/slider/custom_carousel_controller.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:string_validator/string_validator.dart';
import 'package:url_launcher/url_launcher.dart';
class CarousleSliderBanners extends StatefulWidget {
final List<Banners> banners;
final bool autoPlay;
final bool enableInfiniteScroll;
final Function(Banners banner)? onClick;
const CarousleSliderBanners(
{super.key,
required this.banners,
this.autoPlay = true,
this.enableInfiniteScroll = true,
this.onClick});
@override
State<CarousleSliderBanners> createState() => _CarousleSliderBannersState();
}
class _CarousleSliderBannersState extends State<CarousleSliderBanners> {
final CustomCarouselController _buttonCarouselController =
CustomCarouselController();
@override
Widget build(BuildContext context) {
final isWeb =
Responsive(context).isDesktop(); // Check if the platform is web
final isTab =
Responsive(context).isTablet(); // Check if the platform is tablet
final CarouselOptions carouselOptions = CarouselOptions(
viewportFraction: isWeb
? 0.25 // Show 4 banners per slide on web
: isTab
? 0.33 // Show 3 banners per slide on tablets
: 1, // Default to 1 banner per slide
initialPage: 0,
disableCenter: false,
enableInfiniteScroll: widget.enableInfiniteScroll,
reverse: false,
autoPlay: widget.autoPlay,
autoPlayCurve: Curves.fastOutSlowIn,
enlargeCenterPage: true,
enlargeFactor: 0,
onPageChanged: (index, _) {},
scrollDirection: Axis.horizontal,
aspectRatio: 16 / 9,
height: isWeb
? MediaQuery.sizeOf(context).height * 0.2
: isTab
? MediaQuery.sizeOf(context).height * 0.25
: null, // Adjust height for web and tablets
);
return Column(
children: [
CarouselSlider.builder(
carouselController: _buttonCarouselController,
itemCount: widget.banners.length,
itemBuilder: (context, index, realIndex) {
final banner = widget.banners[index];
return GestureDetector(
onTap: () async {
if (banner.bot != null) {
if (banner.bot?.tool ?? false) {
context.go(Routes.assistant, extra: banner.bot!.id);
} else {
context.go(Routes.chat,
extra: ChatArgs(bot: banner.bot!));
}
} else if (banner.link != null) {
if (banner.link!.isURL()) {
await launchUrl(Uri.parse(banner.link!),
mode: LaunchMode.externalApplication)
.onError(
(error, stackTrace) {
if (kDebugMode) {
print('error open Link is: $error');
}
return false;
},
);
} else {
try {
if (banner.link!.contains('navigate')) {
int? index;
if (banner.link!.contains('home')) {
index = 0;
} else if (banner.link!.contains('assisstant')) {
index = 1;
} else if (banner.link!.contains('media')) {
index = 2;
} else if (banner.link!.contains('characters')) {
index = 3;
} else if (banner.link!.contains('setting')) {
index = 4;
}
screenIndex.value = index!;
} else {
context.go(banner.link!);
}
} catch (e) {
if (kDebugMode) {
print('Error is: $e');
}
}
}
}
widget.onClick?.call(banner);
},
child: sliderView(banner));
},
options: carouselOptions),
if (widget.banners.length > 1) sliderIndicator(),
],
);
}
Widget sliderView(Banners banner) {
return Padding(
padding: const EdgeInsets.all(16),
child: ImageNetwork(
width: double.infinity,
url: banner.image ?? '',
fit: BoxFit.contain,
radius: 16,
),
);
}
Widget sliderIndicator() {
return FutureBuilder(
future: _buttonCarouselController.onReady,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
_buttonCarouselController.state!.pageController!.addListener(() {});
return SmoothPageIndicator(
controller: _buttonCarouselController.state!.pageController!,
count: widget.banners.length,
effect: ScrollingDotsEffect(
dotWidth: 8,
dotHeight: 8,
activeDotColor: AppColors.secondryColor.defaultShade,
dotColor: AppColors.secondryColor[100]));
}
return const SizedBox();
});
}
}