Skip to content

Instantly share code, notes, and snippets.

@mushfiqweb
Created October 14, 2024 11:48
Show Gist options
  • Save mushfiqweb/6a34ead7dd093af87fd524771e34eb11 to your computer and use it in GitHub Desktop.
Save mushfiqweb/6a34ead7dd093af87fd524771e34eb11 to your computer and use it in GitHub Desktop.
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