You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
11KB

  1. import 'package:farm_tpf/custom_model/NotificationDTO.dart';
  2. import 'package:farm_tpf/data/repository/repository.dart';
  3. import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart';
  4. import 'package:farm_tpf/presentation/custom_widgets/dash_line_widget.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
  6. import 'package:farm_tpf/presentation/screens/notification/update_count_noti_bloc.dart';
  7. import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
  8. import 'package:farm_tpf/utils/NotificationsBloc.dart';
  9. import 'package:farm_tpf/utils/const_icons.dart';
  10. import 'package:farm_tpf/utils/pref.dart';
  11. import 'package:flutter/material.dart';
  12. import 'package:flutter_bloc/flutter_bloc.dart';
  13. import 'package:farm_tpf/utils/formatter.dart';
  14. import 'package:flutter_svg/svg.dart';
  15. import 'bloc/noti_bloc.dart';
  16. class NotificationScreen extends StatefulWidget {
  17. @override
  18. _NotificationScreenState createState() => _NotificationScreenState();
  19. }
  20. class _NotificationScreenState extends State<NotificationScreen> {
  21. var notiBloc = NotiBloc(repository: Repository());
  22. final _scrollController = ScrollController();
  23. final _scrollThreshold = 250.0;
  24. List<NotificationDTO> currentItems = new List<NotificationDTO>();
  25. int latestId = 0;
  26. int currentPage = 0;
  27. bool currentHasReachedMax = true;
  28. bool isUpdatingFromApi = true;
  29. Stream<LocalNotification> _notificationsStream;
  30. var pref = LocalPref();
  31. var token;
  32. Future<Null> getSharedPrefs() async {
  33. _scrollController.addListener(() {
  34. final maxScroll = _scrollController.position.maxScrollExtent;
  35. final currentScroll = _scrollController.position.pixels;
  36. if (maxScroll - currentScroll < _scrollThreshold) {
  37. notiBloc.add(DataFetched());
  38. }
  39. });
  40. token = await pref.getString(DATA_CONST.TOKEN_KEY);
  41. }
  42. @override
  43. void initState() {
  44. getSharedPrefs();
  45. notiBloc.add(DataFetched());
  46. _notificationsStream = NotificationsBloc.instance.notificationsStream;
  47. _notificationsStream.listen((notification) {
  48. updateCountNotiBloc.getNotifications((data) {}, (err) {});
  49. print('Notification: $notification');
  50. notiBloc.add(OnRefresh());
  51. });
  52. super.initState();
  53. }
  54. @override
  55. Widget build(BuildContext context) {
  56. return Scaffold(
  57. backgroundColor: Colors.white,
  58. body: BlocBuilder<NotiBloc, NotiState>(
  59. cubit: notiBloc,
  60. builder: (context, state) {
  61. if (state is NotiFailure) {
  62. return Center(child: Text(state.errorString));
  63. } else if (state is NotiSuccess) {
  64. updateCountNotiBloc.getNotifications((data) {}, (err) {});
  65. if (state.items.isEmpty) {
  66. return SafeArea(
  67. child: Column(
  68. crossAxisAlignment: CrossAxisAlignment.start,
  69. children: [
  70. SizedBox(
  71. height: 8,
  72. ),
  73. Padding(
  74. padding: const EdgeInsets.all(8.0),
  75. child: Text('Thông báo',
  76. style: TextStyle(
  77. fontWeight: FontWeight.w500, fontSize: 22)),
  78. ),
  79. Expanded(
  80. child: Center(child: Text("Không có thông báo")),
  81. ),
  82. ],
  83. ),
  84. );
  85. }
  86. currentItems = List<NotificationDTO>.from(state.items);
  87. currentPage = state.page;
  88. currentHasReachedMax = state.hasReachedMax;
  89. return SafeArea(
  90. child: Column(
  91. children: <Widget>[
  92. Container(
  93. padding: EdgeInsets.all(8),
  94. color: Colors.white,
  95. child: Row(
  96. children: [
  97. SizedBox(
  98. height: 8,
  99. ),
  100. Expanded(
  101. child: Text(
  102. 'Thông báo',
  103. style: TextStyle(
  104. fontWeight: FontWeight.w500, fontSize: 22),
  105. )),
  106. FlatButton(
  107. onPressed: () {
  108. notiBloc.add(
  109. MarkAllNotificationUpdate(status: "1"));
  110. },
  111. child: Text('Đánh dấu đã đọc tất cả',
  112. style: TextStyle(
  113. fontWeight: FontWeight.normal,
  114. fontSize: 14,
  115. color: Colors.blue)))
  116. ],
  117. )),
  118. Expanded(
  119. child: RefreshIndicator(
  120. child: ListView.builder(
  121. physics: AlwaysScrollableScrollPhysics(),
  122. itemBuilder: (BuildContext context, int index) {
  123. return index >= state.items.length
  124. ? BottomLoader()
  125. : ItemInfinityWidget(
  126. notiBloc: notiBloc,
  127. unread: state.unread,
  128. read: state.read,
  129. currentItems: currentItems,
  130. item: state.items[index],
  131. currentPage: state.page,
  132. currentReachedMax: state.hasReachedMax,
  133. );
  134. },
  135. itemCount: state.hasReachedMax
  136. ? state.items.length
  137. : state.items.length + 1,
  138. controller: _scrollController,
  139. ),
  140. onRefresh: () async {
  141. notiBloc.add(OnRefresh());
  142. }))
  143. ],
  144. ),
  145. );
  146. } else if (state is NotiLoadding) {
  147. return Center(
  148. child: LoadingListPage(),
  149. );
  150. }
  151. return Container();
  152. },
  153. ),
  154. );
  155. }
  156. @override
  157. void dispose() {
  158. _scrollController.dispose();
  159. super.dispose();
  160. }
  161. }
  162. class ItemInfinityWidget extends StatelessWidget {
  163. final int unread;
  164. final int read;
  165. final NotificationDTO item;
  166. final List<NotificationDTO> currentItems;
  167. final int currentPage;
  168. final bool currentReachedMax;
  169. final NotiBloc notiBloc;
  170. const ItemInfinityWidget(
  171. {Key key,
  172. @required this.unread,
  173. @required this.read,
  174. @required this.currentItems,
  175. @required this.item,
  176. @required this.currentPage,
  177. @required this.currentReachedMax,
  178. @required this.notiBloc})
  179. : super(key: key);
  180. @override
  181. Widget build(BuildContext context) {
  182. var type;
  183. try {
  184. type = int.parse(item.type);
  185. } catch (_) {
  186. type = -1;
  187. }
  188. return Column(
  189. children: [
  190. GestureDetector(
  191. child: Container(
  192. margin: EdgeInsets.all(4.0),
  193. child: Column(
  194. children: [
  195. ListTile(
  196. title: Text(item.subject),
  197. subtitle: Column(
  198. crossAxisAlignment: CrossAxisAlignment.start,
  199. children: <Widget>[
  200. Text(item.message),
  201. Row(children: [
  202. Icon(Icons.access_time,
  203. color: item.isRead == 1
  204. ? Colors.grey
  205. : Colors.blue,
  206. size: 18),
  207. SizedBox(
  208. width: 4,
  209. ),
  210. Text(item.sendDate.format_DDMMYY_HHmm(),
  211. style: TextStyle(
  212. color: item.isRead == 1
  213. ? Colors.grey
  214. : Colors.blue))
  215. ]),
  216. ],
  217. ),
  218. leading: SvgPicture.asset(AppIcons.icNotificationItem)),
  219. ],
  220. )),
  221. onTap: () {
  222. if (item.contents == "ENV_UPDATE") {
  223. Navigator.push(
  224. context,
  225. MaterialPageRoute(
  226. builder: (BuildContext context) => PlotDetailScreen(
  227. cropType: type,
  228. cropId: item.tbCropId,
  229. initialIndex: 0,
  230. ))).then((value) {
  231. if (item.isRead == 0) {
  232. _updateReadNotification(
  233. context: context,
  234. unread: unread,
  235. read: read,
  236. item: item,
  237. currentItems: currentItems,
  238. currentPage: currentPage,
  239. currentReachedMax: currentReachedMax);
  240. }
  241. });
  242. } else if (item.contents == "PIC_UPDATE") {
  243. Navigator.push(
  244. context,
  245. MaterialPageRoute(
  246. builder: (BuildContext context) => PlotDetailScreen(
  247. cropType: type,
  248. cropId: item.tbCropId,
  249. initialIndex: 1,
  250. ))).then((value) {
  251. if (item.isRead == 0) {
  252. _updateReadNotification(
  253. context: context,
  254. unread: unread,
  255. read: read,
  256. item: item,
  257. currentItems: currentItems,
  258. currentPage: currentPage,
  259. currentReachedMax: currentReachedMax);
  260. }
  261. });
  262. } else {}
  263. }),
  264. Container(
  265. padding: EdgeInsets.only(left: 16, right: 16),
  266. child: DashLineWidget())
  267. ],
  268. );
  269. }
  270. _updateReadNotification(
  271. {BuildContext context,
  272. int unread,
  273. int read,
  274. NotificationDTO item,
  275. List<NotificationDTO> currentItems,
  276. int currentPage,
  277. bool currentReachedMax}) {
  278. List<NotificationDTO> updatedItems = new List<NotificationDTO>();
  279. currentItems.forEach((e) {
  280. if (e.id == item.id) {
  281. e.isRead = 1;
  282. } else {}
  283. updatedItems.add(NotificationDTO.clone(e));
  284. });
  285. notiBloc.add(OnUpdate<NotificationDTO>(
  286. unread: unread - 1,
  287. read: read + 1,
  288. currentItemId: item.id,
  289. currentItems: updatedItems,
  290. currentPage: currentPage,
  291. hasReachedMax: currentReachedMax));
  292. }
  293. }