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.

349 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. isShowAppbar: true,
  116. ));
  117. } else {
  118. //Go home
  119. }
  120. }
  121. @override
  122. void initState() {
  123. super.initState();
  124. getSharedPrefs();
  125. }
  126. @override
  127. Widget build(BuildContext context) {
  128. return BlocProvider(
  129. create: (context) =>
  130. PlotBloc(repository: Repository())..add(DataFetched()),
  131. child: HoldInfinityWidget(),
  132. );
  133. }
  134. }
  135. class HoldInfinityWidget extends StatelessWidget {
  136. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  137. @override
  138. Widget build(BuildContext context) {
  139. return Scaffold(
  140. backgroundColor: Colors.white,
  141. key: _scaffoldKey,
  142. body: SafeArea(child: InfinityView()));
  143. }
  144. }
  145. class InfinityView extends StatefulWidget {
  146. @override
  147. _InfinityViewState createState() => _InfinityViewState();
  148. }
  149. class _InfinityViewState extends State<InfinityView> {
  150. final _scrollController = ScrollController();
  151. final _scrollThreshold = 250.0;
  152. PlotBloc _plotBloc;
  153. @override
  154. void initState() {
  155. _scrollController.addListener(() {
  156. final maxScroll = _scrollController.position.maxScrollExtent;
  157. final currentScroll = _scrollController.position.pixels;
  158. if (maxScroll - currentScroll < _scrollThreshold) {
  159. _plotBloc.add(DataFetched());
  160. }
  161. });
  162. _plotBloc = BlocProvider.of<PlotBloc>(context);
  163. super.initState();
  164. }
  165. @override
  166. Widget build(BuildContext context) {
  167. return Column(
  168. crossAxisAlignment: CrossAxisAlignment.start,
  169. children: <Widget>[
  170. SizedBox(
  171. height: 8,
  172. ),
  173. Container(
  174. padding: EdgeInsets.all(8),
  175. color: Colors.white,
  176. child: Text(
  177. 'Danh sách lô trồng',
  178. style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
  179. )),
  180. WidgetSearch(),
  181. Expanded(child: BlocBuilder<PlotBloc, PlotState>(
  182. builder: (context, state) {
  183. if (state is PlotFailure) {
  184. return Center(child: Text(state.errorString));
  185. }
  186. if (state is PlotSuccess) {
  187. if (state.items.isEmpty) {
  188. return Center(child: Text(label_list_empty));
  189. }
  190. return RefreshIndicator(
  191. child: ListView.builder(
  192. physics: AlwaysScrollableScrollPhysics(),
  193. itemBuilder: (BuildContext context, int index) {
  194. return index >= state.items.length
  195. ? BottomLoader()
  196. : ItemInfinityWidget(item: state.items[index]);
  197. },
  198. itemCount: state.hasReachedMax
  199. ? state.items.length
  200. : state.items.length + 1,
  201. controller: _scrollController,
  202. ),
  203. onRefresh: () async {
  204. _plotBloc.add(OnRefresh());
  205. });
  206. }
  207. return Center(
  208. child: LoadingListPage(),
  209. );
  210. },
  211. ))
  212. ],
  213. );
  214. }
  215. @override
  216. void dispose() {
  217. _scrollController.dispose();
  218. super.dispose();
  219. }
  220. }
  221. class ItemInfinityWidget extends StatelessWidget {
  222. final Crop item;
  223. const ItemInfinityWidget({Key key, @required this.item}) : super(key: key);
  224. @override
  225. Widget build(BuildContext context) {
  226. var backgroundColor;
  227. var textColor;
  228. switch (item.status) {
  229. case "STATUS_ARE_ACTIVE":
  230. backgroundColor = Colors.white;
  231. textColor = AppColors.DEFAULT;
  232. break;
  233. case "STATUS_FINISHED":
  234. backgroundColor = AppColors.DEFAULT;
  235. textColor = Colors.white;
  236. break;
  237. default:
  238. backgroundColor = Colors.white;
  239. textColor = Colors.black;
  240. }
  241. return GestureDetector(
  242. child: Container(
  243. margin: EdgeInsets.all(8),
  244. decoration: BoxDecoration(
  245. color: backgroundColor,
  246. border: Border.all(color: Colors.grey[300], width: 0.35),
  247. borderRadius: BorderRadius.circular(8),
  248. boxShadow: [
  249. BoxShadow(
  250. color: Colors.grey[300],
  251. blurRadius: 3,
  252. offset: Offset(0, 3))
  253. ]),
  254. padding: EdgeInsets.all(8),
  255. child: Row(
  256. children: [
  257. Container(
  258. child: Stack(
  259. children: [
  260. Image.asset(
  261. AppAssets.tempImage,
  262. width: 65,
  263. height: 65,
  264. ),
  265. Positioned(
  266. child: Container(
  267. color: Colors.grey.withOpacity(0.5),
  268. width: 65,
  269. height: 20,
  270. child: Text(
  271. item.areaM2.formatNumtoStringDecimal().toString() +
  272. " m\u00B2",
  273. textAlign: TextAlign.center,
  274. style: TextStyle(color: Colors.white)),
  275. ),
  276. bottom: 0,
  277. )
  278. ],
  279. ),
  280. ),
  281. SizedBox(
  282. width: 12,
  283. ),
  284. Expanded(
  285. child: Container(
  286. height: 75,
  287. child: Column(
  288. crossAxisAlignment: CrossAxisAlignment.start,
  289. mainAxisSize: MainAxisSize.min,
  290. children: [
  291. Text("${item.code ?? ''} - ${item.suppliesName ?? ''}",
  292. style: TextStyle(
  293. color: textColor, fontWeight: FontWeight.bold)),
  294. Expanded(
  295. child: SizedBox(),
  296. ),
  297. Row(
  298. children: [
  299. Icon(
  300. Icons.access_time,
  301. size: 16,
  302. color: textColor,
  303. ),
  304. SizedBox(
  305. width: 4,
  306. ),
  307. Expanded(
  308. child: Text(
  309. item.startDate.format_DDMMYY_HHmm().toString(),
  310. style: TextStyle(color: textColor)),
  311. ),
  312. ],
  313. )
  314. ],
  315. ),
  316. ),
  317. )
  318. ],
  319. ),
  320. ),
  321. onTap: () {
  322. Navigator.push(
  323. context,
  324. MaterialPageRoute(
  325. builder: (BuildContext context) => PlotDetailScreen(
  326. cropId: item.id, initialIndex: 0, cropType: item.type)));
  327. });
  328. }
  329. }