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.

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