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.

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