import 'package:ebroker/Ui/screens/widgets/AnimatedRoutes/blur_page_route.dart' show BlurredRouter; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_html/flutter_html.dart' show Html; import '../../../app/routes.dart'; import '../../../data/cubits/fetch_articles_cubit.dart'; import '../../../data/model/article_model.dart'; import '../../../utils/Extensions/extensions.dart'; import '../../../utils/api.dart'; import '../../../utils/responsiveSize.dart'; import '../../../utils/ui_utils.dart'; import '../widgets/Erros/no_data_found.dart'; import '../widgets/Erros/no_internet.dart' show NoInternet; import '../widgets/Erros/something_went_wrong.dart'; import '../widgets/shimmerLoadingContainer.dart'; class ArticlesScreen extends StatefulWidget { const ArticlesScreen({super.key}); static Route route(RouteSettings settings) { return BlurredRouter( builder: (context) { return const ArticlesScreen(); }, ); } @override State createState() => _ArticlesScreenState(); } class _ArticlesScreenState extends State { final ScrollController _pageScrollController = ScrollController(); @override void initState() { context.read().fetchArticles(); _pageScrollController.addListener(pageScrollListen); super.initState(); } void pageScrollListen() { if (_pageScrollController.isEndReached()) { if (context.read().hasMoreData()) { context.read().fetchArticlesMore(); } } } @override void dispose() { _pageScrollController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return RefreshIndicator( color: context.color.tertiaryColor, onRefresh: () async { context.read().fetchArticles(); }, child: Scaffold( backgroundColor: context.color.primaryColor, appBar: UiUtils.buildAppBar( context, showBackButton: true, title: UiUtils.translate( context, "articles", ), ), body: BlocBuilder( builder: (context, state) { if (state is FetchArticlesInProgress) { return buildArticlesShimmer(); } if (state is FetchArticlesFailure) { if (state.errorMessage is ApiException) { if (state.errorMessage.errorMessage == "no-internet") { return NoInternet( onRetry: () { context.read().fetchArticles(); }, ); } } return const SomethingWentWrong(); } if (state is FetchArticlesSuccess) { if (state.articlemodel.isEmpty) { return const NoDataFound(); } return Column( mainAxisSize: MainAxisSize.min, children: [ Expanded( child: ListView.builder( controller: _pageScrollController, shrinkWrap: true, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.all(16), itemCount: state.articlemodel.length, itemBuilder: (context, index) { ArticleModel article = state.articlemodel[index]; return buildArticleCard(context, article); // return article(state, index); }), ), if (state.isLoadingMore) const CircularProgressIndicator(), if (state.loadingMoreError) Text(UiUtils.translate(context, "somethingWentWrng")) ], ); } return Container(); }, ), ), ); } Widget buildArticleCard(BuildContext context, ArticleModel article) { return Padding( padding: const EdgeInsets.all(7.0), child: GestureDetector( onTap: () { Navigator.pushNamed( context, Routes.articleDetailsScreenRoute, arguments: { "model": article, }, ); }, child: ClipRRect( clipBehavior: Clip.antiAlias, borderRadius: BorderRadius.circular(18), child: Container( width: double.infinity, // height: 290, decoration: BoxDecoration( color: context.color.secondaryColor, border: Border.all( width: 1.5, color: context.color.borderColor, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsetsDirectional.fromSTEB(12.0, 12, 12, 0), child: ClipRRect( borderRadius: BorderRadius.circular(10), child: UiUtils.getImage( article.image!, fit: BoxFit.cover, width: double.infinity, height: 160, ), ), ), Padding( padding: const EdgeInsetsDirectional.fromSTEB(12.0, 12, 12, 6), child: Text( (article.title ?? "").firstUpperCase(), ) .color( context.color.textColorDark, ) .size(context.font.normal) .setMaxLines( lines: 2, ), ), Padding( padding: const EdgeInsets.symmetric( horizontal: 12, ), child: Text(stripHtmlTags(article.description ?? "").trim()) .setMaxLines(lines: 3) .size(context.font.small) .color(context.color.textLightColor), ), Padding( padding: const EdgeInsetsDirectional.fromSTEB(12.0, 4, 12, 6), child: Text(article.date == null ? "" : article.date.toString().formatDate()) .size(context.font.smaller) .color(context.color.textLightColor), ), const SizedBox( height: 5, ), ], ), ), ), ), ); } String stripHtmlTags(String htmlString) { RegExp exp = RegExp(r"<[^>]*>", multiLine: true, caseSensitive: true); String strippedString = htmlString.replaceAll(exp, ''); return strippedString; } Widget buildArticlesShimmer() { return ListView.builder( itemCount: 10, shrinkWrap: true, padding: const EdgeInsets.all(16), itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: ClipRRect( clipBehavior: Clip.antiAlias, borderRadius: BorderRadius.circular(18), child: Container( width: double.infinity, height: 287.rh(context), decoration: BoxDecoration( color: context.color.secondaryColor, border: Border.all( width: 1.5, color: context.color.borderColor)), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ CustomShimmer( width: double.infinity, height: 160.rh(context), ), Padding( padding: const EdgeInsets.all(10.0), child: CustomShimmer( width: 100.rw(context), height: 10.rh(context), ), ), Padding( padding: const EdgeInsets.all(10.0), child: CustomShimmer( width: 160.rw(context), height: 10.rh(context), ), ), Padding( padding: const EdgeInsets.all(10.0), child: CustomShimmer( width: 150.rw(context), height: 10.rh(context), ), ), ], ), ), ), ); }); } Container article(FetchArticlesSuccess state, int index) { return Container( constraints: const BoxConstraints( minHeight: 50, maxHeight: double.infinity, ), child: Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(state.articlemodel[index].title!).color(Colors.black), const Divider(), if (state.articlemodel[index].image != "") ...[ Image.network(state.articlemodel[index].image!) ], const Divider(), Html(data: state.articlemodel[index].description!) ], ), ), ), ); } }