import 'package:farm_tpf/custom_model/CropPlot.dart'; import 'package:farm_tpf/data/repository/repository.dart'; import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart'; import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart'; import 'package:farm_tpf/presentation/screens/actions/crop_status/sc_edit_action_crop_status.dart'; import 'package:farm_tpf/presentation/screens/actions/disease/sc_edit_action_disease.dart'; import 'package:farm_tpf/presentation/screens/actions/dung/sc_edit_action_dung.dart'; import 'package:farm_tpf/presentation/screens/actions/end/sc_edit_action_end.dart'; import 'package:farm_tpf/presentation/screens/actions/environment_update/sc_edit_action_environment_update.dart'; import 'package:farm_tpf/presentation/screens/actions/harvest/sc_edit_action_harvest.dart'; import 'package:farm_tpf/presentation/screens/actions/nursery/sc_edit_action_nursery.dart'; import 'package:farm_tpf/presentation/screens/actions/other/sc_edit_action_other.dart'; import 'package:farm_tpf/presentation/screens/actions/plant/sc_edit_action_plant.dart'; import 'package:farm_tpf/presentation/screens/actions/spraying/sc_edit_action_spraying.dart'; import 'package:farm_tpf/presentation/screens/actions/use_water/sc_edit_action_user_water.dart'; import 'package:farm_tpf/presentation/screens/plot/sc_plot.dart'; import 'package:farm_tpf/presentation/screens/plot_detail/bloc/plot_detail_bloc.dart'; import 'package:farm_tpf/utils/const_color.dart'; import 'package:farm_tpf/utils/const_string.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:farm_tpf/utils/formatter.dart'; import 'package:get/get.dart'; class PlotActionScreen extends StatefulWidget { int cropId; String cropCode; PlotActionScreen({this.cropId, this.cropCode}); @override _PlotActionScreenState createState() => _PlotActionScreenState(); } class _PlotActionScreenState extends State { List actions = new List(); ScrollController _scrollController; var changeToRefresh = Get.put(ChangeToRefreshLists()); @override void initState() { super.initState(); changeToRefresh.initValue(); _scrollController = ScrollController()..addListener(() => setState(() {})); _initActionButtons(); } _initActionButtons() { actions.add(ActionType( plot_action_nursery, null, EditActionNurseryScreen( cropId: widget.cropId, ))); actions.add(ActionType(plot_action_plant, null, EditActionPlantScreen())); actions.add(ActionType( plot_action_crop_status, null, EditActionCropStatusScreen( cropId: widget.cropId, ))); actions.add(ActionType( plot_action_environment_update, null, EditActionEnvironmentUpdate( cropId: widget.cropId, ))); actions.add(ActionType(plot_action_dung, null, EditActionDungScreen())); actions.add( ActionType(plot_action_spraying, null, EditActionSprayingScreen())); actions.add(ActionType( plot_action_disease, null, EditActionDiseaseScreen( cropId: widget.cropId, ))); actions.add(ActionType( plot_action_use_water, null, EditActionUseWaterScreen( cropId: widget.cropId, ))); actions.add(ActionType(plot_action_other, null, EditActionOtherScreen())); actions.add(ActionType( plot_action_harvest, null, EditActionHarvestScreen( cropId: widget.cropId, ))); actions.add(ActionType(plot_action_finish, null, EditActionEndScreen())); } Widget _createActionButtons(ActionType actionType, BuildContext _context) { return BlocProvider( create: (context) => PlotDetailBloc(repository: Repository()), child: GestureDetector( onTap: () { Navigator.of(context) .push(MaterialPageRoute( builder: (context) => actionType.listScreen)) .then((value) { if (1 == 1) { try { //TODO: refresh list } catch (e) { print(e.toString()); } } }); }, child: Container( height: 75, margin: EdgeInsets.all(4.0), padding: EdgeInsets.all(0.0), decoration: BoxDecoration( color: COLOR_CONST.WHITE, borderRadius: BorderRadius.only( topLeft: Radius.circular(8.0), bottomLeft: Radius.circular(8.0), bottomRight: Radius.circular(8.0), topRight: Radius.circular(8.0)), boxShadow: [ BoxShadow( color: COLOR_CONST.GRAY1.withOpacity(0.2), offset: Offset(1.1, 1.1), blurRadius: 10.0), ], ), child: Stack( children: [ Positioned( top: -10, right: -3, child: (actionType.addScreen == null) ? Container() : IconButton( icon: Icon( Icons.add_circle, size: 40, color: Colors.green, ), onPressed: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) => actionType.addScreen)); })), Positioned.fill( child: Align( alignment: Alignment.center, child: Text( actionType.actionName, textAlign: TextAlign.center, style: TextStyle( fontWeight: FontWeight.w400, fontSize: 13, color: COLOR_CONST.BLACK2, ), )), ), ], ), )), ); } bool _showTitle(BuildContext context) { var kExpandedHeight = MediaQuery.of(context).size.width * 1.125 + 32; return _scrollController.hasClients && _scrollController.offset > kExpandedHeight - kToolbarHeight; } @override Widget build(BuildContext context) { return NestedScrollView( controller: _scrollController, headerSliverBuilder: (context, innerBoxScrolled) => [ SliverAppBar( floating: false, pinned: false, backgroundColor: Colors.white, leading: Container(), title: null, // title: _showTitle(context) ? Text(plot_detail_title) : null, //Height flexibleSpace : WidthScreen /2 * 6/16 * 6(row) + 8(space) *4 expandedHeight: MediaQuery.of(context).size.width * 1.125 + 32, flexibleSpace: _showTitle(context) ? null : BlocProvider( create: (context) => PlotDetailBloc(repository: Repository()), child: BlocBuilder( builder: (contextB, state) { return FlexibleSpaceBar( centerTitle: true, title: GridView.count( shrinkWrap: true, crossAxisCount: 2, childAspectRatio: 16 / 6, children: actions.map( (item) { return _createActionButtons(item, contextB); }, ).toList()), ); }), ), ), ], body: BlocProvider( create: (context) => PlotDetailBloc(repository: Repository()) ..add(DataFetched(cropId: widget.cropId, cropCode: widget.cropCode)), child: HoldInfinityWidget( cropId: widget.cropId, cropCode: widget.cropCode, ), ), ); } } class HoldInfinityWidget extends StatelessWidget { int cropId; String cropCode; HoldInfinityWidget({this.cropId, this.cropCode}); final GlobalKey _scaffoldKey = new GlobalKey(); @override Widget build(BuildContext context) { return Scaffold(key: _scaffoldKey, body: InfinityView(cropId: cropId)); } } class InfinityView extends StatefulWidget { int cropId; String cropCode; InfinityView({this.cropId, this.cropCode}); @override _InfinityViewState createState() => _InfinityViewState(); } class _InfinityViewState extends State { final _scrollController = ScrollController(); final _scrollThreshold = 250.0; PlotDetailBloc _plotDetailBloc; var a = Get.put(ChangeToRefreshLists()); @override void initState() { _scrollController.addListener(() { final maxScroll = _scrollController.position.maxScrollExtent; final currentScroll = _scrollController.position.pixels; if (maxScroll - currentScroll < _scrollThreshold) { _plotDetailBloc .add(DataFetched(cropId: widget.cropId, cropCode: widget.cropCode)); } }); _plotDetailBloc = BlocProvider.of(context); super.initState(); } @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { if (state is PlotDetailFailure) { return Center(child: Text(state.errorString)); } if (state is PlotDetailSuccess) { if (state.items.isEmpty) { return Center(child: Text(label_list_empty)); } List currentItems = List.from(state.items); Get.find() .updateValue(currentItems, state.page, state.hasReachedMax); return RefreshIndicator( child: Column( children: [ Container( height: 40, alignment: Alignment.center, decoration: BoxDecoration( color: COLOR_CONST.WHITE_50, border: Border( top: BorderSide( width: 0.5, color: COLOR_CONST.DEFAULT), bottom: BorderSide( width: 0.5, color: COLOR_CONST.DEFAULT)), ), child: Text( plot_detail_title, style: TextStyle( fontSize: 20, fontWeight: FontWeight.normal), )), Expanded( child: ListView.builder( physics: AlwaysScrollableScrollPhysics(), itemBuilder: (BuildContext context, int index) { return index >= state.items.length ? BottomLoader() : ItemInfinityWidget( currentItems: currentItems, item: state.items[index], currentPage: state.page, currentReachedMax: state.hasReachedMax); }, itemCount: state.hasReachedMax ? state.items.length : state.items.length + 1, controller: _scrollController, )) ], ), onRefresh: () async { _plotDetailBloc.add(OnRefresh( cropId: widget.cropId, cropCode: widget.cropCode)); }); } return Center( child: LoadingListPage(), ); }, ); } @override void dispose() { _scrollController.dispose(); super.dispose(); } } class ItemInfinityWidget extends StatelessWidget { final List currentItems; final Activities item; final int currentPage; final bool currentReachedMax; const ItemInfinityWidget( {Key key, @required this.currentItems, @required this.item, @required this.currentPage, @required this.currentReachedMax}) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( child: Card( child: ListTile( title: Text(item.activityTypeDescription ?? ''), subtitle: Text(item.executeDate.format_DDMMYY_HHmm()), trailing: Text(item.id.toString()), ), ), onTap: () { if (item.activityTypeName == "ACTIVE_TYPE_NURSERY") { Get.to(EditActionNurseryScreen( cropId: item.cropId, activityId: item.id, isEdit: true, )).then((value) { if (value != null) { try { //TODO: refresh when edit activity // BlocProvider.of(context) // .add(OnRefresh(cropId: item.cropId)); // var updatedItem = Activities.fromJson(value); // List updatedItems = new List(); // currentItems.forEach((e) { // if (e.id == updatedItem.id) { // e.executeDate = updatedItem.executeDate; // } else { // // // } // updatedItems.add(Activities.clone(e)); // }); // BlocProvider.of(context).add( // OnUpdate( // currentItems: updatedItems, // currentPage: currentPage, // hasReachedMax: currentReachedMax)); } catch (e) { print(e.toString()); } } }); } else if (item.activityTypeName == "ACTIVE_TYPE_STATUS_CROP") { Get.to(EditActionCropStatusScreen( cropId: item.cropId, activityId: item.id, isEdit: true, )); } else if (item.activityTypeName == "ACTIVE_TYPE_UPDATE_ENV") { Get.to(EditActionEnvironmentUpdate( cropId: item.cropId, activityId: item.id, isEdit: true, )); } else if (item.activityTypeName == "ACTIVE_TYPE_PESTS_INVESTIGATION") { Get.to(EditActionDiseaseScreen( cropId: item.cropId, activityId: item.id, isEdit: true, )); } else if (item.activityTypeName == "ACTIVE_TYPE_USE_WATER") { Get.to(EditActionUseWaterScreen( cropId: item.cropId, activityId: item.id, isEdit: true, )); } else if (item.activityTypeName == "ACTIVE_TYPE_HARVEST") { Get.to(EditActionHarvestScreen( cropId: item.cropId, activityId: item.id, isEdit: true, )); } }); } } class ActionType { Widget addScreen; Widget listScreen; String actionName; ActionType(String actionName, Widget addScreen, Widget listScreen) { this.actionName = actionName; this.addScreen = addScreen; this.listScreen = listScreen; } } class ChangeToRefreshLists extends GetxController { List currentItems; int currentPage; bool currentReachedMax; void initValue() { currentItems = List(); currentPage = 0; currentReachedMax = true; update(); } void updateValue(List updateItems, int page, bool reachedMax) { currentItems = updateItems; currentPage = page; currentReachedMax = reachedMax; update(); } }