import 'package:carousel_slider/carousel_slider.dart'; import 'package:didvan/utils/date_time.dart'; import 'package:didvan/widgets/didvan/card.dart'; import 'package:didvan/widgets/didvan/divider.dart'; import 'package:didvan/widgets/didvan/text.dart'; import 'package:didvan/widgets/skeleton_image.dart'; import 'package:didvan/pages/home/widgets/tag_item.dart'; import 'package:flutter/material.dart'; import 'package:flutter_html/flutter_html.dart'; class DidvanPageView extends StatefulWidget { final List items; final int initialIndex; final int currentIndex; final bool isRadar; final ScrollController scrollController; final void Function(int index) onPageChanged; const DidvanPageView({ Key? key, required this.initialIndex, required this.items, required this.scrollController, required this.onPageChanged, required this.isRadar, required this.currentIndex, }) : super(key: key); @override State createState() => _DidvanPageViewState(); } class _DidvanPageViewState extends State { @override Widget build(BuildContext context) { final double deviceTopPadding = MediaQuery.of(context).padding.top; return Directionality( textDirection: TextDirection.ltr, child: CarouselSlider.builder( itemCount: widget.items.length, options: CarouselOptions( onPageChanged: (index, reason) => widget.onPageChanged(index), height: double.infinity, initialPage: widget.initialIndex, viewportFraction: 0.94, enableInfiniteScroll: false, ), itemBuilder: (context, index, realIndex) => Directionality( textDirection: TextDirection.rtl, child: SizedBox( height: MediaQuery.of(context).size.height, child: SingleChildScrollView( controller: index == widget.currentIndex ? widget.scrollController : null, physics: const BouncingScrollPhysics(), padding: EdgeInsets.only( left: 4, right: 4, top: 16 + deviceTopPadding, bottom: 92, ), child: DidvanCard( padding: EdgeInsets.zero, enableBorder: false, child: Builder( builder: (context) { final item = widget.items[index]; if (item == null) { return const SizedBox(); } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SkeletonImage( imageUrl: item.image, aspectRatio: 16 / 9, ), const SizedBox(height: 20), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: DidvanText( item.title, style: Theme.of(context).textTheme.subtitle1, ), ), const SizedBox(height: 8), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: _subtitle(item), ), for (var i = 0; i < item.contents.length; i++) Padding( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 4, ), child: _contentBuilder(item, i), ), if (item.tags.isNotEmpty) const SizedBox(height: 20), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Wrap( spacing: 8, runSpacing: 8, children: [ for (var i = 0; i < item.tags.length; i++) TagItem(label: item.tags[i].label), ], ), ), const Padding( padding: EdgeInsets.symmetric(horizontal: 16), child: DidvanDivider(), ), ], ); }, ), ), ), ), ), ), ); } Widget _contentBuilder(dynamic item, int index) { final content = item.contents[index]; if (content.text != null) { return Html( data: content.text, style: { '*': Style( direction: TextDirection.rtl, lineHeight: LineHeight.percent(135), // textAlign: TextAlign.justify, margin: EdgeInsets.zero, padding: EdgeInsets.zero, ), }, ); } if (content.image != null) { return SkeletonImage( imageUrl: content.image!, aspectRatio: 16 / 9, ); } return const SizedBox(); } Widget _subtitle(dynamic item) { if (widget.isRadar) { return Wrap( crossAxisAlignment: WrapCrossAlignment.center, children: [ DidvanText( 'رادار ', style: Theme.of(context).textTheme.caption, ), for (var i = 0; i < item.categories.length; i++) DidvanText( item.categories[i].label + '${i != item.categories.length - 1 ? '،' : ''} ', style: Theme.of(context).textTheme.caption, ), DidvanText( ' - ' + DateTimeUtils.momentGenerator(item.createdAt), style: Theme.of(context).textTheme.caption, ), ], ); } else { return Row( children: [ DidvanText( item.reference, style: Theme.of(context).textTheme.caption, ), DidvanText( ' - ' + DateTimeUtils.momentGenerator(item.createdAt), style: Theme.of(context).textTheme.caption, ), ], ); } } }