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.

276 lines
8.7KB

  1. import 'dart:io';
  2. import 'package:dio/dio.dart';
  3. import 'package:farm_tpf/custom_model/NotificationDTO.dart';
  4. import 'package:farm_tpf/data/repository/repository.dart';
  5. import 'package:farm_tpf/data/repository/user_repository.dart';
  6. import 'package:farm_tpf/main.dart';
  7. import 'package:farm_tpf/models/index.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
  10. import 'package:farm_tpf/presentation/screens/plot/widget_search.dart';
  11. import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
  12. import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_information.dart';
  13. import 'package:farm_tpf/utils/const_color.dart';
  14. import 'package:farm_tpf/utils/const_common.dart';
  15. import 'package:farm_tpf/utils/pref.dart';
  16. import 'package:firebase_messaging/firebase_messaging.dart';
  17. import 'package:flutter/material.dart';
  18. import 'package:flutter_bloc/flutter_bloc.dart';
  19. import 'package:farm_tpf/utils/const_string.dart';
  20. import 'package:font_awesome_flutter/font_awesome_flutter.dart';
  21. import 'package:farm_tpf/utils/formatter.dart';
  22. import 'package:get/get.dart';
  23. import 'bloc/plot_bloc.dart';
  24. class PlotListScreen extends StatefulWidget {
  25. @override
  26. _PlotListScreenState createState() => _PlotListScreenState();
  27. }
  28. class _PlotListScreenState extends State<PlotListScreen> {
  29. UserRepository _userRepository = UserRepository();
  30. final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
  31. var pref = LocalPref();
  32. var token;
  33. var client;
  34. String pushkey = "";
  35. String currentFullName = "";
  36. Future<Null> getSharedPrefs() async {
  37. token = await pref.getString(DATA_CONST.TOKEN_KEY);
  38. pushkey = await pref.getString(DATA_CONST.PUSH_KEY);
  39. currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  40. var options = BaseOptions(baseUrl: ConstCommon.baseUrl);
  41. options.headers["Authorization"] = "Bearer $token";
  42. client = Dio(options);
  43. if (Platform.isIOS) {
  44. _firebaseMessaging
  45. .requestNotificationPermissions(IosNotificationSettings());
  46. }
  47. _firebaseMessaging.configure(
  48. onMessage: (Map<String, dynamic> message) async {
  49. print("onMessage: $message");
  50. },
  51. onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
  52. onLaunch: (Map<String, dynamic> message) async {
  53. print("onLaunch: $message");
  54. Future.delayed(Duration(milliseconds: 500), () {
  55. _notificationNavigateOnFCM(message);
  56. });
  57. },
  58. onResume: (Map<String, dynamic> message) async {
  59. print("onResume: $message");
  60. _notificationNavigateOnFCM(message);
  61. },
  62. );
  63. _firebaseMessaging.requestNotificationPermissions(
  64. const IosNotificationSettings(
  65. sound: true, badge: true, alert: true, provisional: true));
  66. _firebaseMessaging.onIosSettingsRegistered
  67. .listen((IosNotificationSettings settings) {
  68. print("Settings registered: $settings");
  69. });
  70. if (pushkey?.isEmpty ?? true) {
  71. _firebaseMessaging.getToken().then((String token) {
  72. assert(token != null);
  73. print("Push Messaging token: $token");
  74. _userRepository.updateFcmToken(token).then((value) {
  75. print("send push key successful");
  76. pref.saveString(DATA_CONST.PUSH_KEY, token);
  77. });
  78. // client.put("");
  79. });
  80. } else {
  81. print("Don't need get push key");
  82. }
  83. if (currentFullName?.isEmpty ?? true) {
  84. try {
  85. var currentUser = await _userRepository.getUser();
  86. pref.saveString(DATA_CONST.CURRENT_FULL_NAME, currentUser.fullName);
  87. print("fullname: ${currentUser.fullName}");
  88. } catch (e) {
  89. print("error: ${e.toString()}");
  90. }
  91. }
  92. }
  93. _notificationNavigateOnFCM(Map<String, dynamic> message) {
  94. //parse data difference between Ios and Android
  95. var noti;
  96. if (Platform.isAndroid) {
  97. var data = message['data'];
  98. noti = NotificationDTO()
  99. ..contents = data['contents']
  100. ..tbCropId = data['tbCropId'];
  101. } else {
  102. noti = NotificationDTO.fromJson(message);
  103. }
  104. if (noti.contents == "ENV_UPDATE") {
  105. Get.to(PlotDetailScreen(cropId: noti.tbCropId));
  106. } else if (noti.contents == "PIC_UPDATE") {
  107. Get.to(PlotInformationScreen(
  108. cropId: noti.tbCropId,
  109. ));
  110. } else {
  111. //Go home
  112. }
  113. }
  114. @override
  115. void initState() {
  116. super.initState();
  117. getSharedPrefs();
  118. }
  119. @override
  120. Widget build(BuildContext context) {
  121. return BlocProvider(
  122. create: (context) =>
  123. PlotBloc(repository: Repository())..add(DataFetched()),
  124. child: HoldInfinityWidget(),
  125. );
  126. }
  127. }
  128. class HoldInfinityWidget extends StatelessWidget {
  129. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  130. @override
  131. Widget build(BuildContext context) {
  132. return Scaffold(
  133. key: _scaffoldKey,
  134. appBar: AppBar(
  135. centerTitle: true,
  136. title: Text("Danh sách lô"),
  137. actions: <Widget>[
  138. IconButton(
  139. icon: Icon(FontAwesomeIcons.qrcode),
  140. onPressed: () {
  141. scan(context);
  142. })
  143. ],
  144. ),
  145. body: InfinityView());
  146. }
  147. }
  148. class InfinityView extends StatefulWidget {
  149. @override
  150. _InfinityViewState createState() => _InfinityViewState();
  151. }
  152. class _InfinityViewState extends State<InfinityView> {
  153. final _scrollController = ScrollController();
  154. final _scrollThreshold = 250.0;
  155. PlotBloc _plotBloc;
  156. @override
  157. void initState() {
  158. _scrollController.addListener(() {
  159. final maxScroll = _scrollController.position.maxScrollExtent;
  160. final currentScroll = _scrollController.position.pixels;
  161. if (maxScroll - currentScroll < _scrollThreshold) {
  162. _plotBloc.add(DataFetched());
  163. }
  164. });
  165. _plotBloc = BlocProvider.of<PlotBloc>(context);
  166. super.initState();
  167. }
  168. @override
  169. Widget build(BuildContext context) {
  170. return Column(
  171. children: <Widget>[
  172. WidgetSearch(),
  173. Expanded(child: BlocBuilder<PlotBloc, PlotState>(
  174. builder: (context, state) {
  175. if (state is PlotFailure) {
  176. return Center(child: Text(state.errorString));
  177. }
  178. if (state is PlotSuccess) {
  179. if (state.items.isEmpty) {
  180. return Center(child: Text(label_list_empty));
  181. }
  182. return RefreshIndicator(
  183. child: ListView.builder(
  184. physics: AlwaysScrollableScrollPhysics(),
  185. itemBuilder: (BuildContext context, int index) {
  186. return index >= state.items.length
  187. ? BottomLoader()
  188. : ItemInfinityWidget(item: state.items[index]);
  189. },
  190. itemCount: state.hasReachedMax
  191. ? state.items.length
  192. : state.items.length + 1,
  193. controller: _scrollController,
  194. ),
  195. onRefresh: () async {
  196. _plotBloc.add(OnRefresh());
  197. });
  198. }
  199. return Center(
  200. child: LoadingListPage(),
  201. );
  202. },
  203. ))
  204. ],
  205. );
  206. }
  207. @override
  208. void dispose() {
  209. _scrollController.dispose();
  210. super.dispose();
  211. }
  212. }
  213. class ItemInfinityWidget extends StatelessWidget {
  214. final Crop item;
  215. const ItemInfinityWidget({Key key, @required this.item}) : super(key: key);
  216. @override
  217. Widget build(BuildContext context) {
  218. var backgroundColor;
  219. var textColor;
  220. switch (item.status) {
  221. case "STATUS_ARE_ACTIVE":
  222. backgroundColor = Colors.white;
  223. textColor = COLOR_CONST.DEFAULT;
  224. break;
  225. case "STATUS_FINISHED":
  226. backgroundColor = COLOR_CONST.DEFAULT;
  227. textColor = Colors.white;
  228. break;
  229. default:
  230. backgroundColor = Colors.white;
  231. textColor = Colors.black;
  232. }
  233. return GestureDetector(
  234. child: Card(
  235. color: backgroundColor,
  236. child: ListTile(
  237. title: Text("${item.code ?? ''} - ${item.suppliesName ?? ''}",
  238. style: TextStyle(color: textColor)),
  239. subtitle: Text(item.startDate.format_DDMMYY_HHmm().toString(),
  240. style: TextStyle(color: textColor)),
  241. trailing: Text(
  242. item.areaM2.formatNumtoStringDecimal().toString() + " m\u00B2",
  243. style: TextStyle(color: textColor)),
  244. ),
  245. ),
  246. onTap: () {
  247. Navigator.push(
  248. context,
  249. MaterialPageRoute(
  250. builder: (BuildContext context) => PlotDetailScreen(
  251. cropId: item.id,
  252. initialIndex: 0,
  253. )));
  254. });
  255. }
  256. }