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.

354 lines
11KB

  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/app_bar_widget.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart';
  10. import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
  11. import 'package:farm_tpf/presentation/screens/plot/widget_search.dart';
  12. import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
  13. import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_information.dart';
  14. import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_parameter.dart';
  15. import 'package:farm_tpf/utils/const_assets.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/pref.dart';
  19. import 'package:firebase_messaging/firebase_messaging.dart';
  20. import 'package:flutter/material.dart';
  21. import 'package:flutter_bloc/flutter_bloc.dart';
  22. import 'package:farm_tpf/utils/const_string.dart';
  23. import 'package:farm_tpf/utils/formatter.dart';
  24. import 'package:get/get.dart';
  25. import 'bloc/plot_bloc.dart';
  26. class PlotListScreen extends StatefulWidget {
  27. @override
  28. _PlotListScreenState createState() => _PlotListScreenState();
  29. }
  30. class _PlotListScreenState extends State<PlotListScreen> {
  31. UserRepository _userRepository = UserRepository();
  32. final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
  33. var pref = LocalPref();
  34. var token;
  35. var client;
  36. String pushkey = "";
  37. String currentFullName = "";
  38. Future<Null> getSharedPrefs() async {
  39. token = await pref.getString(DATA_CONST.TOKEN_KEY);
  40. pushkey = await pref.getString(DATA_CONST.PUSH_KEY);
  41. currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  42. var options = BaseOptions(baseUrl: ConstCommon.baseUrl);
  43. options.headers["Authorization"] = "Bearer $token";
  44. client = Dio(options);
  45. if (Platform.isIOS) {
  46. _firebaseMessaging
  47. .requestNotificationPermissions(IosNotificationSettings());
  48. }
  49. _firebaseMessaging.configure(
  50. onMessage: (Map<String, dynamic> message) async {
  51. print("onMessage: $message");
  52. },
  53. onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
  54. onLaunch: (Map<String, dynamic> message) async {
  55. print("onLaunch: $message");
  56. Future.delayed(Duration(milliseconds: 500), () {
  57. _notificationNavigateOnFCM(message);
  58. });
  59. },
  60. onResume: (Map<String, dynamic> message) async {
  61. print("onResume: $message");
  62. _notificationNavigateOnFCM(message);
  63. },
  64. );
  65. _firebaseMessaging.requestNotificationPermissions(
  66. const IosNotificationSettings(
  67. sound: true, badge: true, alert: true, provisional: true));
  68. _firebaseMessaging.onIosSettingsRegistered
  69. .listen((IosNotificationSettings settings) {
  70. print("Settings registered: $settings");
  71. });
  72. if (pushkey?.isEmpty ?? true) {
  73. _firebaseMessaging.getToken().then((String token) {
  74. assert(token != null);
  75. print("Push Messaging token: $token");
  76. _userRepository.updateFcmToken(token).then((value) {
  77. print("send push key successful");
  78. pref.saveString(DATA_CONST.PUSH_KEY, token);
  79. });
  80. // client.put("");
  81. });
  82. } else {
  83. print("Don't need get push key");
  84. }
  85. if (currentFullName?.isEmpty ?? true) {
  86. try {
  87. var currentUser = await _userRepository.getUser();
  88. pref.saveString(DATA_CONST.CURRENT_FULL_NAME, currentUser.fullName);
  89. print("fullname: ${currentUser.fullName}");
  90. } catch (e) {
  91. print("error: ${e.toString()}");
  92. }
  93. }
  94. }
  95. _notificationNavigateOnFCM(Map<String, dynamic> message) {
  96. //parse data difference between Ios and Android
  97. var noti;
  98. if (Platform.isAndroid) {
  99. var data = message['data'];
  100. noti = NotificationDTO()
  101. ..contents = data['contents']
  102. ..tbCropId = data['tbCropId']
  103. ..type = data['type'];
  104. } else {
  105. noti = NotificationDTO.fromJson(message);
  106. }
  107. if (noti.contents == "ENV_UPDATE") {
  108. Get.to(PlotParameterScreen(
  109. cropId: noti.tbCropId,
  110. isShowAppbar: true,
  111. ));
  112. } else if (noti.contents == "PIC_UPDATE") {
  113. Get.to(PlotInformationScreen(
  114. cropId: noti.tbCropId,
  115. ));
  116. } else {
  117. //Go home
  118. }
  119. }
  120. @override
  121. void initState() {
  122. super.initState();
  123. getSharedPrefs();
  124. }
  125. @override
  126. Widget build(BuildContext context) {
  127. return BlocProvider(
  128. create: (context) =>
  129. PlotBloc(repository: Repository())..add(DataFetched()),
  130. child: HoldInfinityWidget(),
  131. );
  132. }
  133. }
  134. class HoldInfinityWidget extends StatelessWidget {
  135. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  136. @override
  137. Widget build(BuildContext context) {
  138. return Scaffold(
  139. backgroundColor: Colors.white,
  140. key: _scaffoldKey,
  141. appBar: AppBarWidget(
  142. isBack: false,
  143. ),
  144. body: InfinityView());
  145. }
  146. }
  147. class InfinityView extends StatefulWidget {
  148. @override
  149. _InfinityViewState createState() => _InfinityViewState();
  150. }
  151. class _InfinityViewState extends State<InfinityView> {
  152. final _scrollController = ScrollController();
  153. final _scrollThreshold = 250.0;
  154. PlotBloc _plotBloc;
  155. @override
  156. void initState() {
  157. _scrollController.addListener(() {
  158. final maxScroll = _scrollController.position.maxScrollExtent;
  159. final currentScroll = _scrollController.position.pixels;
  160. if (maxScroll - currentScroll < _scrollThreshold) {
  161. _plotBloc.add(DataFetched());
  162. }
  163. });
  164. _plotBloc = BlocProvider.of<PlotBloc>(context);
  165. super.initState();
  166. }
  167. @override
  168. Widget build(BuildContext context) {
  169. return Column(
  170. crossAxisAlignment: CrossAxisAlignment.start,
  171. children: <Widget>[
  172. Container(
  173. padding: EdgeInsets.all(8),
  174. color: Colors.white,
  175. child: Text(
  176. 'Danh sách lô trồng',
  177. style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
  178. )),
  179. WidgetSearch(),
  180. Expanded(child: BlocBuilder<PlotBloc, PlotState>(
  181. builder: (context, state) {
  182. if (state is PlotFailure) {
  183. return Center(child: Text(state.errorString));
  184. }
  185. if (state is PlotSuccess) {
  186. if (state.items.isEmpty) {
  187. return Center(child: Text(label_list_empty));
  188. }
  189. return RefreshIndicator(
  190. child: ListView.builder(
  191. physics: AlwaysScrollableScrollPhysics(),
  192. itemBuilder: (BuildContext context, int index) {
  193. return index >= state.items.length
  194. ? BottomLoader()
  195. : ItemInfinityWidget(item: state.items[index]);
  196. },
  197. itemCount: state.hasReachedMax
  198. ? state.items.length
  199. : state.items.length + 1,
  200. controller: _scrollController,
  201. ),
  202. onRefresh: () async {
  203. _plotBloc.add(OnRefresh());
  204. });
  205. }
  206. return Center(
  207. child: LoadingListPage(),
  208. );
  209. },
  210. ))
  211. ],
  212. );
  213. }
  214. @override
  215. void dispose() {
  216. _scrollController.dispose();
  217. super.dispose();
  218. }
  219. }
  220. class ItemInfinityWidget extends StatelessWidget {
  221. final Crop item;
  222. const ItemInfinityWidget({Key key, @required this.item}) : super(key: key);
  223. @override
  224. Widget build(BuildContext context) {
  225. var backgroundColor;
  226. var textColor;
  227. switch (item.status) {
  228. case "STATUS_ARE_ACTIVE":
  229. backgroundColor = Colors.white;
  230. textColor = AppColors.DEFAULT;
  231. break;
  232. case "STATUS_FINISHED":
  233. backgroundColor = AppColors.DEFAULT;
  234. textColor = Colors.white;
  235. break;
  236. default:
  237. backgroundColor = Colors.white;
  238. textColor = Colors.black;
  239. }
  240. return GestureDetector(
  241. child: Container(
  242. margin: EdgeInsets.all(8),
  243. decoration: BoxDecoration(
  244. color: backgroundColor,
  245. border: Border.all(color: Colors.grey[300], width: 0.35),
  246. borderRadius: BorderRadius.circular(8),
  247. boxShadow: [
  248. BoxShadow(
  249. color: Colors.grey[300],
  250. blurRadius: 3,
  251. offset: Offset(0, 3))
  252. ]),
  253. padding: EdgeInsets.all(8),
  254. child: Row(
  255. children: [
  256. Container(
  257. child: Stack(
  258. children: [
  259. Image.asset(
  260. AppAssets.tempImage,
  261. width: 65,
  262. height: 65,
  263. ),
  264. Positioned(
  265. child: Container(
  266. color: Colors.grey.withOpacity(0.5),
  267. width: 65,
  268. height: 20,
  269. child: Text(
  270. item.areaM2.formatNumtoStringDecimal().toString() +
  271. " m\u00B2",
  272. textAlign: TextAlign.center,
  273. style: TextStyle(color: Colors.white)),
  274. ),
  275. bottom: 0,
  276. )
  277. ],
  278. ),
  279. ),
  280. SizedBox(
  281. width: 12,
  282. ),
  283. Expanded(
  284. child: Container(
  285. height: 75,
  286. child: Column(
  287. crossAxisAlignment: CrossAxisAlignment.start,
  288. mainAxisSize: MainAxisSize.min,
  289. children: [
  290. Text("${item.code ?? ''} - ${item.suppliesName ?? ''}",
  291. style: TextStyle(
  292. color: textColor, fontWeight: FontWeight.bold)),
  293. Expanded(
  294. child: SizedBox(),
  295. ),
  296. Row(
  297. children: [
  298. Icon(
  299. Icons.access_time,
  300. size: 16,
  301. color: textColor,
  302. ),
  303. SizedBox(
  304. width: 4,
  305. ),
  306. Expanded(
  307. child: Text(
  308. item.startDate.format_DDMMYY_HHmm().toString(),
  309. style: TextStyle(color: textColor)),
  310. ),
  311. ],
  312. )
  313. ],
  314. ),
  315. ),
  316. )
  317. ],
  318. ),
  319. ),
  320. onTap: () {
  321. Navigator.push(
  322. context,
  323. MaterialPageRoute(
  324. builder: (BuildContext context) => PlotDetailScreen(
  325. cropId: item.id,
  326. initialIndex: 0,
  327. cropType: item.type,
  328. code: item.code,
  329. areaM2: item.areaM2,
  330. suppliesName: item.suppliesName,
  331. )));
  332. });
  333. }
  334. }