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.

305 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 BlocBuilder<NotiBloc, NotiState>(
  57. cubit: notiBloc,
  58. builder: (context, state) {
  59. if (state is NotiFailure) {
  60. return Center(child: Text(state.errorString));
  61. } else if (state is NotiSuccess) {
  62. updateCountNotiBloc.getNotifications((data) {}, (err) {});
  63. if (state.items.isEmpty) {
  64. return SafeArea(
  65. child: Column(
  66. crossAxisAlignment: CrossAxisAlignment.start,
  67. children: [
  68. SizedBox(
  69. height: 8,
  70. ),
  71. Padding(
  72. padding: const EdgeInsets.all(8.0),
  73. child: Text('Thông báo',
  74. style: TextStyle(
  75. fontWeight: FontWeight.w500, fontSize: 22)),
  76. ),
  77. Expanded(
  78. child: Center(child: Text("Không có thông báo")),
  79. ),
  80. ],
  81. ),
  82. );
  83. }
  84. currentItems = List<NotificationDTO>.from(state.items);
  85. currentPage = state.page;
  86. currentHasReachedMax = state.hasReachedMax;
  87. return SafeArea(
  88. child: Column(
  89. children: <Widget>[
  90. Container(
  91. padding: EdgeInsets.all(8),
  92. color: Colors.white,
  93. child: Row(
  94. children: [
  95. SizedBox(
  96. height: 8,
  97. ),
  98. Expanded(
  99. child: Text(
  100. 'Thông báo',
  101. style: TextStyle(
  102. fontWeight: FontWeight.w500, fontSize: 22),
  103. )),
  104. FlatButton(
  105. onPressed: () {
  106. notiBloc
  107. .add(MarkAllNotificationUpdate(status: "1"));
  108. },
  109. child: Text('Đánh dấu đã đọc tất cả',
  110. style: TextStyle(
  111. fontWeight: FontWeight.normal,
  112. fontSize: 14,
  113. color: Colors.blue)))
  114. ],
  115. )),
  116. Expanded(
  117. child: RefreshIndicator(
  118. child: ListView.builder(
  119. physics: AlwaysScrollableScrollPhysics(),
  120. itemBuilder: (BuildContext context, int index) {
  121. return index >= state.items.length
  122. ? BottomLoader()
  123. : ItemInfinityWidget(
  124. notiBloc: notiBloc,
  125. unread: state.unread,
  126. read: state.read,
  127. currentItems: currentItems,
  128. item: state.items[index],
  129. currentPage: state.page,
  130. currentReachedMax: state.hasReachedMax,
  131. );
  132. },
  133. itemCount: state.hasReachedMax
  134. ? state.items.length
  135. : state.items.length + 1,
  136. controller: _scrollController,
  137. ),
  138. onRefresh: () async {
  139. notiBloc.add(OnRefresh());
  140. }))
  141. ],
  142. ),
  143. );
  144. } else if (state is NotiLoadding) {
  145. return Center(
  146. child: LoadingListPage(),
  147. );
  148. }
  149. return Container();
  150. },
  151. );
  152. }
  153. @override
  154. void dispose() {
  155. _scrollController.dispose();
  156. super.dispose();
  157. }
  158. }
  159. class ItemInfinityWidget extends StatelessWidget {
  160. final int unread;
  161. final int read;
  162. final NotificationDTO item;
  163. final List<NotificationDTO> currentItems;
  164. final int currentPage;
  165. final bool currentReachedMax;
  166. final NotiBloc notiBloc;
  167. const ItemInfinityWidget(
  168. {Key key,
  169. @required this.unread,
  170. @required this.read,
  171. @required this.currentItems,
  172. @required this.item,
  173. @required this.currentPage,
  174. @required this.currentReachedMax,
  175. @required this.notiBloc})
  176. : super(key: key);
  177. @override
  178. Widget build(BuildContext context) {
  179. var type;
  180. try {
  181. type = int.parse(item.type);
  182. } catch (_) {
  183. type = -1;
  184. }
  185. return Column(
  186. children: [
  187. GestureDetector(
  188. child: Container(
  189. margin: EdgeInsets.all(4.0),
  190. child: Column(
  191. children: [
  192. ListTile(
  193. title: Text(item.subject),
  194. subtitle: Column(
  195. crossAxisAlignment: CrossAxisAlignment.start,
  196. children: <Widget>[
  197. Text(item.message),
  198. Row(children: [
  199. Icon(Icons.access_time,
  200. color: item.isRead == 1
  201. ? Colors.grey
  202. : Colors.blue,
  203. size: 18),
  204. SizedBox(
  205. width: 4,
  206. ),
  207. Text(item.sendDate.format_DDMMYY_HHmm(),
  208. style: TextStyle(
  209. color: item.isRead == 1
  210. ? Colors.grey
  211. : Colors.blue))
  212. ]),
  213. ],
  214. ),
  215. leading: SvgPicture.asset(AppIcons.icNotificationItem)),
  216. ],
  217. )),
  218. onTap: () {
  219. if (item.contents == "ENV_UPDATE") {
  220. Navigator.push(
  221. context,
  222. MaterialPageRoute(
  223. builder: (BuildContext context) => PlotDetailScreen(
  224. cropType: type,
  225. cropId: item.tbCropId,
  226. initialIndex: 0,
  227. ))).then((value) {
  228. if (item.isRead == 0) {
  229. _updateReadNotification(
  230. context: context,
  231. unread: unread,
  232. read: read,
  233. item: item,
  234. currentItems: currentItems,
  235. currentPage: currentPage,
  236. currentReachedMax: currentReachedMax);
  237. }
  238. });
  239. } else if (item.contents == "PIC_UPDATE") {
  240. Navigator.push(
  241. context,
  242. MaterialPageRoute(
  243. builder: (BuildContext context) => PlotDetailScreen(
  244. cropType: type,
  245. cropId: item.tbCropId,
  246. initialIndex: 1,
  247. ))).then((value) {
  248. if (item.isRead == 0) {
  249. _updateReadNotification(
  250. context: context,
  251. unread: unread,
  252. read: read,
  253. item: item,
  254. currentItems: currentItems,
  255. currentPage: currentPage,
  256. currentReachedMax: currentReachedMax);
  257. }
  258. });
  259. } else {}
  260. }),
  261. Container(
  262. padding: EdgeInsets.only(left: 16, right: 16),
  263. child: DashLineWidget())
  264. ],
  265. );
  266. }
  267. _updateReadNotification(
  268. {BuildContext context,
  269. int unread,
  270. int read,
  271. NotificationDTO item,
  272. List<NotificationDTO> currentItems,
  273. int currentPage,
  274. bool currentReachedMax}) {
  275. List<NotificationDTO> updatedItems = new List<NotificationDTO>();
  276. currentItems.forEach((e) {
  277. if (e.id == item.id) {
  278. e.isRead = 1;
  279. } else {}
  280. updatedItems.add(NotificationDTO.clone(e));
  281. });
  282. notiBloc.add(OnUpdate<NotificationDTO>(
  283. unread: unread - 1,
  284. read: read + 1,
  285. currentItemId: item.id,
  286. currentItems: updatedItems,
  287. currentPage: currentPage,
  288. hasReachedMax: currentReachedMax));
  289. }
  290. }