Files
elcaribe/news-app/lib/ui/screens/ManagePreference.dart

317 lines
13 KiB
Dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:news/ui/widgets/errorContainerWidget.dart';
import 'package:news/utils/ErrorMessageKeys.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/app/routes.dart';
import 'package:news/cubits/Auth/authCubit.dart';
import 'package:news/cubits/UserPreferences/setUserPreferenceCatCubit.dart';
import 'package:news/cubits/UserPreferences/userByCategoryCubit.dart';
import 'package:news/cubits/appLocalizationCubit.dart';
import 'package:news/cubits/categoryCubit.dart';
import 'package:news/data/models/CategoryModel.dart';
import 'package:news/ui/styles/colors.dart';
import 'package:news/ui/widgets/SnackBarWidget.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/ui/widgets/networkImage.dart';
import 'package:news/ui/widgets/customBackBtn.dart';
import 'package:news/ui/widgets/customTextBtn.dart';
class ManagePref extends StatefulWidget {
final int? from;
const ManagePref({super.key, this.from});
@override
State<StatefulWidget> createState() {
return StateManagePref();
}
static Route route(RouteSettings routeSettings) {
final arguments = routeSettings.arguments as Map<String, dynamic>;
return CupertinoPageRoute(builder: (_) => ManagePref(from: arguments['from']));
}
}
class StateManagePref extends State<ManagePref> with TickerProviderStateMixin {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
String catId = "";
List<String> selectedChoices = [];
String selCatId = "";
static int _count = 0;
List<bool> _checks = [];
late final ScrollController _categoryScrollController = ScrollController()..addListener(hasMoreCategoryScrollListener);
@override
void initState() {
super.initState();
getUserData();
}
void getUserData() {
Future.delayed(Duration.zero, () {
context.read<UserByCatCubit>().getUserById();
});
}
@override
void dispose() {
_categoryScrollController.dispose();
super.dispose();
}
void hasMoreCategoryScrollListener() {
if (_categoryScrollController.offset >= _categoryScrollController.position.maxScrollExtent && !_categoryScrollController.position.outOfRange) {
if (context.read<CategoryCubit>().hasMoreCategory()) {
context.read<CategoryCubit>().getMoreCategory(langId: context.read<AppLocalizationCubit>().state.id);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(key: _scaffoldKey, appBar: setAppBar(), body: contentView());
}
setAppBar() {
return PreferredSize(
preferredSize: const Size(double.infinity, 70),
child: UiUtils.applyBoxShadow(
context: context,
child: AppBar(
leading: widget.from == 1 ? const CustomBackButton(horizontalPadding: 15) : const SizedBox.shrink(),
titleSpacing: 0.0,
centerTitle: false,
backgroundColor: Colors.transparent,
title: CustomTextLabel(
text: 'managePreferences',
textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.w600, letterSpacing: 0.5)),
actions: [skipBtn()],
),
));
}
skipBtn() {
if (widget.from != 1) {
return Align(
alignment: Alignment.topRight,
child: CustomTextButton(
onTap: () {
Navigator.of(context).pushReplacementNamed(Routes.home, arguments: false);
},
text: 'skip',
color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7)));
} else {
return const SizedBox.shrink();
}
}
contentView() {
return BlocConsumer<UserByCatCubit, UserByCatState>(
bloc: context.read<UserByCatCubit>(),
listener: (context, state) {
if (state is UserByCatFetchSuccess) {
if (state.userByCat != null) {
for (int i = 0; i < state.userByCat.length; i++) {
catId = state.userByCat["category_id"];
}
setState(() {
selectedChoices = catId == "" ? catId.split('') : catId.split(',');
});
}
context.read<CategoryCubit>().getCategory(langId: context.read<AppLocalizationCubit>().state.id);
}
},
builder: (context, state) {
return BlocConsumer<CategoryCubit, CategoryState>(
bloc: context.read<CategoryCubit>(),
listener: (context, state) {
if (state is CategoryFetchSuccess) {
if ((state).category.isNotEmpty) {
setState(() {
_count = (state).category.length;
_checks = List.generate(_count, (i) => (selectedChoices.contains((state).category[i].id)) ? true : false);
});
}
}
},
builder: (context, state) {
if (state is CategoryFetchInProgress || state is CategoryInitial) {
return UiUtils.showCircularProgress(true, Theme.of(context).primaryColor);
}
if (state is CategoryFetchFailure) {
return ErrorContainerWidget(
errorMsg: (state.errorMessage.contains(ErrorMessageKeys.noInternet)) ? UiUtils.getTranslatedLabel(context, 'internetmsg') : state.errorMessage, onRetry: getUserData);
}
return SingleChildScrollView(
padding: const EdgeInsetsDirectional.only(start: 15.0, end: 15.0, bottom: 20.0),
controller: _categoryScrollController,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsetsDirectional.only(top: 25.0),
child: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 20, mainAxisSpacing: 20),
shrinkWrap: true,
itemCount: (state as CategoryFetchSuccess).category.length,
physics: const ClampingScrollPhysics(),
itemBuilder: (context, index) {
return _buildCategoryContainer(
category: state.category[index],
hasMore: state.hasMore,
hasMoreCategoryFetchError: state.hasMoreFetchError,
index: index,
totalCurrentCategory: state.category.length);
})),
nxtBtn()
],
),
);
});
});
}
selectCatTxt() {
return Transform(
transform: Matrix4.translationValues(-50.0, 0.0, 0.0),
child: CustomTextLabel(
text: 'sel_pref_cat', textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.w100, letterSpacing: 0.5)),
);
}
_buildCategoryContainer({required CategoryModel category, required int index, required int totalCurrentCategory, required bool hasMoreCategoryFetchError, required bool hasMore}) {
if (index == totalCurrentCategory - 1 && index != 0) {
if (hasMore) {
if (hasMoreCategoryFetchError) {
return const SizedBox.shrink();
} else {
return Center(child: Padding(padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 8.0), child: UiUtils.showCircularProgress(true, Theme.of(context).primaryColor)));
}
}
}
return Container(
padding: EdgeInsets.zero,
decoration: const BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(15))),
child: InkWell(
onTap: () {
_checks[index] = !_checks[index];
if (selectedChoices.contains(category.id)) {
selectedChoices.remove(category.id);
setState(() {});
} else {
selectedChoices.add(category.id!);
setState(() {});
}
if (selectedChoices.isEmpty) {
setState(() {
selectedChoices.add("0");
});
} else {
if (selectedChoices.contains("0")) {
selectedChoices = List.from(selectedChoices)..remove("0");
}
}
},
child: Stack(
fit: StackFit.expand,
children: [
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(15.0)),
child: CustomNetworkImage(networkImageUrl: category.image!, fit: BoxFit.cover, isVideo: false, height: MediaQuery.of(context).size.height / 2.9, width: double.maxFinite)),
Positioned.directional(
//checkbox
textDirection: Directionality.of(context),
end: 10,
top: 10,
child: Container(
height: 20,
width: 20,
decoration:
BoxDecoration(borderRadius: const BorderRadius.all(Radius.circular(5)), color: selectedChoices.contains(category.id) ? Theme.of(context).primaryColor : secondaryColor),
child: selectedChoices.contains(category.id) ? const Icon(Icons.check_rounded, color: secondaryColor, size: 20) : null)),
Positioned.directional(
textDirection: Directionality.of(context),
bottom: 0,
start: 0,
end: 0,
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(15.0), bottomRight: Radius.circular(15.0)),
gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [darkSecondaryColor.withOpacity(0.03), darkSecondaryColor.withOpacity(0.85)])),
padding: EdgeInsets.zero,
margin: EdgeInsets.zero,
child: Padding(
padding: const EdgeInsetsDirectional.all(10),
child: CustomTextLabel(
text: category.categoryName!,
textStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.normal, color: Colors.white),
),
),
),
),
],
),
));
}
nxtBtn() {
return BlocConsumer<SetUserPrefCatCubit, SetUserPrefCatState>(
bloc: context.read<SetUserPrefCatCubit>(),
listener: (context, state) {
if (state is SetUserPrefCatFetchSuccess) {
showSnackBar(UiUtils.getTranslatedLabel(context, 'preferenceSave'), context);
if (widget.from == 2) {
Navigator.of(context).pushReplacementNamed(Routes.home, arguments: false);
} else {
Navigator.pop(context);
}
}
},
builder: (context, state) {
return Padding(
padding: const EdgeInsets.only(top: 30.0),
child: InkWell(
child: Container(
height: 45.0,
width: MediaQuery.of(context).size.width * 0.95,
alignment: Alignment.center,
decoration: BoxDecoration(color: Theme.of(context).primaryColor, borderRadius: BorderRadius.circular(15.0)),
child: (state is SetUserPrefCatFetchInProgress)
? UiUtils.showCircularProgress(true, secondaryColor)
: CustomTextLabel(
//@Start
text: (widget.from == 2) ? 'nxt' : 'saveLbl',
//from Settings
textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(color: secondaryColor, fontWeight: FontWeight.w600, fontSize: 18),
),
),
onTap: () async {
if (context.read<AuthCubit>().getUserId() != "0") {
if (selectedChoices.isEmpty) {
//no preference selected
Navigator.of(context).pushNamedAndRemoveUntil(Routes.home, (Route<dynamic> route) => false);
return;
} else if (selectedChoices.length == 1) {
setState(() {
selCatId = selectedChoices.join();
});
} else {
setState(() {
selCatId = selectedChoices.join(',');
});
}
context.read<SetUserPrefCatCubit>().setUserPrefCat(catId: selCatId);
} else {
UiUtils.loginRequired(context);
}
}),
);
});
}
}