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.

315 lines
11KB

  1. import 'package:farm_tpf/custom_model/CropPlot.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/loading_list_page.dart';
  5. import 'package:farm_tpf/presentation/screens/actions/crop_status/sc_edit_action_crop_status.dart';
  6. import 'package:farm_tpf/presentation/screens/actions/disease/sc_edit_action_disease.dart';
  7. import 'package:farm_tpf/presentation/screens/actions/dung/sc_edit_action_dung.dart';
  8. import 'package:farm_tpf/presentation/screens/actions/end/sc_edit_action_end.dart';
  9. import 'package:farm_tpf/presentation/screens/actions/environment_update/sc_edit_action_environment_update.dart';
  10. import 'package:farm_tpf/presentation/screens/actions/harvest/sc_edit_action_harvest.dart';
  11. import 'package:farm_tpf/presentation/screens/actions/nursery/sc_edit_action_nursery.dart';
  12. import 'package:farm_tpf/presentation/screens/actions/other/sc_edit_action_other.dart';
  13. import 'package:farm_tpf/presentation/screens/actions/plant/sc_edit_action_plant.dart';
  14. import 'package:farm_tpf/presentation/screens/actions/spraying/sc_edit_action_spraying.dart';
  15. import 'package:farm_tpf/presentation/screens/actions/use_water/sc_edit_action_user_water.dart';
  16. import 'package:farm_tpf/presentation/screens/plot/sc_plot.dart';
  17. import 'package:farm_tpf/presentation/screens/plot_detail/bloc/plot_detail_bloc.dart';
  18. import 'package:farm_tpf/utils/const_color.dart';
  19. import 'package:farm_tpf/utils/const_string.dart';
  20. import 'package:flutter/material.dart';
  21. import 'package:flutter_bloc/flutter_bloc.dart';
  22. import 'package:farm_tpf/utils/formatter.dart';
  23. import 'package:get/get.dart';
  24. class PlotActionScreen extends StatefulWidget {
  25. int cropId;
  26. String cropCode;
  27. PlotActionScreen({this.cropId, this.cropCode});
  28. @override
  29. _PlotActionScreenState createState() => _PlotActionScreenState();
  30. }
  31. class _PlotActionScreenState extends State<PlotActionScreen> {
  32. List<ActionType> actions = new List<ActionType>();
  33. ScrollController _scrollController;
  34. @override
  35. void initState() {
  36. super.initState();
  37. _scrollController = ScrollController()..addListener(() => setState(() {}));
  38. _initActionButtons();
  39. }
  40. _initActionButtons() {
  41. actions.add(ActionType(
  42. plot_action_nursery,
  43. null,
  44. EditActionNurseryScreen(
  45. cropId: widget.cropId,
  46. )));
  47. actions.add(ActionType(plot_action_plant, null, EditActionPlantScreen()));
  48. actions.add(ActionType(
  49. plot_action_crop_status, null, EditActionCropStatusScreen()));
  50. actions.add(ActionType(
  51. plot_action_environment_update, null, EditActionEnvironmentUpdate()));
  52. actions.add(ActionType(plot_action_dung, null, EditActionDungScreen()));
  53. actions.add(
  54. ActionType(plot_action_spraying, null, EditActionSprayingScreen()));
  55. actions
  56. .add(ActionType(plot_action_disease, null, EditActionDiseaseScreen()));
  57. actions.add(
  58. ActionType(plot_action_use_water, null, EditActionUseWaterScreen()));
  59. actions.add(ActionType(plot_action_other, null, EditActionOtherScreen()));
  60. actions
  61. .add(ActionType(plot_action_harvest, null, EditActionHarvestScreen()));
  62. actions.add(ActionType(plot_action_finish, null, EditActionEndScreen()));
  63. }
  64. Widget _createActionButtons(ActionType actionType) {
  65. return GestureDetector(
  66. onTap: () {
  67. Navigator.of(context).push(
  68. MaterialPageRoute(builder: (context) => actionType.listScreen));
  69. },
  70. child: Container(
  71. height: 75,
  72. margin: EdgeInsets.all(4.0),
  73. padding: EdgeInsets.all(0.0),
  74. decoration: BoxDecoration(
  75. color: COLOR_CONST.WHITE,
  76. borderRadius: BorderRadius.only(
  77. topLeft: Radius.circular(8.0),
  78. bottomLeft: Radius.circular(8.0),
  79. bottomRight: Radius.circular(8.0),
  80. topRight: Radius.circular(8.0)),
  81. boxShadow: <BoxShadow>[
  82. BoxShadow(
  83. color: COLOR_CONST.GRAY1.withOpacity(0.2),
  84. offset: Offset(1.1, 1.1),
  85. blurRadius: 10.0),
  86. ],
  87. ),
  88. child: Stack(
  89. children: <Widget>[
  90. Positioned(
  91. top: -10,
  92. right: -3,
  93. child: (actionType.addScreen == null)
  94. ? Container()
  95. : IconButton(
  96. icon: Icon(
  97. Icons.add_circle,
  98. size: 40,
  99. color: Colors.green,
  100. ),
  101. onPressed: () {
  102. Navigator.of(context).push(MaterialPageRoute(
  103. builder: (context) => actionType.addScreen));
  104. })),
  105. Positioned.fill(
  106. child: Align(
  107. alignment: Alignment.center,
  108. child: Text(
  109. actionType.actionName,
  110. textAlign: TextAlign.center,
  111. style: TextStyle(
  112. fontWeight: FontWeight.w400,
  113. fontSize: 13,
  114. color: COLOR_CONST.BLACK2,
  115. ),
  116. )),
  117. ),
  118. ],
  119. ),
  120. ));
  121. }
  122. bool _showTitle(BuildContext context) {
  123. var kExpandedHeight = MediaQuery.of(context).size.width * 1.125 + 32;
  124. return _scrollController.hasClients &&
  125. _scrollController.offset > kExpandedHeight - kToolbarHeight;
  126. }
  127. @override
  128. Widget build(BuildContext context) {
  129. return NestedScrollView(
  130. controller: _scrollController,
  131. headerSliverBuilder: (context, innerBoxScrolled) => [
  132. SliverAppBar(
  133. floating: false,
  134. pinned: false,
  135. backgroundColor: Colors.white,
  136. leading: Container(),
  137. title: null,
  138. // title: _showTitle(context) ? Text(plot_detail_title) : null,
  139. //Height flexibleSpace : WidthScreen /2 * 6/16 * 6(row) + 8(space) *4
  140. expandedHeight: MediaQuery.of(context).size.width * 1.125 + 32,
  141. flexibleSpace: _showTitle(context)
  142. ? null
  143. : FlexibleSpaceBar(
  144. centerTitle: true,
  145. title: GridView.count(
  146. shrinkWrap: true,
  147. crossAxisCount: 2,
  148. childAspectRatio: 16 / 6,
  149. children: actions.map(
  150. (item) {
  151. return _createActionButtons(item);
  152. },
  153. ).toList()),
  154. ),
  155. ),
  156. ],
  157. body: BlocProvider(
  158. create: (context) => PlotDetailBloc(repository: Repository())
  159. ..add(DataFetched(cropId: widget.cropId, cropCode: widget.cropCode)),
  160. child: HoldInfinityWidget(
  161. cropId: widget.cropId,
  162. cropCode: widget.cropCode,
  163. ),
  164. ),
  165. );
  166. }
  167. }
  168. class HoldInfinityWidget extends StatelessWidget {
  169. int cropId;
  170. String cropCode;
  171. HoldInfinityWidget({this.cropId, this.cropCode});
  172. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  173. @override
  174. Widget build(BuildContext context) {
  175. return Scaffold(key: _scaffoldKey, body: InfinityView(cropId: cropId));
  176. }
  177. }
  178. class InfinityView extends StatefulWidget {
  179. int cropId;
  180. String cropCode;
  181. InfinityView({this.cropId, this.cropCode});
  182. @override
  183. _InfinityViewState createState() => _InfinityViewState();
  184. }
  185. class _InfinityViewState extends State<InfinityView> {
  186. final _scrollController = ScrollController();
  187. final _scrollThreshold = 250.0;
  188. PlotDetailBloc _plotDetailBloc;
  189. @override
  190. void initState() {
  191. _scrollController.addListener(() {
  192. final maxScroll = _scrollController.position.maxScrollExtent;
  193. final currentScroll = _scrollController.position.pixels;
  194. if (maxScroll - currentScroll < _scrollThreshold) {
  195. _plotDetailBloc
  196. .add(DataFetched(cropId: widget.cropId, cropCode: widget.cropCode));
  197. }
  198. });
  199. _plotDetailBloc = BlocProvider.of<PlotDetailBloc>(context);
  200. super.initState();
  201. }
  202. @override
  203. Widget build(BuildContext context) {
  204. return BlocBuilder<PlotDetailBloc, PlotDetailState>(
  205. builder: (context, state) {
  206. if (state is PlotDetailFailure) {
  207. return Center(child: Text(state.errorString));
  208. }
  209. if (state is PlotDetailSuccess) {
  210. if (state.items.isEmpty) {
  211. return Center(child: Text(label_list_empty));
  212. }
  213. return RefreshIndicator(
  214. child: Column(
  215. children: [
  216. Container(
  217. height: 40,
  218. alignment: Alignment.center,
  219. decoration: BoxDecoration(
  220. color: COLOR_CONST.WHITE_50,
  221. border: Border(
  222. top: BorderSide(
  223. width: 0.5, color: COLOR_CONST.DEFAULT),
  224. bottom: BorderSide(
  225. width: 0.5, color: COLOR_CONST.DEFAULT)),
  226. ),
  227. child: Text(
  228. plot_detail_title,
  229. style: TextStyle(
  230. fontSize: 20, fontWeight: FontWeight.normal),
  231. )),
  232. Expanded(
  233. child: ListView.builder(
  234. physics: AlwaysScrollableScrollPhysics(),
  235. itemBuilder: (BuildContext context, int index) {
  236. return index >= state.items.length
  237. ? BottomLoader()
  238. : ItemInfinityWidget(item: state.items[index]);
  239. },
  240. itemCount: state.hasReachedMax
  241. ? state.items.length
  242. : state.items.length + 1,
  243. controller: _scrollController,
  244. ))
  245. ],
  246. ),
  247. onRefresh: () async {
  248. _plotDetailBloc.add(OnRefresh(
  249. cropId: widget.cropId, cropCode: widget.cropCode));
  250. });
  251. }
  252. return Center(
  253. child: LoadingListPage(),
  254. );
  255. },
  256. );
  257. }
  258. @override
  259. void dispose() {
  260. _scrollController.dispose();
  261. super.dispose();
  262. }
  263. }
  264. class ItemInfinityWidget extends StatelessWidget {
  265. final Activities item;
  266. const ItemInfinityWidget({Key key, @required this.item}) : super(key: key);
  267. @override
  268. Widget build(BuildContext context) {
  269. return GestureDetector(
  270. child: Card(
  271. child: ListTile(
  272. title: Text(item.activityTypeDescription ?? ''),
  273. subtitle: Text(item.executeDate.format_DDMMYY_HHmm()),
  274. trailing: Text(item.id.toString()),
  275. ),
  276. ),
  277. onTap: () {
  278. if (item.activityTypeName == "ACTIVE_TYPE_NURSERY") {
  279. Get.to(EditActionNurseryScreen(
  280. cropId: item.cropId,
  281. activityId: item.id,
  282. isEdit: true,
  283. ));
  284. }
  285. });
  286. }
  287. }
  288. class ActionType {
  289. Widget addScreen;
  290. Widget listScreen;
  291. String actionName;
  292. ActionType(String actionName, Widget addScreen, Widget listScreen) {
  293. this.actionName = actionName;
  294. this.addScreen = addScreen;
  295. this.listScreen = listScreen;
  296. }
  297. }