elCaribe app - customization and branding
This commit is contained in:
197
news-app/lib/ui/screens/SubCategory/Widgets/SubCatNewsList.dart
Normal file
197
news-app/lib/ui/screens/SubCategory/Widgets/SubCatNewsList.dart
Normal file
@@ -0,0 +1,197 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:news/cubits/subCatNewsCubit.dart';
|
||||
import 'package:news/cubits/surveyQuestionCubit.dart';
|
||||
import 'package:news/data/repositories/Settings/settingsLocalDataRepository.dart';
|
||||
import 'package:news/ui/widgets/NewsItem.dart';
|
||||
import 'package:news/ui/screens/SubCategory/Widgets/showSurveyQuestion.dart';
|
||||
import 'package:news/ui/screens/SubCategory/Widgets/showSurveyResult.dart';
|
||||
import 'package:news/ui/widgets/errorContainerWidget.dart';
|
||||
import 'package:news/ui/widgets/shimmerNewsList.dart';
|
||||
import 'package:news/utils/ErrorMessageKeys.dart';
|
||||
import 'package:news/utils/constant.dart';
|
||||
import 'package:news/cubits/Auth/authCubit.dart';
|
||||
import 'package:news/cubits/appLocalizationCubit.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
|
||||
class SubCatNewsList extends StatefulWidget {
|
||||
final int from;
|
||||
final String catId;
|
||||
final String? subCatId;
|
||||
|
||||
const SubCatNewsList({super.key, required this.from, required this.catId, this.subCatId});
|
||||
|
||||
@override
|
||||
SubCatNewsListState createState() => SubCatNewsListState();
|
||||
|
||||
static Route route(RouteSettings routeSettings) {
|
||||
final arguments = routeSettings.arguments as Map<String, dynamic>;
|
||||
return CupertinoPageRoute(builder: (_) => SubCatNewsList(from: arguments['from'], catId: arguments['catId'], subCatId: arguments['subCatId']));
|
||||
}
|
||||
}
|
||||
|
||||
class SubCatNewsListState extends State<SubCatNewsList> with AutomaticKeepAliveClientMixin {
|
||||
List<NewsModel> combineList = [];
|
||||
int totalSurveyQue = 0;
|
||||
Set<String> get locationValue => SettingsLocalDataRepository().getLocationCityValues();
|
||||
late final ScrollController controller = ScrollController()..addListener(hasMoreNotiScrollListener);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
getSubCatNewsData();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
totalSurveyQue = 0;
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future getSubCatNewsData() async {
|
||||
Future.delayed(Duration.zero, () {
|
||||
if (context.read<AuthCubit>().getUserId() != "0") {
|
||||
context.read<SurveyQuestionCubit>().getSurveyQuestion(langId: context.read<AppLocalizationCubit>().state.id).whenComplete(() {
|
||||
getSubcategoryNews();
|
||||
});
|
||||
} else {
|
||||
getSubcategoryNews();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void hasMoreNotiScrollListener() {
|
||||
if (controller.position.maxScrollExtent == controller.offset) {
|
||||
if (context.read<SubCatNewsCubit>().hasMoreSubCatNews()) {
|
||||
context.read<SubCatNewsCubit>().getMoreSubCatNews(
|
||||
langId: context.read<AppLocalizationCubit>().state.id,
|
||||
subCatId: widget.from == 2 ? widget.subCatId : null,
|
||||
catId: widget.from == 1 ? widget.catId : null,
|
||||
latitude: locationValue.first,
|
||||
longitude: locationValue.last);
|
||||
} else {}
|
||||
}
|
||||
}
|
||||
|
||||
updateCombineList(NewsModel model, int index) {
|
||||
setState(() {
|
||||
combineList[index] = model;
|
||||
});
|
||||
}
|
||||
|
||||
Widget getNewsList() {
|
||||
return BlocConsumer<SubCatNewsCubit, SubCatNewsState>(
|
||||
bloc: context.read<SubCatNewsCubit>(),
|
||||
listener: (context, state) {
|
||||
if (state is SubCatNewsFetchSuccess) {
|
||||
combineList.clear();
|
||||
int cur = 0;
|
||||
for (int i = 0; i < (state).subCatNews.length; i++) {
|
||||
if (i != 0 && i % surveyShow == 0) {
|
||||
if (context.read<SurveyQuestionCubit>().surveyList().isNotEmpty && context.read<SurveyQuestionCubit>().surveyList().length > cur) {
|
||||
combineList.add(context.read<SurveyQuestionCubit>().surveyList()[cur]);
|
||||
cur++;
|
||||
}
|
||||
}
|
||||
combineList.add((state).subCatNews[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
builder: (context, stateSubCat) {
|
||||
if (stateSubCat is SubCatNewsFetchSuccess) {
|
||||
return combineNewsList(stateSubCat, stateSubCat.subCatNews);
|
||||
}
|
||||
if (stateSubCat is SubCatNewsFetchFailure) {
|
||||
return ErrorContainerWidget(
|
||||
errorMsg: (stateSubCat.errorMessage.contains(ErrorMessageKeys.noInternet)) ? UiUtils.getTranslatedLabel(context, 'internetmsg') : stateSubCat.errorMessage, onRetry: getSubCatNewsData);
|
||||
}
|
||||
//stateSubCat is SubCatNewsFetchInProgress || stateSubCat is SubCatNewsInitial
|
||||
return ShimmerNewsList(isNews: true);
|
||||
});
|
||||
}
|
||||
|
||||
setTotalSurveyQueCount() {
|
||||
for (var element in combineList) {
|
||||
if (element.type == "survey") totalSurveyQue += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Widget combineNewsList(SubCatNewsFetchSuccess state, List<NewsModel> newsList) {
|
||||
setTotalSurveyQueCount();
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
combineList.clear();
|
||||
if (context.read<AuthCubit>().getUserId() != "0") {
|
||||
context.read<SurveyQuestionCubit>().getSurveyQuestion(langId: context.read<AppLocalizationCubit>().state.id).whenComplete(() {
|
||||
getSubcategoryNews();
|
||||
});
|
||||
} else {
|
||||
getSubcategoryNews();
|
||||
}
|
||||
setTotalSurveyQueCount();
|
||||
setState(() {});
|
||||
},
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsetsDirectional.symmetric(vertical: 15),
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: controller,
|
||||
itemCount: combineList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _buildNewsContainer(
|
||||
model: combineList[index], hasMore: state.hasMore, hasMoreNewsFetchError: state.hasMoreFetchError, index: index, totalCurrentNews: combineList.length, newsList: newsList);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
void getSubcategoryNews() {
|
||||
context.read<SubCatNewsCubit>().getSubCatNews(
|
||||
langId: context.read<AppLocalizationCubit>().state.id,
|
||||
subCatId: widget.from == 2 ? widget.subCatId : null,
|
||||
catId: widget.from == 1 ? widget.catId : null,
|
||||
latitude: locationValue.first,
|
||||
longitude: locationValue.last);
|
||||
}
|
||||
|
||||
_buildNewsContainer({required NewsModel model, required int index, required int totalCurrentNews, required bool hasMoreNewsFetchError, required bool hasMore, required List<NewsModel> newsList}) {
|
||||
if (index == totalCurrentNews - 1 && index != 0) {
|
||||
if (hasMore) {
|
||||
if (hasMoreNewsFetchError) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 8.0),
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
context.read<SubCatNewsCubit>().getMoreSubCatNews(
|
||||
langId: context.read<AppLocalizationCubit>().state.id,
|
||||
subCatId: widget.from == 2 ? widget.subCatId : null,
|
||||
catId: widget.from == 1 ? widget.catId : null,
|
||||
latitude: locationValue.first,
|
||||
longitude: locationValue.last);
|
||||
},
|
||||
icon: Icon(Icons.error, color: Theme.of(context).primaryColor)),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Center(child: Padding(padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 8.0), child: UiUtils.showCircularProgress(true, Theme.of(context).primaryColor)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return model.type == "survey"
|
||||
? model.from == 2
|
||||
? showSurveyQueResult(model, context, true)
|
||||
: ShowSurveyQue(model: model, index: index, surveyId: context.read<SurveyQuestionCubit>().getSurveyQuestionIndex(questionTitle: model.question!), updateList: updateCombineList)
|
||||
: NewsItem(model: model, index: (index <= totalSurveyQue) ? index : (index - totalSurveyQue), newslist: newsList, fromShowMore: false);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return getNewsList();
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
subcatShimmer() {
|
||||
return Shimmer.fromColors(
|
||||
baseColor: Colors.grey.withOpacity(0.4),
|
||||
highlightColor: Colors.grey.withOpacity(0.4),
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [0, 1, 2, 3, 4, 5, 6]
|
||||
.map((i) => Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 15, top: 0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5.0), color: const Color.fromARGB(255, 59, 49, 49)),
|
||||
height: 32.0,
|
||||
width: 70.0,
|
||||
)))
|
||||
.toList()),
|
||||
));
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:news/cubits/getSurveyAnswerCubit.dart';
|
||||
import 'package:news/cubits/setSurveyAnswerCubit.dart';
|
||||
import 'package:news/cubits/surveyQuestionCubit.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:news/cubits/appLocalizationCubit.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
import 'package:news/ui/widgets/SnackBarWidget.dart';
|
||||
|
||||
class ShowSurveyQue extends StatefulWidget {
|
||||
final NewsModel model;
|
||||
final int index;
|
||||
final String surveyId;
|
||||
final bool isPaddingRequired;
|
||||
final Function(NewsModel, int) updateList;
|
||||
|
||||
const ShowSurveyQue({super.key, required this.model, required this.index, required this.surveyId, required this.updateList, this.isPaddingRequired = true});
|
||||
|
||||
@override
|
||||
ShowSurveyQueState createState() => ShowSurveyQueState();
|
||||
}
|
||||
|
||||
class ShowSurveyQueState extends State<ShowSurveyQue> {
|
||||
String? optSel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return showSurveyQue();
|
||||
}
|
||||
|
||||
Widget showSurveyQue() {
|
||||
return BlocConsumer<SetSurveyAnsCubit, SetSurveyAnsState>(
|
||||
bloc: context.read<SetSurveyAnsCubit>(),
|
||||
listener: (context, state) {
|
||||
if (state is SetSurveyAnsInitial || state is SetSurveyAnsFetchInProgress) {
|
||||
Center(child: UiUtils.showCircularProgress(true, Theme.of(context).primaryColor));
|
||||
}
|
||||
if (state is SetSurveyAnsFetchSuccess) {
|
||||
context.read<SurveyQuestionCubit>().removeQuestion(widget.surveyId);
|
||||
context.read<GetSurveyAnsCubit>().getSurveyAns(langId: context.read<AppLocalizationCubit>().state.id);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return BlocConsumer<GetSurveyAnsCubit, GetSurveyAnsState>(
|
||||
bloc: context.read<GetSurveyAnsCubit>(),
|
||||
listener: (context, state) {
|
||||
if (state is GetSurveyAnsInitial || state is GetSurveyAnsFetchInProgress) {
|
||||
Center(child: UiUtils.showCircularProgress(true, Theme.of(context).primaryColor));
|
||||
}
|
||||
if (state is GetSurveyAnsFetchSuccess) {
|
||||
for (var element in state.getSurveyAns) {
|
||||
if (element.id == widget.model.id) {
|
||||
NewsModel newModel = element;
|
||||
newModel.from = 2;
|
||||
widget.updateList(newModel, widget.index);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: 15.0, left: (widget.isPaddingRequired) ? 15 : 0, right: (widget.isPaddingRequired) ? 15 : 0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10.0), color: UiUtils.getColorScheme(context).surface),
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Column(
|
||||
children: [
|
||||
CustomTextLabel(
|
||||
text: widget.model.question!, textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, height: 1.0)),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(top: 15.0, start: 7.0, end: 7.0),
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.vertical,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: widget.model.optionDataList!.length,
|
||||
itemBuilder: (context, j) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10.0),
|
||||
child: InkWell(
|
||||
child: Container(
|
||||
height: 50,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
color: optSel == widget.model.optionDataList![j].id ? Theme.of(context).primaryColor.withOpacity(0.1) : UiUtils.getColorScheme(context).secondary),
|
||||
child: CustomTextLabel(
|
||||
text: widget.model.optionDataList![j].options!,
|
||||
textStyle: Theme.of(context).textTheme.titleSmall?.copyWith(
|
||||
color: optSel == widget.model.optionDataList![j].id ? Theme.of(context).primaryColor : UiUtils.getColorScheme(context).primaryContainer,
|
||||
height: 1.0),
|
||||
textAlign: TextAlign.center)),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
optSel = widget.model.optionDataList![j].id;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
})),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 15.0),
|
||||
child: InkWell(
|
||||
child: Container(
|
||||
height: 40.0,
|
||||
width: MediaQuery.of(context).size.width * 0.35,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(color: secondaryColor, borderRadius: BorderRadius.circular(7.0)),
|
||||
child: CustomTextLabel(
|
||||
text: 'submitBtn',
|
||||
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: Theme.of(context).primaryColor, fontWeight: FontWeight.w600, letterSpacing: 0.6),
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
if (optSel != null) {
|
||||
//get survey id from survey question
|
||||
String currentIndex = context.read<SurveyQuestionCubit>().getSurveyQuestionIndex(questionTitle: widget.model.question!);
|
||||
context.read<SetSurveyAnsCubit>().setSurveyAns(optId: optSel!, queId: currentIndex);
|
||||
await Future.delayed(Duration(seconds: 2));
|
||||
} else {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'optSel'), context);
|
||||
}
|
||||
}),
|
||||
)
|
||||
],
|
||||
)));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||
import 'package:news/data/models/NewsModel.dart';
|
||||
|
||||
showSurveyQueResult(NewsModel model, BuildContext context, bool isPaddingRequired) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: 15.0, left: (isPaddingRequired) ? 15 : 0, right: (isPaddingRequired) ? 15 : 0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10.0), color: UiUtils.getColorScheme(context).surface),
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Column(
|
||||
children: [
|
||||
CustomTextLabel(text: model.question!, textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, height: 1.0)),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(top: 15.0, start: 7.0, end: 7.0),
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.vertical,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: model.optionDataList!.length,
|
||||
itemBuilder: (context, j) {
|
||||
return Padding(
|
||||
padding: const EdgeInsetsDirectional.only(bottom: 10.0, start: 15.0, end: 15.0),
|
||||
child: LinearPercentIndicator(
|
||||
animation: true,
|
||||
animationDuration: 1000,
|
||||
lineHeight: 40.0,
|
||||
percent: model.optionDataList![j].percentage! / 100,
|
||||
center: CustomTextLabel(text: "${(model.optionDataList![j].percentage!).toStringAsFixed(2)}%", textStyle: Theme.of(context).textTheme.titleSmall),
|
||||
barRadius: const Radius.circular(16),
|
||||
progressColor: Theme.of(context).primaryColor,
|
||||
isRTL: false,
|
||||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0)));
|
||||
})),
|
||||
],
|
||||
)));
|
||||
}
|
||||
Reference in New Issue
Block a user