elCaribe app - customization and branding

This commit is contained in:
2025-12-12 19:09:42 -04:00
parent 9e5d0d8ebf
commit ba7deac9f3
402 changed files with 31833 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:news/data/models/FeatureSectionModel.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/app/routes.dart';
import 'package:news/utils/uiUtils.dart';
Widget commonSectionTitle(FeatureSectionModel model, BuildContext context) {
return ListTile(
minVerticalPadding: 5,
contentPadding: EdgeInsets.zero,
title: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: CustomTextLabel(
text: model.title!,
textStyle: Theme.of(context).textTheme.titleMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.bold),
softWrap: true,
maxLines: 1,
overflow: TextOverflow.ellipsis)),
GestureDetector(
onTap: () {
UiUtils.showInterstitialAds(context: context);
if ((model.newsType == 'news' || model.newsType == "user_choice") || model.videosType == 'news' && model.newsType != 'breaking_news') {
Navigator.of(context).pushNamed(Routes.sectionNews, arguments: {"sectionId": model.id!, "title": model.title!});
} else {
Navigator.of(context).pushNamed(Routes.sectionBreakNews, arguments: {"sectionId": model.id!, "title": model.title!});
}
},
child: CustomTextLabel(
text: 'viewMore',
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(decoration: TextDecoration.underline, fontWeight: FontWeight.bold, color: UiUtils.getColorScheme(context).outline)),
)
],
),
subtitle: (model.shortDescription != null)
? CustomTextLabel(
text: model.shortDescription!,
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.6)),
softWrap: true,
maxLines: 3,
overflow: TextOverflow.ellipsis)
: SizedBox.shrink(),
);
}

View File

@@ -0,0 +1,165 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:news/app/routes.dart';
import 'package:news/cubits/appLocalizationCubit.dart';
import 'package:news/cubits/generalNewsCubit.dart';
import 'package:news/data/models/NewsModel.dart';
import 'package:news/data/repositories/Settings/settingsLocalDataRepository.dart';
import 'package:news/ui/styles/colors.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/ui/widgets/networkImage.dart';
import 'package:news/utils/uiUtils.dart';
class GeneralNewsRandomStyle extends StatefulWidget {
final List<NewsModel> modelList;
const GeneralNewsRandomStyle({super.key, required this.modelList});
@override
GeneralNewsRandomStyleState createState() => GeneralNewsRandomStyleState();
}
class GeneralNewsRandomStyleState extends State<GeneralNewsRandomStyle> {
late final ScrollController scrollController = ScrollController()..addListener(hasMoreGeneralNewsListener);
late int counter; //counter will handle unique index in both list & grid
late List<NewsModel> newsList;
@override
void initState() {
super.initState();
newsList = widget.modelList;
}
@override
void dispose() {
scrollController.removeListener(() {});
super.dispose();
}
void hasMoreGeneralNewsListener() {
if (scrollController.position.maxScrollExtent == scrollController.offset) {
if (context.read<GeneralNewsCubit>().hasMoreGeneralNews()) {
context.read<GeneralNewsCubit>().getMoreGeneralNews(
langId: context.read<AppLocalizationCubit>().state.id,
latitude: SettingsLocalDataRepository().getLocationCityValues().first,
longitude: SettingsLocalDataRepository().getLocationCityValues().last);
}
}
}
@override
Widget build(BuildContext context) {
counter = 0;
return Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListView.separated(
controller: scrollController,
shrinkWrap: true,
padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(),
itemCount: newsList.length,
separatorBuilder: (BuildContext context, int index) {
return (index.isOdd && counter + 1 < newsList.length) ? getGrid() : const SizedBox.shrink();
},
itemBuilder: (BuildContext context, int index) {
return (counter < newsList.length) ? listRow(counter++) : const SizedBox.shrink();
},
),
],
);
}
Widget getGrid() {
return SizedBox(
height: 200,
child: GridView.count(
crossAxisCount: 1,
scrollDirection: Axis.horizontal,
children: List.generate((counter % 3 == 0) ? 3 : 2, (index) {
return Padding(padding: const EdgeInsets.only(right: 15), child: listRow((counter < newsList.length) ? counter++ : counter));
})));
}
Widget listRow(int index) {
NewsModel newsModel = newsList[index];
return Padding(
padding: const EdgeInsets.only(top: 15),
child: GestureDetector(
onTap: () {
List<NewsModel> newList = [];
newList.addAll(newsList);
newList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": newsList[index], "newsList": newList, "isFromBreak": false, "fromShowMore": false});
},
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: ShaderMask(
shaderCallback: (rect) =>
LinearGradient(begin: Alignment.center, end: Alignment.bottomCenter, colors: [Colors.transparent, darkSecondaryColor.withOpacity(0.9)]).createShader(rect),
blendMode: BlendMode.darken,
child: Container(
width: double.maxFinite,
height: MediaQuery.of(context).size.height / 3.3,
color: primaryColor.withValues(alpha: 0.15),
child: CustomNetworkImage(
networkImageUrl: newsModel.image!,
fit: BoxFit.cover,
width: double.maxFinite,
height: MediaQuery.of(context).size.height / 3.3,
isVideo: newsModel.type == 'videos' ? true : false),
))),
if (newsModel.type == 'videos')
Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.12,
start: MediaQuery.of(context).size.width / 3,
end: MediaQuery.of(context).size.width / 3,
child: InkWell(
onTap: () {
List<NewsModel> allNewsList = List.from(newsList)..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": newsModel, "otherVideos": allNewsList});
},
child: UiUtils.setPlayButton(context: context))),
Positioned.directional(
textDirection: Directionality.of(context),
bottom: 10,
start: 10,
end: 10,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (newsModel.categoryName != null)
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Container(
padding: const EdgeInsets.all(5),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: CustomTextLabel(
text: newsModel.categoryName!,
textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(color: secondaryColor.withOpacity(0.6)),
overflow: TextOverflow.ellipsis,
softWrap: true)),
),
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: CustomTextLabel(
text: newsModel.title!,
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.normal),
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: true)),
],
))
],
)),
);
}
}

View File

@@ -0,0 +1,145 @@
import 'package:flutter/material.dart';
import 'package:news/ui/screens/auth/Widgets/svgPictureWidget.dart';
import 'package:shimmer/shimmer.dart';
import 'package:news/app/routes.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:news/cubits/themeCubit.dart';
import 'package:news/ui/styles/appTheme.dart';
import 'package:news/cubits/liveStreamCubit.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/cubits/appSystemSettingCubit.dart';
class LiveWithSearchView extends StatefulWidget {
const LiveWithSearchView({super.key});
@override
LiveWithSearchState createState() => LiveWithSearchState();
}
class LiveWithSearchState extends State<LiveWithSearchView> {
Widget liveWithSearchView() {
return BlocBuilder<LiveStreamCubit, LiveStreamState>(
bloc: context.read<LiveStreamCubit>(),
builder: (context, state) {
if (state is LiveStreamFetchSuccess) {
return Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Logo Caribe
Container(
decoration: BoxDecoration(shape: BoxShape.circle, color: UiUtils.getColorScheme(context).surface),
height: 60,
width: 60,
child: Center(
child: SvgPictureWidget(assetName: "logo_caribe", height: 40.0, width: 40.0),
)),
const SizedBox(width: 10),
// Search bar
Expanded(
child: InkWell(
child: Container(
alignment: Alignment.centerLeft,
height: 60,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(30.0), color: UiUtils.getColorScheme(context).surface),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Padding(
padding: const EdgeInsetsDirectional.only(start: 10.0),
child: Icon(Icons.search_rounded, color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7))),
Padding(
padding: const EdgeInsetsDirectional.only(start: 10.0),
child: CustomTextLabel(text: 'searchHomeNews', maxLines: 3, textStyle: TextStyle(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7)))),
],
),
)),
onTap: () {
Navigator.of(context).pushNamed(Routes.search);
},
)),
if (state.liveStream.isNotEmpty && context.read<AppConfigurationCubit>().getLiveStreamMode() == "1")
Padding(
padding: const EdgeInsetsDirectional.only(start: 10.0),
child: InkWell(
child: Container(
decoration: BoxDecoration(shape: BoxShape.circle, color: UiUtils.getColorScheme(context).surface),
height: 60,
width: 60,
child: Center(
child: SvgPictureWidget(assetName: (context.read<ThemeCubit>().state.appTheme == AppTheme.Dark ? "live_news_dark" : "live_news"), height: 30.0, width: 54.0),
)),
onTap: () {
Navigator.of(context).pushNamed(Routes.live, arguments: {"liveNews": state.liveStream});
},
))
],
));
}
if (state is LiveStreamFetchFailure) {
return Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
children: [
// Logo Caribe
Container(
decoration: BoxDecoration(shape: BoxShape.circle, color: UiUtils.getColorScheme(context).surface),
height: 60,
width: 60,
child: Center(
child: SvgPictureWidget(assetName: "logo_caribe", height: 40.0, width: 40.0),
)),
const SizedBox(width: 10),
// Search bar
Expanded(
child: InkWell(
child: Container(
alignment: Alignment.centerLeft,
height: 60,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(30.0), color: UiUtils.getColorScheme(context).surface),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Padding(padding: const EdgeInsetsDirectional.only(start: 10.0), child: Icon(Icons.search_rounded, color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7))),
Padding(
padding: const EdgeInsetsDirectional.only(start: 10.0),
child: CustomTextLabel(text: 'searchHomeNews', maxLines: 3, textStyle: TextStyle(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7))),
),
],
),
)),
onTap: () {
Navigator.of(context).pushNamed(Routes.search);
},
),
),
],
),
);
}
return shimmerData(); //state is LiveStreamFetchInProgress || state is LiveStreamInitial
});
}
Widget shimmerData() {
return Shimmer.fromColors(
baseColor: Colors.grey.withOpacity(0.6),
highlightColor: Colors.grey,
child: Container(
height: 60,
margin: const EdgeInsets.only(top: 15),
width: double.maxFinite,
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: Colors.grey.withOpacity(0.6))));
}
@override
Widget build(BuildContext context) {
return liveWithSearchView();
}
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
Widget sectionShimmer(BuildContext context) {
return Shimmer.fromColors(
baseColor: Colors.grey.withOpacity(0.6),
highlightColor: Colors.grey,
child: ListView(shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsetsDirectional.only(top: 10), children: [
Container(
height: 55,
width: double.maxFinite,
decoration: BoxDecoration(color: Colors.grey.withOpacity(0.6), borderRadius: BorderRadius.circular(10)),
),
ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: 5,
itemBuilder: (context, index) {
return Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height / 3.3,
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(top: 15),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: Colors.grey.withOpacity(0.6)),
);
}),
]));
}

View File

@@ -0,0 +1,321 @@
import 'dart:math';
import 'package:news/ui/screens/HomePage/Widgets/CommonSectionTitle.dart';
import 'package:flutter/material.dart';
import 'package:news/app/routes.dart';
import 'package:news/data/models/BreakingNewsModel.dart';
import 'package:news/data/models/FeatureSectionModel.dart';
import 'package:news/data/models/NewsModel.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/utils/constant.dart';
import 'package:news/utils/strings.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/ui/styles/colors.dart';
import 'package:news/ui/widgets/networkImage.dart';
class Style1Section extends StatefulWidget {
final FeatureSectionModel model;
const Style1Section({super.key, required this.model});
@override
Style1SectionState createState() => Style1SectionState();
}
class Style1SectionState extends State<Style1Section> {
int? style1Sel;
PageController? _pageStyle1Controller = PageController();
int limit = limitOfStyle1;
int newsLength = 0;
int brNewsLength = 0;
@override
void dispose() {
_pageStyle1Controller!.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
newsLength = (widget.model.newsType == 'news' || widget.model.newsType == "user_choice") ? widget.model.news!.length : widget.model.videos!.length;
brNewsLength = widget.model.newsType == 'breaking_news' ? widget.model.breakNews!.length : widget.model.breakVideos!.length;
return style1Data(widget.model);
}
Widget style1Data(FeatureSectionModel model) {
if (model.breakVideos!.isNotEmpty || model.breakNews!.isNotEmpty || model.videos!.isNotEmpty || model.news!.isNotEmpty) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
commonSectionTitle(model, context),
if ((model.newsType == 'news' || model.videosType == "news" || model.newsType == "user_choice") &&
((model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.isNotEmpty : model.videos!.isNotEmpty))
style1NewsData(model),
if ((model.newsType == 'breaking_news' || model.videosType == "breaking_news") && (model.newsType == 'breaking_news' ? model.breakNews!.isNotEmpty : model.breakVideos!.isNotEmpty))
style1BreakNewsData(model)
],
);
} else {
return const SizedBox.shrink();
}
}
Widget style1NewsData(FeatureSectionModel model) {
if ((model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.length > 1 : model.videos!.length > 1) {
style1Sel ??= 1;
_pageStyle1Controller = PageController(initialPage: 1, viewportFraction: 0.87);
} else {
style1Sel = 0;
_pageStyle1Controller = PageController(initialPage: 0, viewportFraction: 1);
}
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.36,
width: double.maxFinite,
child: PageView.builder(
physics: const BouncingScrollPhysics(),
itemCount: min(newsLength, limit),
scrollDirection: Axis.horizontal,
pageSnapping: true,
controller: _pageStyle1Controller,
onPageChanged: (index) {
setState(() => style1Sel = index);
},
itemBuilder: (BuildContext context, int index) {
NewsModel data = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![index] : model.videos![index];
return InkWell(
child: Padding(
padding: EdgeInsetsDirectional.only(start: 7, end: 7, top: style1Sel == index ? 0 : MediaQuery.of(context).size.height * 0.027),
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: CustomNetworkImage(
networkImageUrl: data.image!,
height: style1Sel == index ? MediaQuery.of(context).size.height / 4 : MediaQuery.of(context).size.height / 5,
width: double.maxFinite,
fit: BoxFit.cover,
isVideo: model.newsType == 'videos' ? true : false),
),
if (model.newsType == 'videos')
Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.075,
start: MediaQuery.of(context).size.width / 3,
end: MediaQuery.of(context).size.width / 3,
child: InkWell(
onTap: () {
List<NewsModel> newsList = List.from(model.videos ?? [])..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": data, "otherVideos": newsList});
},
child: UiUtils.setPlayButton(context: context)),
),
Positioned.directional(
textDirection: Directionality.of(context),
start: 8,
end: 8,
top: MediaQuery.of(context).size.height / 7,
child: Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height / 5,
width: MediaQuery.of(context).size.width,
margin: const EdgeInsetsDirectional.all(10),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: UiUtils.getColorScheme(context).surface),
padding: const EdgeInsets.all(13),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (data.categoryName != null)
Container(
height: 20.0,
padding: const EdgeInsetsDirectional.only(start: 8.0, end: 8.0, top: 2.5),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: Theme.of(context).primaryColor),
child: CustomTextLabel(
text: data.categoryName!,
textAlign: TextAlign.center,
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: secondaryColor),
overflow: TextOverflow.ellipsis,
softWrap: true)),
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: CustomTextLabel(
text: data.title!,
textStyle: Theme.of(context).textTheme.titleMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.normal),
softWrap: true,
maxLines: 3,
overflow: TextOverflow.ellipsis)),
],
),
)),
],
),
),
onTap: () {
if (model.newsType == 'news' || model.newsType == "user_choice") {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
List<NewsModel> newsList = [];
newsList.addAll(model.news!);
newsList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": data, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
}
},
);
},
),
),
style1Indicator(model, min(newsLength, limit))
],
);
}
Widget style1BreakNewsData(FeatureSectionModel model) {
if (model.newsType == 'breaking_news' ? model.breakNews!.length > 1 : model.breakVideos!.length > 1) {
style1Sel ??= 1;
_pageStyle1Controller = PageController(initialPage: 1, viewportFraction: 0.87);
} else {
style1Sel = 0;
_pageStyle1Controller = PageController(initialPage: 0, viewportFraction: 1);
}
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.36,
width: double.maxFinite,
child: PageView.builder(
physics: const BouncingScrollPhysics(),
itemCount: min(brNewsLength, limit),
scrollDirection: Axis.horizontal,
controller: _pageStyle1Controller,
reverse: false,
onPageChanged: (index) {
setState(() => style1Sel = index);
},
itemBuilder: (BuildContext context, int index) {
BreakingNewsModel data = model.newsType == 'breaking_news' ? model.breakNews![index] : model.breakVideos![index];
return Padding(
padding: EdgeInsetsDirectional.only(start: 7, end: 7, top: style1Sel == index ? 0 : MediaQuery.of(context).size.height * 0.027),
child: InkWell(
onTap: () {
if (model.newsType == 'breaking_news') {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
List<BreakingNewsModel> breakList = [];
breakList.addAll(model.breakNews!);
breakList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": data, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
}
},
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: CustomNetworkImage(
networkImageUrl: data.image!,
height: style1Sel == index ? MediaQuery.of(context).size.height / 4 : MediaQuery.of(context).size.height / 5,
width: double.maxFinite,
fit: BoxFit.cover,
isVideo: model.newsType == 'videos' ? true : false),
),
if (model.newsType == 'videos')
Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.075,
start: MediaQuery.of(context).size.width / 3,
end: MediaQuery.of(context).size.width / 3,
child: InkWell(
onTap: () {
List<BreakingNewsModel> allBrNewsList = List.from(model.breakVideos ?? [])..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 3, "breakModel": data, "otherBreakingVideos": allBrNewsList});
},
child: UiUtils.setPlayButton(context: context)),
),
Positioned.directional(
textDirection: Directionality.of(context),
start: 8,
end: 8,
top: MediaQuery.of(context).size.height / 7,
child: Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height / 5,
width: MediaQuery.of(context).size.width,
margin: const EdgeInsetsDirectional.all(10),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: UiUtils.getColorScheme(context).surface),
padding: const EdgeInsets.all(13),
child: CustomTextLabel(
text: data.title!,
textStyle: Theme.of(context).textTheme.titleMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.normal),
softWrap: true,
maxLines: 4,
overflow: TextOverflow.ellipsis))),
],
),
),
);
},
),
),
style1Indicator(model, min(brNewsLength, limit))
],
);
}
Widget style1Indicator(FeatureSectionModel model, int len) {
return len <= 1
? const SizedBox.shrink()
: Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: map<Widget>(
(model.newsType == 'news' || model.newsType == "user_choice")
? model.news!
: (model.newsType == BREAKING_NEWS)
? model.breakNews!
: (model.newsType == 'videos' && (model.videosTotal! > 0 && model.videos!.isNotEmpty))
? model.videos!
: model.breakVideos!,
(index, url) {
return Container(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsetsDirectional.only(start: 5.0, end: 5.0),
child: Container(
height: 14.0,
width: 14.0,
decoration: BoxDecoration(color: Colors.transparent, shape: BoxShape.circle, border: Border.all(color: UiUtils.getColorScheme(context).primaryContainer)),
child: style1Sel == index
? Container(
margin: const EdgeInsets.all(2),
decoration: BoxDecoration(color: Theme.of(context).primaryColor, shape: BoxShape.circle),
)
: const SizedBox.shrink()),
),
);
},
),
)));
}
List<T> map<T>(List list, Function handler) {
List<T> result = [];
int mapLength = (widget.model.newsType == 'news' || widget.model.newsType == "user_choice") ? min(newsLength, limit) : min(brNewsLength, limit);
for (var i = 0; i < mapLength; i++) {
result.add(handler(i, list[i]));
}
return result;
}
}

View File

@@ -0,0 +1,170 @@
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:news/cubits/appSystemSettingCubit.dart';
import 'package:news/ui/screens/HomePage/Widgets/CommonSectionTitle.dart';
import 'package:news/app/routes.dart';
import 'package:news/data/models/BreakingNewsModel.dart';
import 'package:news/data/models/FeatureSectionModel.dart';
import 'package:news/data/models/NewsModel.dart';
import 'package:news/ui/styles/colors.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/ui/widgets/networkImage.dart';
import 'package:news/utils/constant.dart';
import 'package:news/utils/uiUtils.dart';
class Style2Section extends StatelessWidget {
final FeatureSectionModel model;
bool isNews = true;
Style2Section({super.key, required this.model});
@override
Widget build(BuildContext context) {
return style2Data(model, context);
}
Widget style2Data(FeatureSectionModel model, BuildContext context) {
if (model.breakVideos!.isNotEmpty || model.breakNews!.isNotEmpty || model.videos!.isNotEmpty || model.news!.isNotEmpty) {
if (model.newsType == 'news' || model.videosType == "news" || model.newsType == "user_choice") {
if ((model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.isNotEmpty : model.videos!.isNotEmpty) {
isNews = true;
}
}
if (model.newsType == 'breaking_news' || model.videosType == "breaking_news") {
if (model.newsType == 'breaking_news' ? model.breakNews!.isNotEmpty : model.breakVideos!.isNotEmpty) {
isNews = false;
}
}
int limit = limitOfAllOtherStyle;
int newsLength = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.length : model.videos!.length;
int brNewsLength = model.newsType == 'breaking_news' ? model.breakNews!.length : model.breakVideos!.length;
var totalCount = (isNews) ? min(newsLength, limit) : min(brNewsLength, limit);
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
commonSectionTitle(model, context),
ListView.builder(
padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: totalCount,
itemBuilder: (context, index) => (isNews)
? setStyle2(context: context, index: index, model: model, newsModel: (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![index] : model.videos![index])
: setStyle2(context: context, index: index, model: model, breakingNewsModel: (model.newsType == 'breaking_news') ? model.breakNews![index] : model.breakVideos![index])),
],
);
} else {
return const SizedBox.shrink();
}
}
Widget setStyle2({required BuildContext context, required int index, required FeatureSectionModel model, NewsModel? newsModel, BreakingNewsModel? breakingNewsModel}) {
return Padding(
padding: EdgeInsets.only(top: index == 0 ? 0 : 15),
child: Column(
children: [
if (context.read<AppConfigurationCubit>().getInAppAdsMode() == "1" &&
(context.read<AppConfigurationCubit>().getAdsType() != "unity" || context.read<AppConfigurationCubit>().getIOSAdsType() != "unity"))
nativeAdsShow(context: context, index: index),
InkWell(
onTap: () {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
if (model.newsType == 'news' || model.newsType == "user_choice") {
List<NewsModel> newsList = [];
newsList.addAll(model.news!);
newsList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": newsModel, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
} else if (model.newsType == 'breaking_news') {
List<BreakingNewsModel> breakList = [];
breakList.addAll(model.breakNews!);
breakList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": breakingNewsModel, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
}
},
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: ShaderMask(
shaderCallback: (rect) =>
LinearGradient(begin: Alignment.center, end: Alignment.bottomCenter, colors: [Colors.transparent, darkSecondaryColor.withOpacity(0.9)]).createShader(rect),
blendMode: BlendMode.darken,
child: Container(
color: primaryColor.withAlpha(5),
width: double.maxFinite,
height: MediaQuery.of(context).size.height / 3.3,
child: CustomNetworkImage(
networkImageUrl: (newsModel != null) ? newsModel.image! : breakingNewsModel!.image!,
fit: BoxFit.cover,
width: double.maxFinite,
height: MediaQuery.of(context).size.height / 3.3,
isVideo: model.newsType == 'videos' ? true : false),
),
)),
if (model.newsType == 'videos')
Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.12,
start: MediaQuery.of(context).size.width / 3,
end: MediaQuery.of(context).size.width / 3,
child: InkWell(
onTap: () {
List<NewsModel> newsList = [];
List<BreakingNewsModel> brNewsList = [];
if (model.breakVideos != null && model.breakVideos!.isNotEmpty) brNewsList = List.from(model.breakVideos ?? [])..removeAt(index);
if (model.videos != null && model.videos!.isNotEmpty) newsList = List.from(model.videos ?? [])..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {
"from": 1,
"model": (newsModel != null) ? newsModel : breakingNewsModel!,
if (newsList.isNotEmpty) "otherVideos": newsList,
if (brNewsList.isNotEmpty) "otherBreakingVideos": brNewsList
});
},
child: UiUtils.setPlayButton(context: context))),
Positioned.directional(
textDirection: Directionality.of(context),
bottom: 10,
start: 10,
end: 10,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (newsModel != null && newsModel.categoryName != null)
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Container(
padding: const EdgeInsets.all(5),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: CustomTextLabel(
text: newsModel.categoryName!,
textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(color: secondaryColor.withOpacity(0.6)),
overflow: TextOverflow.ellipsis,
softWrap: true)),
),
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: CustomTextLabel(
text: (newsModel != null) ? newsModel.title! : breakingNewsModel!.title!,
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.normal),
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: true)),
],
))
],
),
),
],
),
);
}
}

View File

@@ -0,0 +1,241 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:news/app/routes.dart';
import 'package:news/cubits/appSystemSettingCubit.dart';
import 'package:news/data/models/BreakingNewsModel.dart';
import 'package:news/data/models/FeatureSectionModel.dart';
import 'package:news/data/models/NewsModel.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/utils/constant.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/ui/styles/colors.dart';
import 'package:news/ui/widgets/networkImage.dart';
import 'package:news/ui/screens/HomePage/Widgets/CommonSectionTitle.dart';
class Style3Section extends StatelessWidget {
final FeatureSectionModel model;
const Style3Section({super.key, required this.model});
@override
Widget build(BuildContext context) {
return style3Data(model, context);
}
Widget style3Data(FeatureSectionModel model, BuildContext context) {
int limit = limitOfAllOtherStyle;
int newsLength = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.length : model.videos!.length;
int brNewsLength = model.newsType == 'breaking_news' ? model.breakNews!.length : model.breakVideos!.length;
if (model.breakVideos!.isNotEmpty || model.breakNews!.isNotEmpty || model.videos!.isNotEmpty || model.news!.isNotEmpty) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
commonSectionTitle(model, context),
if ((model.newsType == 'breaking_news' || model.videosType == "breaking_news") && (model.newsType == 'breaking_news' ? model.breakNews!.isNotEmpty : model.breakVideos!.isNotEmpty))
SizedBox(
height: MediaQuery.of(context).size.height * 0.34,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const AlwaysScrollableScrollPhysics(),
itemCount: min(brNewsLength, limit),
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
BreakingNewsModel data = model.newsType == 'breaking_news' ? model.breakNews![index] : model.breakVideos![index];
return Row(
mainAxisSize: MainAxisSize.min,
children: [
if ((index != 0 && index % nativeAdsIndex == 0) &&
context.read<AppConfigurationCubit>().getInAppAdsMode() == "1" &&
(context.read<AppConfigurationCubit>().getAdsType() != "unity" || context.read<AppConfigurationCubit>().getIOSAdsType() != "unity"))
SizedBox(width: MediaQuery.of(context).size.width * 0.87, child: nativeAdsShow(context: context, index: index)),
InkWell(
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.87,
child: Stack(
children: <Widget>[
Positioned.directional(
textDirection: Directionality.of(context),
start: 0,
end: 0,
top: MediaQuery.of(context).size.height / 15,
child: Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height / 4,
margin: EdgeInsetsDirectional.only(start: index == 0 ? 0 : 10, end: 10, top: 10, bottom: 10),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: UiUtils.getColorScheme(context).surface),
padding: const EdgeInsets.all(14),
child: Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height / 9),
child: CustomTextLabel(
text: data.title!,
textStyle: Theme.of(context).textTheme.titleMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.normal),
softWrap: true,
maxLines: 2,
overflow: TextOverflow.ellipsis)),
)),
Positioned.directional(
textDirection: Directionality.of(context),
start: 30,
end: 30,
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: CustomNetworkImage(
networkImageUrl: data.image!,
height: MediaQuery.of(context).size.height / 4.7,
width: double.maxFinite,
fit: BoxFit.cover,
isVideo: model.newsType == 'videos' ? true : false),
),
),
if (model.newsType == 'videos')
Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.085,
start: MediaQuery.of(context).size.width / 3,
end: MediaQuery.of(context).size.width / 3,
child: InkWell(
onTap: () {
List<BreakingNewsModel> brNewsList = List.from(model.breakVideos ?? [])..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 3, "breakModel": data, "otherBreakingVideos": brNewsList});
},
child: UiUtils.setPlayButton(context: context)),
),
],
),
),
onTap: () {
if (model.newsType == 'breaking_news') {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
List<BreakingNewsModel> breakList = [];
breakList.addAll(model.breakNews!);
breakList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": data, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
}
},
),
],
);
})),
if ((model.newsType == 'news' || model.videosType == "news" || model.newsType == "user_choice") &&
((model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.isNotEmpty : model.videos!.isNotEmpty))
SizedBox(
height: MediaQuery.of(context).size.height * 0.34,
child: ListView.builder(
padding: EdgeInsets.zero,
physics: const AlwaysScrollableScrollPhysics(),
itemCount: min(newsLength, limit),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
NewsModel data = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![index] : model.videos![index];
return Row(
mainAxisSize: MainAxisSize.min,
children: [
if ((index != 0 && index % nativeAdsIndex == 0) &&
context.read<AppConfigurationCubit>().getInAppAdsMode() == "1" &&
(context.read<AppConfigurationCubit>().getAdsType() != "unity" || context.read<AppConfigurationCubit>().getIOSAdsType() != "unity"))
SizedBox(width: MediaQuery.of(context).size.width * 0.87, child: nativeAdsShow(context: context, index: index)),
InkWell(
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.87,
child: Stack(
children: <Widget>[
Positioned.directional(
textDirection: Directionality.of(context),
start: 0,
end: 0,
top: MediaQuery.of(context).size.height / 15,
child: Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height / 3.8,
margin: EdgeInsetsDirectional.only(start: index == 0 ? 0 : 10, end: 10, top: 10, bottom: 10),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: UiUtils.getColorScheme(context).surface),
padding: const EdgeInsets.all(14),
child: Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height / 8),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (data.categoryName != null)
Container(
height: 20.0,
padding: const EdgeInsetsDirectional.only(start: 8.0, end: 8.0, top: 2.5),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: Theme.of(context).primaryColor),
child: CustomTextLabel(
text: data.categoryName!,
textAlign: TextAlign.center,
textStyle: Theme.of(context).textTheme.bodyMedium?.copyWith(color: secondaryColor),
overflow: TextOverflow.ellipsis,
softWrap: true)),
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: CustomTextLabel(
text: data.title!,
textStyle:
Theme.of(context).textTheme.titleMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.normal),
softWrap: true,
maxLines: 2,
overflow: TextOverflow.ellipsis)),
],
),
),
)),
Positioned.directional(
textDirection: Directionality.of(context),
start: 30,
end: 30,
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: CustomNetworkImage(
networkImageUrl: data.image!,
height: MediaQuery.of(context).size.height / 4.7,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
isVideo: model.newsType == 'videos' ? true : false),
),
),
if (model.newsType == 'videos')
Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.085,
start: MediaQuery.of(context).size.width / 3,
end: MediaQuery.of(context).size.width / 3,
child: InkWell(
onTap: () {
List<NewsModel> allNewsList = List.from(model.videos ?? [])..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": data, "otherVideos": allNewsList});
},
child: UiUtils.setPlayButton(context: context)),
),
],
),
),
onTap: () {
if (model.newsType == 'news' || model.newsType == "user_choice") {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
List<NewsModel> newsList = [];
newsList.addAll(model.news!);
newsList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": data, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
}
},
),
],
);
})),
],
);
} else {
return const SizedBox.shrink();
}
}
}

View File

@@ -0,0 +1,189 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:news/ui/screens/HomePage/Widgets/CommonSectionTitle.dart';
import 'package:news/app/routes.dart';
import 'package:news/data/models/BreakingNewsModel.dart';
import 'package:news/data/models/FeatureSectionModel.dart';
import 'package:news/data/models/NewsModel.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/utils/constant.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/ui/styles/colors.dart';
import 'package:news/ui/widgets/networkImage.dart';
class Style4Section extends StatelessWidget {
final FeatureSectionModel model;
const Style4Section({super.key, required this.model});
@override
Widget build(BuildContext context) {
return style4Data(model, context);
}
Widget style4Data(FeatureSectionModel model, BuildContext context) {
int limit = limitOfAllOtherStyle;
int newsLength = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.length : model.videos!.length;
int brNewsLength = model.newsType == 'breaking_news' ? model.breakNews!.length : model.breakVideos!.length;
if (model.breakVideos!.isNotEmpty || model.breakNews!.isNotEmpty || model.videos!.isNotEmpty || model.news!.isNotEmpty) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
commonSectionTitle(model, context),
if ((model.newsType == 'news' || model.videosType == "news" || model.newsType == "user_choice") &&
((model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.isNotEmpty : model.videos!.isNotEmpty))
Column(
children: [
setGridLayout(
context: context,
totalCount: min(newsLength, limit),
childWidget: (context, index) {
NewsModel data = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![index] : model.videos![index];
return InkWell(
child: Container(
padding: const EdgeInsets.all(7),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: UiUtils.getColorScheme(context).surface),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(children: [
setNewsImage(context: context, imageURL: data.image!),
if (data.categoryName != null && data.categoryName != "")
Align(
alignment: Alignment.topLeft,
child: Container(
margin: const EdgeInsetsDirectional.only(start: 7.0, top: 7.0),
height: 18.0,
padding: const EdgeInsetsDirectional.only(start: 6.0, end: 6.0, top: 2.5),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: Theme.of(context).primaryColor),
child: CustomTextLabel(
text: data.categoryName!,
textAlign: TextAlign.center,
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: secondaryColor),
overflow: TextOverflow.ellipsis,
softWrap: true)),
),
if (model.newsType == 'videos')
Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.065,
start: MediaQuery.of(context).size.width / 6,
end: MediaQuery.of(context).size.width / 6,
child: InkWell(
onTap: () {
List<NewsModel> allNewsList = List.from(model.videos ?? [])..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": data, "otherVideos": allNewsList});
},
child: UiUtils.setPlayButton(context: context)),
),
]),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: CustomTextLabel(
text: data.title!,
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
softWrap: true,
maxLines: 3,
overflow: TextOverflow.ellipsis)),
],
),
),
onTap: () {
if (model.newsType == 'news' || model.newsType == "user_choice") {
//show interstitial ads
UiUtils.showInterstitialAds(context: context);
List<NewsModel> newsList = [];
newsList.addAll(model.news!);
newsList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": data, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
}
},
);
}),
],
),
if ((model.newsType == 'breaking_news' || model.videosType == "breaking_news") && (model.newsType == 'breaking_news' ? model.breakNews!.isNotEmpty : model.breakVideos!.isNotEmpty))
setGridLayout(
context: context,
totalCount: min(brNewsLength, limit),
childWidget: (context, index) {
BreakingNewsModel data = model.newsType == 'breaking_news' ? model.breakNews![index] : model.breakVideos![index];
return InkWell(
child: Container(
padding: const EdgeInsets.all(7),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: UiUtils.getColorScheme(context).surface),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(children: [
setNewsImage(context: context, imageURL: data.image!),
if (model.newsType == 'videos')
Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.065,
start: MediaQuery.of(context).size.width / 6,
end: MediaQuery.of(context).size.width / 6,
child: InkWell(
onTap: () {
List<BreakingNewsModel> brNewsList = List.from(model.breakVideos ?? [])..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 3, "breakModel": data, "otherBreakingVideos": brNewsList});
},
child: UiUtils.setPlayButton(context: context)),
),
]),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: CustomTextLabel(
text: data.title!,
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
softWrap: true,
maxLines: 3,
overflow: TextOverflow.ellipsis)),
],
),
),
onTap: () {
if (model.newsType == 'breaking_news') {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
List<BreakingNewsModel> breakList = [];
breakList.addAll(model.breakNews!);
breakList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": data, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
}
},
);
})
],
);
} else {
return const SizedBox.shrink();
}
}
Widget setGridLayout({required BuildContext context, required int totalCount, required Widget? Function(BuildContext, int) childWidget}) {
return GridView.builder(
padding: EdgeInsets.zero,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(mainAxisExtent: MediaQuery.of(context).size.height * 0.27, crossAxisCount: 2, crossAxisSpacing: 10, mainAxisSpacing: 13),
shrinkWrap: true,
itemCount: totalCount,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: childWidget);
}
Widget setNewsImage({required BuildContext context, required String imageURL}) {
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: CustomNetworkImage(
networkImageUrl: imageURL,
height: MediaQuery.of(context).size.height * 0.175,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
isVideo: model.newsType == 'videos' ? true : false));
}
}

View File

@@ -0,0 +1,400 @@
import 'dart:math';
import 'package:news/ui/screens/HomePage/Widgets/CommonSectionTitle.dart';
import 'package:flutter/material.dart';
import 'package:news/app/routes.dart';
import 'package:news/data/models/BreakingNewsModel.dart';
import 'package:news/data/models/FeatureSectionModel.dart';
import 'package:news/data/models/NewsModel.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/utils/constant.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/ui/styles/colors.dart';
import 'package:news/ui/widgets/networkImage.dart';
class Style5Section extends StatelessWidget {
final FeatureSectionModel model;
const Style5Section({super.key, required this.model});
@override
Widget build(BuildContext context) {
return style5Data(model, context);
}
Widget style5SingleNewsData(FeatureSectionModel model, BuildContext context) {
NewsModel data = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![0] : model.videos![0];
return InkWell(
child: Container(
height: MediaQuery.of(context).size.height * 0.28,
width: double.maxFinite,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: CustomNetworkImage(
networkImageUrl: data.image!, height: MediaQuery.of(context).size.height * 0.28, width: double.maxFinite, fit: BoxFit.cover, isVideo: model.newsType == 'videos' ? true : false),
),
Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: EdgeInsets.all(MediaQuery.of(context).size.height * 0.01),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (data.categoryName != null)
Container(
height: 20.0,
padding: const EdgeInsetsDirectional.only(start: 8.0, end: 8.0, top: 2.5),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: Theme.of(context).primaryColor),
child: CustomTextLabel(
text: data.categoryName!,
textAlign: TextAlign.left,
textStyle: Theme.of(context).textTheme.bodyMedium?.copyWith(color: secondaryColor),
overflow: TextOverflow.ellipsis,
softWrap: true)),
Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.01),
child: CustomTextLabel(
text: data.title!,
textAlign: TextAlign.left,
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.w700),
maxLines: 3,
overflow: TextOverflow.ellipsis,
softWrap: true)),
Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.01),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.calendar_month, color: secondaryColor, size: 20),
Padding(
padding: const EdgeInsetsDirectional.only(start: 10),
child: CustomTextLabel(
text: UiUtils.convertToAgo(context, DateTime.parse(data.publishDate ?? data.date!), 0)!,
textAlign: TextAlign.left,
textStyle: Theme.of(context).textTheme.bodyMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.w600),
overflow: TextOverflow.ellipsis,
softWrap: true)),
],
),
),
if (model.newsType == 'videos')
InkWell(
child: Padding(padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.02), child: UiUtils.setPlayButton(context: context)),
onTap: () {
List<NewsModel> allNewsList = List.from(model.videos ?? [])..removeWhere((item) => item.id == data.id);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": data, "otherVideos": allNewsList});
},
),
],
),
),
),
],
),
),
onTap: () {
if (model.newsType == 'news' || model.newsType == "user_choice") {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
List<NewsModel> newsList = [];
newsList.addAll(model.news!);
newsList.removeAt(0);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": data, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
}
},
);
}
Widget style5SingleBreakNewsData(FeatureSectionModel model, BuildContext context) {
BreakingNewsModel data = model.newsType == 'breaking_news' ? model.breakNews![0] : model.breakVideos![0];
return InkWell(
child: Container(
height: MediaQuery.of(context).size.height * 0.28,
width: double.maxFinite,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: ShaderMask(
shaderCallback: (rect) => LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.transparent, darkSecondaryColor.withOpacity(0.9)]).createShader(rect),
blendMode: BlendMode.darken,
child: CustomNetworkImage(
networkImageUrl: data.image!, height: MediaQuery.of(context).size.height * 0.28, width: double.maxFinite, fit: BoxFit.cover, isVideo: model.newsType == 'videos' ? true : false),
),
),
(model.newsType == 'videos')
? Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.all(MediaQuery.of(context).size.height * 0.01),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.02),
child: CustomTextLabel(
text: data.title!,
textAlign: TextAlign.left,
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.w700),
maxLines: 3,
overflow: TextOverflow.ellipsis,
softWrap: true)),
InkWell(
child: Padding(padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.02), child: UiUtils.setPlayButton(context: context)),
onTap: () {
List<BreakingNewsModel> brNewsList = List.from(model.breakVideos ?? [])..removeWhere((item) => item.id == data.id);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 3, "breakModel": data, "otherBreakingVideos": brNewsList});
},
),
],
)),
)
: Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
padding: EdgeInsets.all(MediaQuery.of(context).size.height * 0.01),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
child: CustomTextLabel(
text: data.title!,
textAlign: TextAlign.left,
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.w700),
maxLines: 3,
overflow: TextOverflow.ellipsis,
softWrap: true)),
),
],
),
),
onTap: () {
if (model.newsType == 'breaking_news') {
//show interstitial ads
UiUtils.showInterstitialAds(context: context);
List<BreakingNewsModel> breakList = [];
breakList.addAll(model.breakNews!);
breakList.removeAt(0);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": data, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
}
},
);
}
Widget style5Data(FeatureSectionModel model, BuildContext context) {
int limit = limitOfAllOtherStyle;
int newsLength = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news!.length : model.videos!.length;
int brNewsLength = model.newsType == 'breaking_news' ? model.breakNews!.length : model.breakVideos!.length;
if (model.breakVideos!.isNotEmpty || model.breakNews!.isNotEmpty || model.videos!.isNotEmpty || model.news!.isNotEmpty) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
commonSectionTitle(model, context),
if ((model.newsType == 'news' || model.videosType == "news" || model.newsType == "user_choice") && (model.newsType == 'news' || model.newsType == "user_choice")
? model.news!.isNotEmpty
: model.videos!.isNotEmpty)
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
style5SingleNewsData(model, context),
if (newsLength > 1)
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: List.generate(min(newsLength, limit), (index) {
if (newsLength > index + 1) {
NewsModel data = (model.newsType == 'news' || model.newsType == "user_choice") ? model.news![index + 1] : model.videos![index + 1];
return InkWell(
child: SizedBox(
width: MediaQuery.of(context).size.width / 2.35,
child: Padding(
padding: EdgeInsetsDirectional.only(start: index == 0 ? 0 : 10.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(children: [
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: CustomNetworkImage(
networkImageUrl: data.image!,
height: MediaQuery.of(context).size.height * 0.15,
width: MediaQuery.of(context).size.width / 2.35,
fit: BoxFit.cover,
isVideo: model.newsType == 'videos' ? true : false),
),
if (data.categoryName != null)
Align(
alignment: Alignment.topLeft,
child: Container(
margin: const EdgeInsetsDirectional.only(start: 7.0, top: 7.0),
height: 18.0,
padding: const EdgeInsetsDirectional.only(start: 6.0, end: 6.0, top: 2.5),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: Theme.of(context).primaryColor),
child: CustomTextLabel(
text: data.categoryName!,
textAlign: TextAlign.left,
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: secondaryColor),
overflow: TextOverflow.ellipsis,
softWrap: true)),
),
if (model.newsType == 'videos')
Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.058,
start: MediaQuery.of(context).size.width / 8.5,
end: MediaQuery.of(context).size.width / 8.5,
child: InkWell(
onTap: () {
List<NewsModel> allNewsList = List.from(model.videos ?? [])..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 1, "model": data, "otherVideos": allNewsList});
},
child: UiUtils.setPlayButton(context: context, heightVal: 28)),
),
]),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: CustomTextLabel(
text: data.title!,
textStyle: Theme.of(context).textTheme.labelMedium!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
softWrap: true,
maxLines: 2,
overflow: TextOverflow.ellipsis)),
Padding(
padding: const EdgeInsets.only(top: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.calendar_month, color: UiUtils.getColorScheme(context).primaryContainer, size: 15),
Padding(
padding: const EdgeInsetsDirectional.only(start: 5),
child: CustomTextLabel(
text: UiUtils.convertToAgo(context, DateTime.parse(data.publishDate ?? data.date!), 0)!,
textAlign: TextAlign.left,
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
overflow: TextOverflow.ellipsis,
softWrap: true)),
],
),
),
],
),
),
),
onTap: () {
if (model.newsType == 'news' || model.newsType == "user_choice") {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
List<NewsModel> newsList = [];
newsList.addAll(model.news!);
newsList.removeAt(index + 1);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": data, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
}
},
);
} else {
return const SizedBox.shrink();
}
})),
)),
],
),
if ((model.newsType == 'breaking_news' && model.breakNews?.isNotEmpty == true) || (model.videosType == 'breaking_news' && model.breakVideos?.isNotEmpty == true))
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
style5SingleBreakNewsData(model, context),
if (brNewsLength > 1)
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: List.generate(min(brNewsLength, limit), (index) {
if (brNewsLength > index + 1) {
BreakingNewsModel data = model.newsType == 'breaking_news' ? model.breakNews![index + 1] : model.breakVideos![index + 1];
return InkWell(
child: Container(
width: MediaQuery.of(context).size.width / 2.35,
padding: EdgeInsetsDirectional.only(start: index == 0 ? 0 : 10.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(children: [
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: CustomNetworkImage(
networkImageUrl: data.image!,
height: MediaQuery.of(context).size.height * 0.15,
width: MediaQuery.of(context).size.width / 2.35,
fit: BoxFit.cover,
isVideo: model.newsType == 'videos' ? true : false),
),
if (model.newsType == 'videos')
Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.058,
start: MediaQuery.of(context).size.width / 8.5,
end: MediaQuery.of(context).size.width / 8.5,
child: InkWell(
onTap: () {
List<BreakingNewsModel> brNewsList = List.from(model.breakVideos ?? [])..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {"from": 3, "breakModel": data, "otherBreakingVideos": brNewsList});
},
child: UiUtils.setPlayButton(context: context, heightVal: 28)),
),
]),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: CustomTextLabel(
text: data.title!,
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
softWrap: true,
maxLines: 2,
overflow: TextOverflow.ellipsis)),
],
),
),
onTap: () {
if (model.newsType == 'breaking_news') {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
List<BreakingNewsModel> breakList = [];
breakList.addAll(model.breakNews!);
breakList.removeAt(index + 1);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": data, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
}
},
);
} else {
return const SizedBox.shrink();
}
})),
)),
],
)
],
);
} else {
return const SizedBox.shrink();
}
}
}

View File

@@ -0,0 +1,216 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:news/app/routes.dart';
import 'package:news/cubits/appLocalizationCubit.dart';
import 'package:news/cubits/sectionByIdCubit.dart';
import 'package:news/data/models/BreakingNewsModel.dart';
import 'package:news/data/models/FeatureSectionModel.dart';
import 'package:news/data/models/NewsModel.dart';
import 'package:news/data/repositories/Settings/settingsLocalDataRepository.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/ui/styles/colors.dart';
import 'package:news/ui/widgets/networkImage.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
class Style6Section extends StatefulWidget {
final FeatureSectionModel model;
const Style6Section({super.key, required this.model});
@override
Style6SectionState createState() => Style6SectionState();
}
class Style6SectionState extends State<Style6Section> {
int? style6Sel;
bool isNews = true;
late final ScrollController style6ScrollController = ScrollController()..addListener(hasMoreSectionScrollListener);
late BreakingNewsModel breakingNewsData;
late NewsModel newsData;
@override
void initState() {
super.initState();
getSectionDataById();
}
@override
void dispose() {
style6ScrollController.removeListener(() {});
super.dispose();
}
void hasMoreSectionScrollListener() {
if (style6ScrollController.position.maxScrollExtent == style6ScrollController.offset) {
if (context.read<SectionByIdCubit>().hasMoreSections() && !(context.read<SectionByIdCubit>().state is SectionByIdFetchInProgress)) {
context.read<SectionByIdCubit>().getMoreSectionById(langId: context.read<AppLocalizationCubit>().state.id, sectionId: widget.model.id!);
}
}
}
@override
Widget build(BuildContext context) {
return style6Data();
}
void getSectionDataById() {
Future.delayed(Duration.zero, () {
context.read<SectionByIdCubit>().getSectionById(
langId: context.read<AppLocalizationCubit>().state.id,
sectionId: widget.model.id!,
latitude: SettingsLocalDataRepository().getLocationCityValues().first,
longitude: SettingsLocalDataRepository().getLocationCityValues().last);
});
}
Widget style6Data() {
return BlocBuilder<SectionByIdCubit, SectionByIdState>(builder: (context, state) {
if (state is SectionByIdFetchSuccess) {
isNews = (state.type == 'news' || state.type == 'user_choice' || state.type == 'videos') && state.newsModel.isNotEmpty
? true
: (state.type == 'breaking_news' || state.type == 'videos') && state.breakNewsModel.isNotEmpty
? false
: isNews;
int totalCount = (isNews) ? state.newsModel.length : state.breakNewsModel.length;
return (state.breakNewsModel.isNotEmpty || state.newsModel.isNotEmpty)
? Padding(padding: const EdgeInsets.symmetric(vertical: 5), child: style6NewsDetails(newsData: state.newsModel, brNewsData: state.breakNewsModel, total: totalCount, type: state.type))
: SizedBox.shrink();
}
return SizedBox.shrink();
});
}
Widget style6NewsDetails({List<NewsModel>? newsData, List<BreakingNewsModel>? brNewsData, String? type, int total = 0}) {
return SizedBox(
height: MediaQuery.of(context).size.height / 2.8,
child: SingleChildScrollView(
controller: style6ScrollController,
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(total, (index) {
return SizedBox(
width: 180,
child: Padding(
padding: const EdgeInsets.all(5),
child: (isNews)
? setImageCard(index: index, total: total, type: type!, newsModel: newsData![index], allNewsList: newsData)
: setImageCard(index: index, total: total, type: type!, breakingNewsModel: brNewsData![index], breakingNewsList: brNewsData)));
}))));
}
Widget setImageCard(
{required int index,
required int total,
required String type,
NewsModel? newsModel,
BreakingNewsModel? breakingNewsModel,
List<NewsModel>? allNewsList,
List<BreakingNewsModel>? breakingNewsList}) {
return InkWell(
child: Stack(children: [
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: ShaderMask(
shaderCallback: (bounds) {
return LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.transparent, darkSecondaryColor.withOpacity(0.9)]).createShader(bounds);
},
blendMode: BlendMode.darken,
child: Container(
color: primaryColor.withValues(alpha: 0.15),
width: MediaQuery.of(context).size.width / 1.9,
height: MediaQuery.of(context).size.height / 2.5,
child: CustomNetworkImage(
networkImageUrl: (newsModel != null) ? newsModel.image! : breakingNewsModel!.image!,
height: MediaQuery.of(context).size.height / 2.5,
width: MediaQuery.of(context).size.width / 1.9,
fit: BoxFit.cover,
isVideo: type == "videos"),
),
)),
(newsModel != null && newsModel.categoryName != null)
? Align(
alignment: Alignment.topLeft,
child: Container(
margin: const EdgeInsetsDirectional.only(start: 7.0, top: 7.0),
height: 20.0,
padding: const EdgeInsetsDirectional.only(start: 6.0, end: 6.0, top: 2.5),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(3), color: Theme.of(context).primaryColor),
child: CustomTextLabel(
text: newsModel.categoryName!,
textAlign: TextAlign.center,
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: secondaryColor),
overflow: TextOverflow.ellipsis,
softWrap: true)))
: const SizedBox.shrink(),
(type == "videos")
? Positioned.directional(
textDirection: Directionality.of(context),
top: MediaQuery.of(context).size.height * 0.13,
start: MediaQuery.of(context).size.width / 6,
end: MediaQuery.of(context).size.width / 6,
child: UiUtils.setPlayButton(context: context))
: const SizedBox.shrink(),
Positioned.directional(
textDirection: Directionality.of(context),
bottom: 5,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
(newsModel != null)
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: CustomTextLabel(
text: UiUtils.convertToAgo(context, DateTime.parse(newsModel.publishDate ?? newsModel.date!), 3)!,
textStyle: Theme.of(context).textTheme.labelSmall!.copyWith(color: Colors.white)))
: const SizedBox.shrink(),
Container(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
width: MediaQuery.of(context).size.width * 0.50,
child: CustomTextLabel(
text: (newsModel != null) ? newsModel.title! : breakingNewsModel!.title!,
textStyle: Theme.of(context).textTheme.titleSmall!.copyWith(color: secondaryColor),
softWrap: true,
maxLines: 2,
overflow: TextOverflow.ellipsis))
]),
),
]),
onTap: () {
if (type == "videos") {
List<NewsModel> newsList = [];
List<BreakingNewsModel> brNewsList = [];
if (newsModel != null && allNewsList != null && allNewsList.isNotEmpty) {
newsList = List.from(allNewsList);
newsList.removeAt(index);
} else if (breakingNewsModel != null && breakingNewsList != null && breakingNewsList.isNotEmpty) {
brNewsList = List.from(breakingNewsList);
brNewsList.removeAt(index);
}
// List<NewsModel> newsList = List.from(allNewsList ?? [])..removeAt(index);
// List<BreakingNewsModel> breakNewsList = List.from(breakingNewsList ?? [])..removeAt(index);
Navigator.of(context).pushNamed(Routes.newsVideo, arguments: {
"from": (newsModel != null) ? 1 : 3,
if (newsModel != null) "model": newsModel,
if (breakingNewsModel != null) "breakModel": breakingNewsModel,
"otherBreakingVideos": brNewsList,
"otherVideos": newsList,
});
} else if (type == 'news' || type == "user_choice") {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
if (allNewsList != null && allNewsList.isNotEmpty) {
List<NewsModel> newsList = List.from(allNewsList);
newsList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"model": newsModel, "newsList": newsList, "isFromBreak": false, "fromShowMore": false});
}
} else {
if (breakingNewsList != null && breakingNewsList.isNotEmpty) {
//interstitial ads
UiUtils.showInterstitialAds(context: context);
List<BreakingNewsModel> breakList = List.from(breakingNewsList);
breakList.removeAt(index);
Navigator.of(context).pushNamed(Routes.newsDetails, arguments: {"breakModel": breakingNewsModel, "breakNewsList": breakList, "isFromBreak": true, "fromShowMore": false});
}
}
},
);
}
}

View File

@@ -0,0 +1,140 @@
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:intl/intl.dart';
import 'package:news/utils/hiveBoxKeys.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/data/models/WeatherData.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
class WeatherDataView extends StatefulWidget {
final WeatherDetails weatherData;
const WeatherDataView({super.key, required this.weatherData});
@override
WeatherDataState createState() => WeatherDataState();
}
class WeatherDataState extends State<WeatherDataView> {
late Future<void> _future;
@override
void initState() {
super.initState();
_future = UiUtils.checkIfValidLocale(langCode: Hive.box(settingsBoxKey).get(currentLanguageCodeKey));
}
Widget weatherDataView() {
return FutureBuilder<void>(
future: _future,
builder: (context, snapshot) {
DateTime now = DateTime.now();
String day = DateFormat('EEEE').format(now);
WeatherDetails weatherData = widget.weatherData;
return Container(
margin: const EdgeInsetsDirectional.only(top: 15.0),
padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10.0), color: UiUtils.getColorScheme(context).surface),
height: MediaQuery.of(context).size.height * 0.14,
child: Row(
children: <Widget>[
Expanded(
flex: 3,
child: Column(
children: <Widget>[
CustomTextLabel(
text: 'weatherLbl',
textStyle: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: true),
Row(
children: <Widget>[
Image.network("https:${weatherData.icon!}", width: 40.0, height: 40.0),
Padding(
padding: const EdgeInsetsDirectional.only(start: 7.0),
child: CustomTextLabel(
text: "${weatherData.tempC!.toString()}\u2103",
textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
overflow: TextOverflow.ellipsis,
softWrap: true,
maxLines: 1))
],
)
],
),
),
const Spacer(),
Expanded(
flex: 4,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
CustomTextLabel(
text: "${weatherData.name!},${weatherData.region!}",
textStyle: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.w600),
overflow: TextOverflow.ellipsis,
softWrap: true,
maxLines: 1),
CustomTextLabel(
text: weatherData.country!,
textStyle: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.w600),
overflow: TextOverflow.ellipsis,
softWrap: true,
maxLines: 1),
Padding(
padding: const EdgeInsetsDirectional.only(top: 3.0),
child: CustomTextLabel(
text: day,
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
overflow: TextOverflow.ellipsis,
softWrap: true,
maxLines: 1)),
Padding(
padding: const EdgeInsetsDirectional.only(top: 3.0),
child: CustomTextLabel(
text: weatherData.text!,
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: true)),
Expanded(
child: Padding(
padding: const EdgeInsetsDirectional.only(top: 3.0),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Icon(Icons.arrow_upward_outlined, size: 13.0, color: UiUtils.getColorScheme(context).primaryContainer),
CustomTextLabel(
text: "H:${weatherData.maxTempC!.toString()}\u2103",
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: true),
Padding(
padding: const EdgeInsetsDirectional.only(start: 8.0),
child: Icon(Icons.arrow_downward_outlined, size: 13.0, color: UiUtils.getColorScheme(context).primaryContainer)),
CustomTextLabel(
text: "L:${weatherData.minTempC!.toString()}\u2103",
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.8)),
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: true)
],
)),
)
],
),
)
],
));
},
);
}
@override
Widget build(BuildContext context) {
return weatherDataView();
}
}