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.

281 lines
9.7KB

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