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.

352 lines
14KB

  1. import 'dart:io';
  2. import 'package:badges/badges.dart';
  3. import 'package:dio/dio.dart';
  4. import 'package:farm_tpf/custom_model/NotificationObjectDTO.dart';
  5. import 'package:farm_tpf/data/repository/repository.dart';
  6. import 'package:farm_tpf/data/repository/user_repository.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  8. import 'package:farm_tpf/presentation/screens/account/sc_account.dart';
  9. import 'package:farm_tpf/presentation/screens/control_device/sc_control_device.dart';
  10. import 'package:farm_tpf/presentation/screens/notification/sc_notification.dart';
  11. import 'package:farm_tpf/presentation/screens/notification/update_count_noti_bloc.dart';
  12. import 'package:farm_tpf/presentation/screens/plot/sc_plot.dart';
  13. import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
  14. import 'package:farm_tpf/presentation/screens/qr_scan/qr_scan_page.dart';
  15. import 'package:farm_tpf/utils/NotificationsBloc.dart';
  16. import 'package:farm_tpf/utils/const_color.dart';
  17. import 'package:farm_tpf/utils/const_common.dart';
  18. import 'package:farm_tpf/utils/const_icons.dart';
  19. import 'package:farm_tpf/utils/pref.dart';
  20. import 'package:firebase_messaging/firebase_messaging.dart';
  21. import 'package:flutter/material.dart';
  22. import 'package:flutter_svg/flutter_svg.dart';
  23. import 'package:get/get.dart';
  24. import '../../../main.dart';
  25. class TabbarScreen extends StatefulWidget {
  26. static Route route() {
  27. return MaterialPageRoute<void>(builder: (_) => TabbarScreen());
  28. }
  29. @override
  30. _TabbarScreenState createState() => _TabbarScreenState();
  31. }
  32. class _TabbarScreenState extends State<TabbarScreen> {
  33. Stream<LocalNotification> _notificationsStream;
  34. UserRepository _userRepository = UserRepository();
  35. final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
  36. var pref = LocalPref();
  37. String pushkey = "";
  38. String currentFullName = "";
  39. var token;
  40. var client;
  41. final changeTabbar = Get.put(TabbarSelected());
  42. List<TabbarItem> itemsTabbar = [
  43. TabbarItem(icon: AppIcons.icPlot, title: 'Lô trồng', index: TabBarIndex.plot),
  44. TabbarItem(icon: AppIcons.icDevice, title: 'Thiết bị', index: TabBarIndex.device),
  45. TabbarItem(icon: AppIcons.icQr, title: 'Quét QR', index: TabBarIndex.qr),
  46. TabbarItem(icon: AppIcons.icNotification, title: 'Thông báo', index: TabBarIndex.notification),
  47. TabbarItem(icon: AppIcons.icPerson, title: 'Cá nhân', index: TabBarIndex.account)
  48. ];
  49. Future<Null> getSharedPrefs() async {
  50. token = await pref.getString(DATA_CONST.TOKEN_KEY);
  51. pushkey = await pref.getString(DATA_CONST.PUSH_KEY);
  52. currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  53. var options = BaseOptions(baseUrl: ConstCommon.baseUrl);
  54. options.headers["Authorization"] = "Bearer $token";
  55. client = Dio(options);
  56. if (Platform.isIOS) {
  57. _firebaseMessaging.requestNotificationPermissions(IosNotificationSettings());
  58. }
  59. _firebaseMessaging.configure(
  60. onMessage: (Map<String, dynamic> message) async {
  61. print("onMessage--tabbar-: $message");
  62. try {
  63. final String type = message['tbCropType'];
  64. final String contents = message['contents'];
  65. final String tbCropId = message['tbCropId'];
  66. updateCountNotiBloc.getNotifications((data) {}, (err) {});
  67. final notification = LocalNotification(type, contents, tbCropId);
  68. NotificationsBloc.instance.newNotification(notification);
  69. if (contents == "ENV_UPDATE") {
  70. if (Get.isSnackbarOpen) Get.back();
  71. Get.snackbar(null, 'Thông số môi trường được cập nhật');
  72. } else if (contents == "PIC_UPDATE") {
  73. if (Get.isSnackbarOpen) Get.back();
  74. Get.snackbar(null, 'Người phụ trách được cập nhật');
  75. } else {
  76. //Go home
  77. }
  78. } catch (e) {
  79. print('error');
  80. print(e);
  81. }
  82. },
  83. onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
  84. onLaunch: (Map<String, dynamic> message) async {
  85. print("onLaunch: $message");
  86. Future.delayed(Duration(milliseconds: 500), () {
  87. updateCountNotiBloc.getNotifications((data) {}, (err) {});
  88. _notificationNavigateOnFCM(message);
  89. });
  90. },
  91. onResume: (Map<String, dynamic> message) async {
  92. print("onResume: $message");
  93. updateCountNotiBloc.getNotifications((data) {}, (err) {});
  94. _notificationNavigateOnFCM(message);
  95. },
  96. );
  97. _firebaseMessaging.requestNotificationPermissions(const IosNotificationSettings(sound: true, badge: true, alert: true, provisional: true));
  98. _firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
  99. print("Settings registered: $settings");
  100. });
  101. if (pushkey?.isEmpty ?? true) {
  102. _firebaseMessaging.getToken().then((String token) {
  103. assert(token != null);
  104. print("Push Messaging token: $token");
  105. _userRepository.updateFcmToken(token).then((value) {
  106. print("send push key successful");
  107. pref.saveString(DATA_CONST.PUSH_KEY, token);
  108. });
  109. // client.put("");
  110. });
  111. } else {
  112. print("Don't need get push key");
  113. }
  114. if (currentFullName?.isEmpty ?? true) {
  115. try {
  116. var currentUser = await _userRepository.getUser();
  117. pref.saveString(DATA_CONST.CURRENT_FULL_NAME, currentUser.fullName);
  118. print("fullname: ${currentUser.fullName}");
  119. } catch (e) {
  120. print("error: ${e.toString()}");
  121. }
  122. }
  123. }
  124. @override
  125. void initState() {
  126. super.initState();
  127. getSharedPrefs();
  128. changeTabbar.initValue();
  129. updateCountNotiBloc.getNotifications((data) {}, (err) {});
  130. _notificationsStream = NotificationsBloc.instance.notificationsStream;
  131. _notificationsStream.listen((notification) {
  132. updateCountNotiBloc.getNotifications((data) {}, (err) {});
  133. print('Notification: $notification');
  134. });
  135. }
  136. _notificationNavigateOnFCM(Map<String, dynamic> message) {
  137. try {
  138. final String type = message['tbCropType'];
  139. final String contents = message['contents'];
  140. final String tbCropId = message['tbCropId'];
  141. if (contents == "ENV_UPDATE") {
  142. Get.to(PlotDetailScreen(
  143. cropType: int.parse(type),
  144. cropId: int.parse(tbCropId),
  145. initialIndex: 0,
  146. ));
  147. } else if (contents == "PIC_UPDATE") {
  148. Get.to(PlotDetailScreen(
  149. cropType: int.parse(type),
  150. cropId: int.parse(tbCropId),
  151. initialIndex: 1,
  152. ));
  153. } else {
  154. //Go home
  155. }
  156. } catch (e) {
  157. //Go home
  158. }
  159. Get.to(PlotDetailScreen(
  160. cropType: 0,
  161. cropId: 1,
  162. initialIndex: 0,
  163. ));
  164. }
  165. Widget textCountNoti() {
  166. return StreamBuilder(
  167. stream: updateCountNotiBloc.actions,
  168. builder: (context, AsyncSnapshot<dynamic> snapshot) {
  169. if (snapshot.hasData) {
  170. var noti = snapshot.data as NotificationObjectDTO;
  171. var unreadNoti = noti.numberUnreadTotal > 99 ? '99+' : '${noti.numberUnreadTotal}';
  172. return Text(
  173. '$unreadNoti',
  174. softWrap: true,
  175. style: TextStyle(color: Colors.white, fontSize: 10),
  176. );
  177. } else {
  178. return Text(
  179. 'O',
  180. softWrap: true,
  181. style: TextStyle(color: Colors.white, fontSize: 10),
  182. );
  183. }
  184. },
  185. );
  186. }
  187. @override
  188. Widget build(BuildContext context) {
  189. return Container(
  190. color: Colors.white,
  191. child: SafeArea(
  192. top: false,
  193. bottom: true,
  194. child: Scaffold(
  195. body: GetBuilder<TabbarSelected>(builder: (tabbarSelected) {
  196. switch (tabbarSelected.index) {
  197. case TabBarIndex.plot:
  198. return PlotListScreen();
  199. break;
  200. case TabBarIndex.device:
  201. return ControlDeviceScreen();
  202. break;
  203. case TabBarIndex.qr:
  204. break;
  205. case TabBarIndex.notification:
  206. return NotificationScreen();
  207. break;
  208. case TabBarIndex.account:
  209. return AccountScreen();
  210. break;
  211. default:
  212. return PlotListScreen();
  213. }
  214. }),
  215. bottomNavigationBar: Container(
  216. padding: EdgeInsets.all(4),
  217. height: 70,
  218. decoration: BoxDecoration(color: Colors.white, border: Border(top: BorderSide(color: Colors.grey, width: 0.35))),
  219. child: GetBuilder<TabbarSelected>(builder: (tabbarSelected) {
  220. return Center(
  221. child: ListView.builder(
  222. scrollDirection: Axis.horizontal,
  223. shrinkWrap: true,
  224. physics: NeverScrollableScrollPhysics(),
  225. itemCount: itemsTabbar.length,
  226. itemBuilder: (context, index) {
  227. return GestureDetector(
  228. child: Container(
  229. width: (Get.width - 20) / 5,
  230. margin: EdgeInsets.all(1),
  231. padding: EdgeInsets.all(10),
  232. child: Column(
  233. mainAxisAlignment: MainAxisAlignment.center,
  234. children: [
  235. index == 3
  236. ? Badge(
  237. badgeContent: textCountNoti(),
  238. shape: BadgeShape.circle,
  239. badgeColor: Colors.red,
  240. position: BadgePosition(top: -15, start: 10),
  241. child: SvgPicture.asset(
  242. itemsTabbar[index].icon,
  243. width: 24,
  244. height: 24,
  245. color: (tabbarSelected.index == itemsTabbar[index].index) ? AppColors.YELLOW : AppColors.GRAY1,
  246. ),
  247. )
  248. : SvgPicture.asset(
  249. itemsTabbar[index].icon,
  250. width: 24,
  251. height: 24,
  252. color: (tabbarSelected.index == itemsTabbar[index].index) ? AppColors.YELLOW : AppColors.GRAY1,
  253. ),
  254. Flexible(
  255. child: Text(
  256. itemsTabbar[index].title,
  257. style: TextStyle(
  258. color: (tabbarSelected.index == itemsTabbar[index].index) ? AppColors.DEFAULT : Colors.grey,
  259. fontSize: 9),
  260. ),
  261. )
  262. ],
  263. )),
  264. onTap: () {
  265. //Open scan qr code when tap icon in tabbar
  266. if (index == 2) {
  267. changeTabbar.changeIndex(changeTabbar.index);
  268. // scan(context);
  269. Get.to(QrCodeScannerScreen()).then((value) {
  270. if (value != null) {
  271. _showAlertCheckCropCode(value);
  272. }
  273. });
  274. } else {
  275. changeTabbar.changeIndex(itemsTabbar[index].index);
  276. }
  277. },
  278. );
  279. }),
  280. );
  281. })),
  282. )));
  283. }
  284. _showAlertCheckCropCode(String cropCode) async {
  285. var repository = Repository();
  286. Get.defaultDialog(title: "Kiểm tra thông tin lô ....", middleText: "", content: CircularProgressIndicator());
  287. try {
  288. await repository.getPlotDetailByCode(cropCode, page: 1, size: 1).then((value) {
  289. print("ok");
  290. if (Get.isDialogOpen) Get.back();
  291. Get.to(PlotDetailScreen(cropId: value.tbCropDTO.id, cropType: value.tbCropDTO.tbCropTypeId, initialIndex: 0));
  292. }).catchError((onError) {
  293. Utils.showDialog(
  294. title: "Không tìm thấy lô",
  295. message: "Thử lại với mã tem khác?",
  296. textConfirm: "Thử lại",
  297. textCancel: "Huỷ",
  298. onConfirm: () {
  299. Get.back();
  300. // scan(context);
  301. });
  302. });
  303. } catch (e) {
  304. Utils.showDialog(
  305. title: "Không tìm thấy lô",
  306. message: "Thử lại với mã tem khác?",
  307. textConfirm: "Thử lại",
  308. textCancel: "Huỷ",
  309. onConfirm: () {
  310. Get.back();
  311. // scan(context);
  312. });
  313. }
  314. }
  315. }
  316. class TabbarSelected extends GetxController {
  317. TabBarIndex index;
  318. void initValue() {
  319. index = TabBarIndex.plot;
  320. update();
  321. }
  322. void changeIndex(TabBarIndex changedIndex) {
  323. index = changedIndex;
  324. update();
  325. }
  326. }
  327. enum TabBarIndex { plot, device, qr, notification, account }
  328. class TabbarItem {
  329. TabBarIndex index;
  330. String icon;
  331. String title;
  332. TabbarItem({this.icon, this.title, this.index});
  333. }