Created
October 14, 2024 11:48
-
-
Save mushfiqweb/6a34ead7dd093af87fd524771e34eb11 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:math'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter_bloc/flutter_bloc.dart'; | |
import 'package:flutter_screenutil/flutter_screenutil.dart'; | |
import 'package:spiresoft/app/core/constraints/app_colors.dart'; | |
import 'package:spiresoft/app/core/constraints/app_text_style.dart'; | |
import 'package:spiresoft/app/core/utils/custom_theme_colors.dart'; | |
import 'package:spiresoft/app/core/widgets/app_checkbox.dart'; | |
import 'package:spiresoft/app/core/widgets/app_glow_effect.dart'; | |
import 'package:spiresoft/app/core/widgets/circle_icon_button.dart'; | |
import 'package:spiresoft/app/data/pojo/notification/get_notification_list_model.dart'; | |
import 'package:spiresoft/app/routes/app_routes.dart'; | |
import 'package:spiresoft/l10n/app_localizations.dart'; | |
import '../../core/constraints/app_constraints.dart'; | |
import '../../core/constraints/tr_constraints.dart'; | |
import '../../core/state/theme/theme_bloc.dart'; | |
import '../../core/widgets/app_app_bar.dart'; | |
import '../../network/api_urls.dart'; | |
class NotificationList extends StatefulWidget { | |
const NotificationList({super.key}); | |
@override | |
State<NotificationList> createState() => _NotificationListState(); | |
} | |
class _NotificationListState extends State<NotificationList> { | |
final scrollController = ScrollController(); | |
List<Data> notificationList = [], filteredNotificationList = []; | |
int currentPage = 1, totalData = 1; | |
bool isShowAll = true, isDataLoaded = false; | |
String courtOrder = "Court order", | |
courtHearing = "Court hearing", | |
drugTest = "Drug test", | |
probation = "Probation", | |
reports = "Reports", | |
checkIn = "Check-in", | |
selectedFilter = ""; | |
StateSetter? setBottomSheetState; | |
@override | |
void initState() { | |
logger.d('This logger is for easy navigation from the run console.'); | |
Future.delayed(Duration.zero, () { | |
getNotificationList(); | |
// List.generate(20, (index) { | |
// notificationList.add( | |
// Data( | |
// message: | |
// "You received a message from Officer’s Name... You are expected to meet with Ser Criston on the 5th of September for your hearing.", | |
// subject: "Officer Message", | |
// notificationDate: "2024-08-19 20:12:31.255944", | |
// categoryCode: [ | |
// courtOrder, | |
// courtHearing, | |
// drugTest, | |
// probation, | |
// reports, | |
// checkIn | |
// ][Random().nextInt(6)], | |
// ), | |
// ); | |
// }); | |
}); | |
// Future.delayed(const Duration(seconds: 3), () { | |
// setState(() { | |
// filteredNotificationList = notificationList; | |
// isDataLoaded = true; | |
// }); | |
// }); | |
scrollController.addListener(() { | |
if (scrollController.position.atEdge) { | |
bool isTop = scrollController.position.pixels == 0; | |
if (isTop) { | |
} else { | |
if (totalData > notificationList.length) { | |
currentPage += 1; | |
getNotificationList(); | |
} | |
} | |
} | |
}); | |
super.initState(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
final customColor = Theme.of(context).extension<CustomColor>(); | |
final isDark = appHelper.isDark(context); | |
return Scaffold( | |
backgroundColor: customColor?.white50Black60 ?? AppColors.white50Color, | |
appBar: AppAppBar( | |
title: notificationTr.tr(context), | |
// needToShowFilter: true, | |
// onFilterClick: () { | |
// filterClick(); | |
// }, | |
), | |
body: SafeArea( | |
child: Padding( | |
padding: mainPadding(17, 20, bottomPadding: 0), | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Row( | |
mainAxisSize: MainAxisSize.max, | |
children: [ | |
Expanded( | |
child: Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Flexible( | |
child: AppCheckbox( | |
isChecked: isShowAll, | |
clickListener: !isShowAll ? showAllClick : null, | |
title: showAllTr.tr(context), | |
needStandardPadding: true, | |
titleFontWeight: | |
isShowAll ? FontWeight.w700 : FontWeight.w400, | |
), | |
), | |
], | |
), | |
), | |
Container( | |
color: AppColors.black10Color, | |
height: 50, | |
width: .5, | |
), | |
Expanded( | |
child: Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
IntrinsicWidth( | |
child: AppCheckbox( | |
isChecked: !isShowAll, | |
clickListener: isShowAll ? showAllClick : null, | |
title: showUnreadTr.tr(context), | |
needStandardPadding: true, | |
titleFontWeight: | |
!isShowAll ? FontWeight.w700 : FontWeight.w400, | |
titleColor: isDark && !isShowAll | |
? AppColors.white60Color | |
: null, | |
// suffixWidget: Random().nextBool() | |
// ? Padding( | |
// padding: mainPadding(3, 0, rightPadding: 0), | |
// child: Container( | |
// width: 8.r, | |
// height: 8.r, | |
// decoration: BoxDecoration( | |
// color: AppColors.randomColor3, | |
// borderRadius: | |
// BorderRadius.circular(100), | |
// ), | |
// ), | |
// ) | |
// : null, | |
), | |
), | |
], | |
), | |
), | |
], | |
), | |
appWidget.divider( | |
height: 32, | |
color: isDark ? AppColors.black50Color : AppColors.black10Color, | |
), | |
if (!isDataLoaded) | |
const Expanded( | |
child: Center( | |
child: CircularProgressIndicator.adaptive(), | |
), | |
), | |
// if (!isShowAll) blankDesign(), | |
// if (isShowAll) ...[ | |
filteredNotificationList.isEmpty && isDataLoaded | |
? blankDesign(isDark) | |
: Expanded( | |
child: ListView.separated( | |
itemCount: filteredNotificationList.length, | |
shrinkWrap: true, | |
physics: const BouncingScrollPhysics(), | |
itemBuilder: (context, index) { | |
var data = filteredNotificationList[index]; | |
if (index == 0) { | |
return Column( | |
children: [ | |
gapH16, | |
notificationDesign( | |
data, | |
index, | |
customColor: customColor, | |
isDark: isDark, | |
), | |
], | |
); | |
} else if (index == 15) { | |
return Column( | |
children: [ | |
notificationDesign( | |
data, | |
index, | |
customColor: customColor, | |
isDark: isDark, | |
), | |
gapH16, | |
], | |
); | |
} | |
return notificationDesign( | |
data, | |
index, | |
customColor: customColor, | |
isDark: isDark, | |
); | |
}, | |
separatorBuilder: (BuildContext context, int index) { | |
return gapH8; | |
}, | |
), | |
), | |
// ] | |
], | |
), | |
), | |
), | |
); | |
} | |
Widget blankDesign(bool isDark) { | |
return Expanded( | |
child: Center( | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
crossAxisAlignment: CrossAxisAlignment.center, | |
mainAxisSize: MainAxisSize.max, | |
children: [ | |
Container( | |
height: 144.r, | |
width: 144.r, | |
decoration: BoxDecoration( | |
color: | |
isDark ? AppColors.black50Color : const Color(0xFFD9D9D9), | |
borderRadius: BorderRadius.circular(32.r), | |
), | |
), | |
gapH12, | |
Text( | |
itsLonelyInHere.tr(context), | |
style: textStyle( | |
context, | |
fontSize: 24, | |
isBlack30Percent: true, | |
), | |
), | |
gapH3, | |
Text( | |
allNotificationsWouldShowUpHere.tr(context), | |
style: text14Style( | |
context, | |
isInter: true, | |
isBlack30Percent: true, | |
), | |
), | |
appWidget.gapH(.2.sh) | |
], | |
), | |
), | |
); | |
} | |
Widget notificationDesign(Data data, int index, | |
{CustomColor? customColor, bool isDark = false}) { | |
bool isExpanded = data.isExpanded ?? false; | |
return InkWell( | |
onTap: () { | |
onNotificationClicked(data, index); | |
}, | |
child: Container( | |
width: double.infinity, | |
padding: mainPadding(16, 16), | |
decoration: BoxDecoration( | |
color: isDark | |
? AppColors.randomColor14.withOpacity(.24) | |
: AppColors.white10Color, | |
borderRadius: BorderRadius.circular(24.r), | |
), | |
child: Row( | |
crossAxisAlignment: CrossAxisAlignment.center, | |
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |
children: [ | |
Expanded( | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.start, | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Row( | |
children: [ | |
if (data.viewedDate == null) ...[ | |
Padding( | |
padding: mainPadding(3, 0, rightPadding: 0), | |
child: GlowingContainer(), | |
// child: Container( | |
// width: 8.r, | |
// height: 8.r, | |
// decoration: BoxDecoration( | |
// color: AppColors.randomColor3, | |
// borderRadius: BorderRadius.circular(100), | |
// ), | |
// ), | |
), | |
gapW8 | |
], | |
Text( | |
(data.subject ?? "").length > 25 | |
? (data.subject ?? "").substring(0, 25) + "..." | |
: data.subject ?? "", | |
overflow: TextOverflow.ellipsis, | |
style: text16Style( | |
context, | |
isWeight800: true, | |
color: isDark ? AppColors.white60Color : null, | |
), | |
), | |
], | |
), | |
gapH8, | |
Text.rich( | |
textAlign: TextAlign.start, | |
maxLines: 1, | |
overflow: TextOverflow.ellipsis, | |
// maxLines: isExpanded ? null : 2, | |
// overflow: isExpanded ? null : TextOverflow.ellipsis, | |
TextSpan( | |
children: [ | |
TextSpan( | |
text: data.message, | |
style: text14Style( | |
context, | |
isInter: true, | |
isWhite50Percent: isDark, | |
), | |
), | |
// TextSpan( | |
// text: data.message?.substring( | |
// (data.message?.indexOf("Officer’s Name...") ?? | |
// 0) + | |
// 18), | |
// style: text14Style( | |
// context, | |
// isInter: true, | |
// ), | |
// ), | |
], | |
), | |
), | |
gapH8, | |
Row( | |
children: [ | |
BlocBuilder<ThemeBloc, ThemeState>( | |
builder: (context, state) { | |
return Text( | |
appHelper.timeAgo(data.notificationDate ?? ""), | |
style: text12Style( | |
context, | |
isBlack30Percent: !isDark, | |
isBlack20Percent: isDark, | |
), | |
); | |
}, | |
), | |
gapW8, | |
// notificationCategoryDesign(data.categoryCode ?? ""), | |
], | |
) | |
], | |
), | |
), | |
CircleImageButton( | |
image: isExpanded ? "ic_down_arrow.png" : "ic_big_next.png", | |
imageColor: isExpanded | |
? (isDark | |
? AppColors.drugTestDarkBG | |
: AppColors.secondaryColor) | |
: (isDark ? AppColors.white10Color : AppColors.black60Color), | |
borderColor: isExpanded | |
? (isDark | |
? AppColors.secondary3Color | |
: AppColors.secondaryColor) | |
: (isDark ? AppColors.black50Color : null), | |
bgColor: isDark ? AppColors.white100Color : null, | |
// onClick: () { | |
// setState(() { | |
// filteredNotificationList[index].isExpanded = !isExpanded; | |
// }); | |
// }, | |
) | |
], | |
), | |
), | |
); | |
} | |
onNotificationClicked(Data data, int index) async { | |
Navigator.pushNamed( | |
context, | |
Paths.NOTIFICATION_DETAILS, | |
arguments: notificationList[index], | |
); | |
if (data.viewedDate == null) { | |
var resData = await apiClient.postAPI( | |
context, | |
setNotificationViewedUrl, | |
"'${data.id}'", | |
onNotificationClicked, | |
needToHideLoader: true, | |
needToShowLoader: false, | |
// model: getNotificationListModelFromJson, | |
); | |
if (resData != null) { | |
data.viewedDate = DateTime.now().toString(); | |
if (!isShowAll) { | |
filteredNotificationList.removeWhere((item) => item.id == data.id); | |
} | |
setState(() { | |
data = data; | |
filteredNotificationList = filteredNotificationList; | |
// filteredNotificationList[index].isExpanded = | |
// !(filteredNotificationList[index].isExpanded ?? false); | |
}); | |
} | |
} | |
} | |
Widget notificationCategoryDesign(String category) { | |
if (category == "") { | |
return const SizedBox.shrink(); | |
} | |
if (category == probation) { | |
return notificationCategoryChildDesign( | |
category, | |
AppColors.probationBG, | |
AppColors.black30Color, | |
); | |
} else if (category == courtHearing) { | |
return notificationCategoryChildDesign( | |
category, | |
AppColors.courtHearingBG, | |
AppColors.courtHearingFG, | |
); | |
} else if (category == reports) { | |
return notificationCategoryChildDesign( | |
category, | |
AppColors.reportsBG, | |
AppColors.reportsFG, | |
); | |
} else if (category == courtOrder) { | |
return notificationCategoryChildDesign( | |
category, | |
AppColors.courtOrderBG, | |
AppColors.courtOrderFG, | |
); | |
} else if (category == drugTest) { | |
return notificationCategoryChildDesign( | |
category, | |
AppColors.drugTestBG, | |
AppColors.drugTestFG, | |
); | |
} else if (category == checkIn) { | |
return notificationCategoryChildDesign( | |
category, | |
AppColors.checkInBG, | |
AppColors.checkInFG, | |
); | |
} | |
return Text(category); | |
} | |
Widget notificationCategoryChildDesign( | |
String title, Color bgColor, Color textColor) { | |
return Container( | |
decoration: BoxDecoration( | |
color: bgColor, | |
borderRadius: BorderRadius.circular(4.r), | |
), | |
padding: mainPadding(8, 4), | |
child: Text( | |
title, | |
style: textStyle( | |
context, | |
fontSize: 8, | |
isWeight600: true, | |
color: textColor, | |
), | |
), | |
); | |
} | |
void getNotificationList() async { | |
if (currentPage == 1) { | |
notificationList.clear(); | |
} | |
var postData = <String, dynamic>{}; | |
postData["pageIndex"] = currentPage; | |
postData["pageSize"] = 20; | |
postData["SearchBy"] = isShowAll ? '' : 'Unread'; | |
var data = await apiClient.postAPI( | |
context, | |
getNotificationListUrl, | |
postData, | |
getNotificationList, | |
model: getNotificationListModelFromJson, | |
); | |
if (data != null) { | |
GetNotificationListModel model = | |
getNotificationListModelFromJson(data.toString()); | |
if (model.state == 1) { | |
model.data?.forEach((data) { | |
notificationList.add(data); | |
}); | |
setState(() { | |
notificationList = notificationList; | |
filteredNotificationList = notificationList; | |
isDataLoaded = true; | |
}); | |
if (currentPage == 1) { | |
totalData = (model.total ?? 0).toInt(); | |
} | |
} else { | |
if (mounted) { | |
appWidget.showSimpleToast(context, model.msg); | |
} | |
} | |
} | |
} | |
void showAllClick() { | |
setState(() { | |
isShowAll = !isShowAll; | |
currentPage = 1; | |
}); | |
getNotificationList(); | |
} | |
void filterClick() { | |
showModalBottomSheet<void>( | |
context: context, | |
builder: (BuildContext context) { | |
return StatefulBuilder( | |
builder: (BuildContext context, StateSetter setState) { | |
setBottomSheetState = setState; | |
return IntrinsicHeight( | |
child: Container( | |
decoration: BoxDecoration( | |
borderRadius: onlyTopRadius(), | |
), | |
padding: mainPadding(0, 16, bottomPadding: 4), | |
child: Column( | |
mainAxisSize: MainAxisSize.min, | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: <Widget>[ | |
Padding( | |
padding: mainPadding(16, 0), | |
child: Text( | |
'${sortByTr.tr(context)}:', | |
style: text16Style( | |
context, | |
isWeight800: true, | |
isBlack40Percent: true, | |
), | |
), | |
), | |
gapH12, | |
filterItemDesign( | |
courtOrder, | |
AppColors.courtOrderBG, | |
AppColors.courtOrderFG, | |
"ic_court_order.png", | |
selectedFilter == courtOrder, | |
), | |
filterItemDesign( | |
courtHearing, | |
AppColors.courtHearingBG, | |
AppColors.courtHearingFG, | |
"ic_court_hearing.png", | |
selectedFilter == courtHearing, | |
), | |
filterItemDesign( | |
drugTest, | |
AppColors.drugTestBG, | |
AppColors.drugTestFG, | |
"ic_drug_test.png", | |
selectedFilter == drugTest, | |
), | |
filterItemDesign( | |
probation, | |
AppColors.probationBG, | |
AppColors.probationFG, | |
"ic_probation.png", | |
selectedFilter == probation, | |
), | |
filterItemDesign( | |
reports, | |
AppColors.reportsBG, | |
AppColors.reportsFG, | |
"ic_reports.png", | |
selectedFilter == reports, | |
), | |
filterItemDesign( | |
checkIn, | |
AppColors.checkInBG, | |
AppColors.checkInFG, | |
"ic_check_in.png", | |
selectedFilter == checkIn, | |
), | |
], | |
), | |
), | |
); | |
}); | |
}, | |
); | |
} | |
Widget filterItemDesign(String name, Color bgColor, Color iconColor, | |
String icon, bool isSelected) { | |
return InkWell( | |
onTap: () { | |
if (setBottomSheetState != null) { | |
setBottomSheetState!(() { | |
selectedFilter = name; | |
}); | |
} | |
List<Data> tempList = []; | |
for (var data in notificationList) { | |
if (data.categoryCode == selectedFilter) { | |
tempList.add(data); | |
} | |
} | |
setState(() { | |
filteredNotificationList = tempList; | |
}); | |
Navigator.pop(context); | |
}, | |
borderRadius: BorderRadius.circular(16), | |
child: Padding( | |
padding: mainPadding(16, 12), | |
child: Row( | |
mainAxisSize: MainAxisSize.max, | |
children: [ | |
Container( | |
height: 40.r, | |
width: 40.r, | |
decoration: BoxDecoration( | |
color: bgColor, | |
borderRadius: BorderRadius.circular(100), | |
), | |
padding: mainPadding(8, 8), | |
child: Image.asset( | |
"assets/png/$icon", | |
color: iconColor, | |
), | |
), | |
gapW8, | |
Text( | |
name, | |
style: text16Style(context, isWeight600: true), | |
), | |
const Spacer(), | |
Container( | |
height: 24.0, | |
width: 24.0, | |
decoration: BoxDecoration( | |
borderRadius: BorderRadius.circular(100), | |
border: Border.all( | |
color: AppColors.black10Color, | |
), | |
), | |
child: isSelected | |
? Padding( | |
padding: const EdgeInsets.all(2), | |
child: Container( | |
decoration: BoxDecoration( | |
borderRadius: BorderRadius.circular(100), | |
color: AppColors.black10Color, | |
), | |
), | |
) | |
: const SizedBox.shrink(), | |
), | |
], | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment