|
|
|
|
|
|
|
|
class _PlotActionScreenState extends State<PlotActionScreen> { |
|
|
class _PlotActionScreenState extends State<PlotActionScreen> { |
|
|
List<ActionType> actions = new List<ActionType>(); |
|
|
List<ActionType> actions = new List<ActionType>(); |
|
|
ScrollController _scrollController; |
|
|
ScrollController _scrollController; |
|
|
var changeToRefresh = Get.put(ChangeToRefreshLists()); |
|
|
|
|
|
|
|
|
var blocPlotDetail = PlotDetailBloc(repository: Repository()); |
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
void initState() { |
|
|
void initState() { |
|
|
super.initState(); |
|
|
super.initState(); |
|
|
changeToRefresh.initValue(); |
|
|
|
|
|
_scrollController = ScrollController()..addListener(() => setState(() {})); |
|
|
_scrollController = ScrollController()..addListener(() => setState(() {})); |
|
|
_initActionButtons(); |
|
|
_initActionButtons(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
|
void dispose() { |
|
|
|
|
|
blocPlotDetail.close(); |
|
|
|
|
|
super.dispose(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
_initActionButtons() { |
|
|
_initActionButtons() { |
|
|
//type: 0- Trồng, 1- ướm |
|
|
//type: 0- Trồng, 1- ướm |
|
|
if (widget.cropType == 1) { |
|
|
if (widget.cropType == 1) { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Widget _createActionButtons(ActionType actionType, BuildContext _context) { |
|
|
Widget _createActionButtons(ActionType actionType, BuildContext _context) { |
|
|
return BlocProvider<PlotDetailBloc>( |
|
|
|
|
|
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( |
|
|
|
|
|
margin: EdgeInsets.all(2.5), |
|
|
|
|
|
decoration: BoxDecoration( |
|
|
|
|
|
color: COLOR_CONST.WHITE, |
|
|
|
|
|
borderRadius: BorderRadius.all(Radius.circular(4.0)), |
|
|
|
|
|
boxShadow: <BoxShadow>[ |
|
|
|
|
|
BoxShadow( |
|
|
|
|
|
color: COLOR_CONST.GRAY1.withOpacity(0.2), |
|
|
|
|
|
offset: Offset(1.1, 1.1), |
|
|
|
|
|
blurRadius: 4.0), |
|
|
|
|
|
], |
|
|
|
|
|
), |
|
|
|
|
|
child: Align( |
|
|
|
|
|
alignment: Alignment.center, |
|
|
|
|
|
child: Text( |
|
|
|
|
|
actionType.actionName, |
|
|
|
|
|
textAlign: TextAlign.center, |
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
fontWeight: FontWeight.w400, |
|
|
|
|
|
fontSize: 11, |
|
|
|
|
|
color: COLOR_CONST.BLACK2, |
|
|
|
|
|
), |
|
|
|
|
|
)), |
|
|
|
|
|
)), |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
return BlocBuilder<PlotDetailBloc, PlotDetailState>( |
|
|
|
|
|
cubit: blocPlotDetail, |
|
|
|
|
|
builder: (context, state) { |
|
|
|
|
|
return GestureDetector( |
|
|
|
|
|
onTap: () { |
|
|
|
|
|
Navigator.of(context) |
|
|
|
|
|
.push(MaterialPageRoute( |
|
|
|
|
|
builder: (context) => actionType.listScreen)) |
|
|
|
|
|
.then((value) { |
|
|
|
|
|
if (value != null) { |
|
|
|
|
|
try { |
|
|
|
|
|
blocPlotDetail.add(OnRefresh(cropId: widget.cropId)); |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
print(e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
child: Container( |
|
|
|
|
|
margin: EdgeInsets.all(2.5), |
|
|
|
|
|
decoration: BoxDecoration( |
|
|
|
|
|
color: COLOR_CONST.WHITE, |
|
|
|
|
|
borderRadius: BorderRadius.all(Radius.circular(4.0)), |
|
|
|
|
|
boxShadow: <BoxShadow>[ |
|
|
|
|
|
BoxShadow( |
|
|
|
|
|
color: COLOR_CONST.GRAY1.withOpacity(0.2), |
|
|
|
|
|
offset: Offset(1.1, 1.1), |
|
|
|
|
|
blurRadius: 4.0), |
|
|
|
|
|
], |
|
|
|
|
|
), |
|
|
|
|
|
child: Align( |
|
|
|
|
|
alignment: Alignment.center, |
|
|
|
|
|
child: Text( |
|
|
|
|
|
actionType.actionName, |
|
|
|
|
|
textAlign: TextAlign.center, |
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
fontWeight: FontWeight.w400, |
|
|
|
|
|
fontSize: 11, |
|
|
|
|
|
color: COLOR_CONST.BLACK2, |
|
|
|
|
|
), |
|
|
|
|
|
)), |
|
|
|
|
|
)); |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool _showTitle(BuildContext context) { |
|
|
bool _showTitle(BuildContext context) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
Widget build(BuildContext context) { |
|
|
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 * 4/16 * 5(row) + 8(space) *3 |
|
|
|
|
|
expandedHeight: MediaQuery.of(context).size.width * 0.625 + 24, |
|
|
|
|
|
flexibleSpace: _showTitle(context) |
|
|
|
|
|
? null |
|
|
|
|
|
: BlocProvider<PlotDetailBloc>( |
|
|
|
|
|
create: (context) => PlotDetailBloc(repository: Repository()), |
|
|
|
|
|
child: BlocBuilder<PlotDetailBloc, PlotDetailState>( |
|
|
|
|
|
builder: (contextB, state) { |
|
|
|
|
|
return FlexibleSpaceBar( |
|
|
|
|
|
centerTitle: true, |
|
|
|
|
|
title: GridView.count( |
|
|
|
|
|
shrinkWrap: true, |
|
|
|
|
|
crossAxisCount: 2, |
|
|
|
|
|
childAspectRatio: 16 / 4, |
|
|
|
|
|
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, |
|
|
|
|
|
parentScroll: _scrollController, |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class HoldInfinityWidget extends StatelessWidget { |
|
|
|
|
|
int cropId; |
|
|
|
|
|
String cropCode; |
|
|
|
|
|
ScrollController parentScroll; |
|
|
|
|
|
HoldInfinityWidget({this.cropId, this.cropCode, @required this.parentScroll}); |
|
|
|
|
|
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); |
|
|
|
|
|
@override |
|
|
|
|
|
Widget build(BuildContext context) { |
|
|
|
|
|
return Scaffold( |
|
|
|
|
|
key: _scaffoldKey, |
|
|
|
|
|
body: InfinityView( |
|
|
|
|
|
cropId: cropId, |
|
|
|
|
|
parentScroll: parentScroll, |
|
|
|
|
|
)); |
|
|
|
|
|
|
|
|
return BlocBuilder<PlotDetailBloc, PlotDetailState>( |
|
|
|
|
|
cubit: blocPlotDetail, |
|
|
|
|
|
builder: (context, state) { |
|
|
|
|
|
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 * 4/16 * 5(row) + 8(space) *3 |
|
|
|
|
|
expandedHeight: |
|
|
|
|
|
MediaQuery.of(context).size.width * 0.625 + 24, |
|
|
|
|
|
flexibleSpace: _showTitle(context) |
|
|
|
|
|
? null |
|
|
|
|
|
: BlocBuilder<PlotDetailBloc, PlotDetailState>( |
|
|
|
|
|
cubit: blocPlotDetail, |
|
|
|
|
|
builder: (contextB, state) { |
|
|
|
|
|
return FlexibleSpaceBar( |
|
|
|
|
|
centerTitle: true, |
|
|
|
|
|
title: GridView.count( |
|
|
|
|
|
shrinkWrap: true, |
|
|
|
|
|
crossAxisCount: 2, |
|
|
|
|
|
childAspectRatio: 16 / 4, |
|
|
|
|
|
children: actions.map( |
|
|
|
|
|
(item) { |
|
|
|
|
|
return _createActionButtons( |
|
|
|
|
|
item, contextB); |
|
|
|
|
|
}, |
|
|
|
|
|
).toList()), |
|
|
|
|
|
); |
|
|
|
|
|
})), |
|
|
|
|
|
], |
|
|
|
|
|
body: BlocBuilder<PlotDetailBloc, PlotDetailState>( |
|
|
|
|
|
cubit: blocPlotDetail, |
|
|
|
|
|
builder: (context, state) { |
|
|
|
|
|
return InfinityView( |
|
|
|
|
|
cropId: widget.cropId, |
|
|
|
|
|
parentScroll: _scrollController, |
|
|
|
|
|
plotDetailBloc: blocPlotDetail, |
|
|
|
|
|
); |
|
|
|
|
|
}), |
|
|
|
|
|
); |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int cropId; |
|
|
int cropId; |
|
|
String cropCode; |
|
|
String cropCode; |
|
|
ScrollController parentScroll; |
|
|
ScrollController parentScroll; |
|
|
InfinityView({this.cropId, this.cropCode, @required this.parentScroll}); |
|
|
|
|
|
|
|
|
PlotDetailBloc plotDetailBloc; |
|
|
|
|
|
InfinityView( |
|
|
|
|
|
{this.cropId, |
|
|
|
|
|
this.cropCode, |
|
|
|
|
|
@required this.parentScroll, |
|
|
|
|
|
@required this.plotDetailBloc}); |
|
|
@override |
|
|
@override |
|
|
_InfinityViewState createState() => _InfinityViewState(); |
|
|
_InfinityViewState createState() => _InfinityViewState(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
class _InfinityViewState extends State<InfinityView> { |
|
|
class _InfinityViewState extends State<InfinityView> { |
|
|
final _scrollController = ScrollController(); |
|
|
final _scrollController = ScrollController(); |
|
|
final _scrollThreshold = 250.0; |
|
|
final _scrollThreshold = 250.0; |
|
|
PlotDetailBloc _plotDetailBloc; |
|
|
|
|
|
var a = Get.put(ChangeToRefreshLists()); |
|
|
|
|
|
var heightOfActionButton = Get.width * 0.625 + 24; |
|
|
var heightOfActionButton = Get.width * 0.625 + 24; |
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
void initState() { |
|
|
void initState() { |
|
|
|
|
|
widget.plotDetailBloc |
|
|
|
|
|
.add(DataFetched(cropId: widget.cropId, cropCode: widget.cropCode)); |
|
|
_scrollController.addListener(() { |
|
|
_scrollController.addListener(() { |
|
|
final maxScroll = _scrollController.position.maxScrollExtent; |
|
|
final maxScroll = _scrollController.position.maxScrollExtent; |
|
|
final currentScroll = _scrollController.position.pixels; |
|
|
final currentScroll = _scrollController.position.pixels; |
|
|
if (maxScroll - currentScroll < _scrollThreshold) { |
|
|
if (maxScroll - currentScroll < _scrollThreshold) { |
|
|
_plotDetailBloc |
|
|
|
|
|
|
|
|
widget.plotDetailBloc |
|
|
.add(DataFetched(cropId: widget.cropId, cropCode: widget.cropCode)); |
|
|
.add(DataFetched(cropId: widget.cropId, cropCode: widget.cropCode)); |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
_plotDetailBloc = BlocProvider.of<PlotDetailBloc>(context); |
|
|
|
|
|
super.initState(); |
|
|
super.initState(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
Widget build(BuildContext context) { |
|
|
Widget build(BuildContext context) { |
|
|
return BlocBuilder<PlotDetailBloc, PlotDetailState>( |
|
|
return BlocBuilder<PlotDetailBloc, PlotDetailState>( |
|
|
|
|
|
cubit: widget.plotDetailBloc, |
|
|
builder: (context, state) { |
|
|
builder: (context, state) { |
|
|
if (state is PlotDetailFailure) { |
|
|
if (state is PlotDetailFailure) { |
|
|
return Center(child: Text(state.errorString)); |
|
|
return Center(child: Text(state.errorString)); |
|
|
|
|
|
|
|
|
return Center(child: Text(label_list_empty)); |
|
|
return Center(child: Text(label_list_empty)); |
|
|
} |
|
|
} |
|
|
List<Activities> currentItems = List<Activities>.from(state.items); |
|
|
List<Activities> currentItems = List<Activities>.from(state.items); |
|
|
Get.find<ChangeToRefreshLists>() |
|
|
|
|
|
.updateValue(currentItems, state.page, state.hasReachedMax); |
|
|
|
|
|
return RefreshIndicator( |
|
|
return RefreshIndicator( |
|
|
child: Column( |
|
|
child: Column( |
|
|
children: [ |
|
|
children: [ |
|
|
|
|
|
|
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
onRefresh: () async { |
|
|
onRefresh: () async { |
|
|
_plotDetailBloc.add(OnRefresh( |
|
|
|
|
|
|
|
|
widget.plotDetailBloc.add(OnRefresh( |
|
|
cropId: widget.cropId, cropCode: widget.cropCode)); |
|
|
cropId: widget.cropId, cropCode: widget.cropCode)); |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
child: ListTile( |
|
|
child: ListTile( |
|
|
title: Text(item.activityTypeDescription ?? ''), |
|
|
title: Text(item.activityTypeDescription ?? ''), |
|
|
subtitle: Text(item.executeDate.format_DDMMYY_HHmm()), |
|
|
subtitle: Text(item.executeDate.format_DDMMYY_HHmm()), |
|
|
//TODO: remove when release |
|
|
|
|
|
// trailing: Text(item.id.toString()), |
|
|
|
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
onTap: () { |
|
|
onTap: () { |
|
|
|
|
|
|
|
|
cropId: item.cropId, |
|
|
cropId: item.cropId, |
|
|
activityId: item.id, |
|
|
activityId: item.id, |
|
|
isEdit: true, |
|
|
isEdit: true, |
|
|
)).then((value) { |
|
|
|
|
|
if (value != null) { |
|
|
|
|
|
try { |
|
|
|
|
|
//TODO: refresh when edit activity |
|
|
|
|
|
// BlocProvider.of<PlotDetailBloc>(context) |
|
|
|
|
|
// .add(OnRefresh(cropId: item.cropId)); |
|
|
|
|
|
// var updatedItem = Activities.fromJson(value); |
|
|
|
|
|
|
|
|
|
|
|
// List<Activities> updatedItems = new List<Activities>(); |
|
|
|
|
|
// currentItems.forEach((e) { |
|
|
|
|
|
// if (e.id == updatedItem.id) { |
|
|
|
|
|
// e.executeDate = updatedItem.executeDate; |
|
|
|
|
|
// } else { |
|
|
|
|
|
// // |
|
|
|
|
|
// } |
|
|
|
|
|
// updatedItems.add(Activities.clone(e)); |
|
|
|
|
|
// }); |
|
|
|
|
|
|
|
|
|
|
|
// BlocProvider.of<PlotDetailBloc>(context).add( |
|
|
|
|
|
// OnUpdate<Activities>( |
|
|
|
|
|
// currentItems: updatedItems, |
|
|
|
|
|
// currentPage: currentPage, |
|
|
|
|
|
// hasReachedMax: currentReachedMax)); |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
print(e.toString()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
)); |
|
|
} else if (item.activityTypeName == "ACTIVE_TYPE_STATUS_CROP") { |
|
|
} else if (item.activityTypeName == "ACTIVE_TYPE_STATUS_CROP") { |
|
|
Get.to(EditActionCropStatusScreen( |
|
|
Get.to(EditActionCropStatusScreen( |
|
|
cropId: item.cropId, |
|
|
cropId: item.cropId, |
|
|
|
|
|
|
|
|
isEdit: true, |
|
|
isEdit: true, |
|
|
)); |
|
|
)); |
|
|
} else { |
|
|
} else { |
|
|
//TODO: Check other types |
|
|
|
|
|
Get.to(EditActionOtherScreen( |
|
|
Get.to(EditActionOtherScreen( |
|
|
cropId: item.cropId, |
|
|
cropId: item.cropId, |
|
|
activityId: item.id, |
|
|
activityId: item.id, |
|
|
|
|
|
|
|
|
this.listScreen = listScreen; |
|
|
this.listScreen = listScreen; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
class ChangeToRefreshLists extends GetxController { |
|
|
|
|
|
List<Activities> currentItems; |
|
|
|
|
|
int currentPage; |
|
|
|
|
|
bool currentReachedMax; |
|
|
|
|
|
|
|
|
|
|
|
void initValue() { |
|
|
|
|
|
currentItems = List<Activities>(); |
|
|
|
|
|
currentPage = 0; |
|
|
|
|
|
currentReachedMax = true; |
|
|
|
|
|
update(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void updateValue(List<Activities> updateItems, int page, bool reachedMax) { |
|
|
|
|
|
currentItems = updateItems; |
|
|
|
|
|
currentPage = page; |
|
|
|
|
|
currentReachedMax = reachedMax; |
|
|
|
|
|
update(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|