Browse Source

show environment parameter

master
daivph 5 years ago
parent
commit
5611ddeff3
12 changed files with 325 additions and 5 deletions
  1. +1
    -1
      ios/Flutter/.last_build_id
  2. +36
    -0
      lib/custom_model/EnvironmentParameter.dart
  3. +7
    -0
      lib/data/api/rest_client.dart
  4. +23
    -0
      lib/data/api/rest_client.g.dart
  5. +8
    -0
      lib/data/repository/repository.dart
  6. +0
    -1
      lib/presentation/screens/plot/bloc/plot_bloc.dart
  7. +1
    -1
      lib/presentation/screens/plot/sc_plot.dart
  8. +67
    -0
      lib/presentation/screens/plot_detail/bloc/plot_parameter_bloc.dart
  9. +18
    -0
      lib/presentation/screens/plot_detail/bloc/plot_parameter_event.dart
  10. +35
    -0
      lib/presentation/screens/plot_detail/bloc/plot_parameter_state.dart
  11. +3
    -1
      lib/presentation/screens/plot_detail/sc_plot_detail.dart
  12. +126
    -1
      lib/presentation/screens/plot_detail/sc_plot_parameter.dart

+ 1
- 1
ios/Flutter/.last_build_id View File

40af80373277a16a0592f58ccbdc7f07
eb141365fb69a4e0decadd2584d53516

+ 36
- 0
lib/custom_model/EnvironmentParameter.dart View File

class EnvironmentParameter {
int id;
String name;
num index;
int activityId;
String executeDate;
bool status;

EnvironmentParameter(
{this.id,
this.name,
this.index,
this.activityId,
this.executeDate,
this.status});

EnvironmentParameter.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
index = json['index'];
activityId = json['activityId'];
executeDate = json['executeDate'];
status = json['status'];
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['index'] = this.index;
data['activityId'] = this.activityId;
data['executeDate'] = this.executeDate;
data['status'] = this.status;
return data;
}
}

+ 7
- 0
lib/data/api/rest_client.dart View File

import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:farm_tpf/custom_model/CropPlot.dart'; import 'package:farm_tpf/custom_model/CropPlot.dart';
import 'package:farm_tpf/custom_model/Device.dart'; import 'package:farm_tpf/custom_model/Device.dart';
import 'package:farm_tpf/custom_model/EnvironmentParameter.dart';
import 'package:farm_tpf/custom_model/Harvest.dart'; import 'package:farm_tpf/custom_model/Harvest.dart';
import 'package:farm_tpf/custom_model/WaterType.dart'; import 'package:farm_tpf/custom_model/WaterType.dart';
import 'package:farm_tpf/custom_model/account.dart'; import 'package:farm_tpf/custom_model/account.dart';
//Device //Device
@GET("/api/listDeviceOfUserCustomers") @GET("/api/listDeviceOfUserCustomers")
Future<List<Device>> getDevices(); Future<List<Device>> getDevices();
//Get environment parameter
@GET("/api/list-environment-updates-display/{cropId}?page={page}&size={size}")
Future<List<EnvironmentParameter>> getEnvironmentParameters(
@Path() int cropId,
{@Path() int page = 0,
@Path() int size = 20});
} }

+ 23
- 0
lib/data/api/rest_client.g.dart View File

return value; return value;
} }


@override
getEnvironmentParameters(cropId, {page = 0, size = 20}) async {
ArgumentError.checkNotNull(cropId, 'cropId');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final Response<List<dynamic>> _result = await _dio.request(
'/api/list-environment-updates-display/$cropId?page=$page&size=$size',
queryParameters: queryParameters,
options: RequestOptions(
method: 'GET',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) =>
EnvironmentParameter.fromJson(i as Map<String, dynamic>))
.toList();
return value;
}

RequestOptions newRequestOptions(Options options) { RequestOptions newRequestOptions(Options options) {
if (options is RequestOptions) { if (options is RequestOptions) {
return options; return options;

+ 8
- 0
lib/data/repository/repository.dart View File

import 'package:dio_http_cache/dio_http_cache.dart'; import 'package:dio_http_cache/dio_http_cache.dart';
import 'package:farm_tpf/custom_model/CropPlot.dart'; import 'package:farm_tpf/custom_model/CropPlot.dart';
import 'package:farm_tpf/custom_model/Device.dart'; import 'package:farm_tpf/custom_model/Device.dart';
import 'package:farm_tpf/custom_model/EnvironmentParameter.dart';
import 'package:farm_tpf/custom_model/Harvest.dart'; import 'package:farm_tpf/custom_model/Harvest.dart';
import 'package:farm_tpf/custom_model/WaterType.dart'; import 'package:farm_tpf/custom_model/WaterType.dart';
import 'package:farm_tpf/custom_model/user.dart'; import 'package:farm_tpf/custom_model/user.dart';
final client = RestClient(dio); final client = RestClient(dio);
return client.getDevices(); return client.getDevices();
} }

//Environment Parameter
Future<List<EnvironmentParameter>> getEnvironmentParameters(
{@required int cropId, int page, int size}) {
final client = RestClient(dio);
return client.getEnvironmentParameters(cropId, page: page, size: size);
}
} }

+ 0
- 1
lib/presentation/screens/plot/bloc/plot_bloc.dart View File

if (state is PlotSuccess) { if (state is PlotSuccess) {
final currentState = state as PlotSuccess; final currentState = state as PlotSuccess;
int page = currentState.page + 1; int page = currentState.page + 1;
yield PlotLoading();
final response = final response =
await repository.getPlots(page: page, size: pageSize); await repository.getPlots(page: page, size: pageSize);
yield response.isEmpty yield response.isEmpty

+ 1
- 1
lib/presentation/screens/plot/sc_plot.dart View File

MaterialPageRoute( MaterialPageRoute(
builder: (BuildContext context) => PlotDetailScreen( builder: (BuildContext context) => PlotDetailScreen(
cropId: item.id, cropId: item.id,
initialIndex: 1,
initialIndex: 0,
))); )));
}); });
} }

+ 67
- 0
lib/presentation/screens/plot_detail/bloc/plot_parameter_bloc.dart View File

import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:farm_tpf/data/api/app_exception.dart';
import 'package:farm_tpf/data/repository/repository.dart';
import 'package:meta/meta.dart';

part 'plot_parameter_event.dart';
part 'plot_parameter_state.dart';

class PlotParameterBloc extends Bloc<PlotParameterEvent, PlotParameterState> {
final Repository repository;
PlotParameterBloc({@required this.repository})
: super(PlotParameterInitial());
static int pageSize = 20;

@override
Stream<PlotParameterState> mapEventToState(
PlotParameterEvent event,
) async* {
if (event is DataFetched &&
!(state is PlotParameterSuccess &&
(state as PlotParameterSuccess).hasReachedMax)) {
try {
if (state is PlotParameterInitial) {
yield PlotParameterLoading();
final response = await repository.getEnvironmentParameters(
cropId: event.cropId, page: 0, size: pageSize);
yield PlotParameterSuccess(
items: response,
page: 0,
hasReachedMax: response.length < pageSize ? true : false);
}
//TODO: check paging api
// if (state is PlotParameterSuccess) {
// final currentState = state as PlotParameterSuccess;
// int page = currentState.page + 1;
// final response = await repository.getEnvironmentParameters(
// cropId: event.cropId, page: page, size: pageSize);
// yield response.isEmpty
// ? currentState.copyWith(hasReachedMax: true)
// : PlotParameterSuccess(
// items: currentState.items + response,
// page: currentState.page + 1,
// hasReachedMax: false);
// }
} catch (e) {
var errorString = AppException.handleError(e);
yield PlotParameterFailure(errorString: errorString);
}
}
if (event is OnRefresh) {
try {
yield PlotParameterLoading();
final response = await repository.getEnvironmentParameters(
cropId: event.cropId, page: 0, size: pageSize);
yield PlotParameterSuccess(
items: response,
page: 0,
hasReachedMax: response.length < pageSize ? true : false);
} catch (e) {
yield PlotParameterFailure(errorString: AppException.handleError(e));
}
}
}
}

+ 18
- 0
lib/presentation/screens/plot_detail/bloc/plot_parameter_event.dart View File

part of 'plot_parameter_bloc.dart';

abstract class PlotParameterEvent extends Equatable {
const PlotParameterEvent();

@override
List<Object> get props => [];
}

class DataFetched extends PlotParameterEvent {
final int cropId;
DataFetched({@required this.cropId});
}

class OnRefresh extends PlotParameterEvent {
final int cropId;
OnRefresh({@required this.cropId});
}

+ 35
- 0
lib/presentation/screens/plot_detail/bloc/plot_parameter_state.dart View File

part of 'plot_parameter_bloc.dart';

abstract class PlotParameterState extends Equatable {
const PlotParameterState();

@override
List<Object> get props => [];
}

class PlotParameterInitial extends PlotParameterState {}

class PlotParameterLoading extends PlotParameterState {}

class PlotParameterFailure extends PlotParameterState {
final String errorString;
PlotParameterFailure({@required this.errorString});
}

class PlotParameterSuccess<T> extends PlotParameterState {
final List<T> items;
final int page;
final bool hasReachedMax;

const PlotParameterSuccess({this.items, this.page, this.hasReachedMax});

PlotParameterSuccess copyWith({List<T> items, int page, bool hasReachedMax}) {
return PlotParameterSuccess(
items: items ?? this.items,
page: page ?? this.page,
hasReachedMax: hasReachedMax ?? this.hasReachedMax);
}

@override
List<Object> get props => [items, hasReachedMax];
}

+ 3
- 1
lib/presentation/screens/plot_detail/sc_plot_detail.dart View File

backgroundColor: COLOR_CONST.ITEM_BG, backgroundColor: COLOR_CONST.ITEM_BG,
body: TabBarView( body: TabBarView(
children: [ children: [
PlotParameterScreen(),
PlotParameterScreen(
cropId: widget.cropId,
),
PlotActionScreen( PlotActionScreen(
cropId: widget.cropId, cropId: widget.cropId,
cropCode: widget.cropCode, cropCode: widget.cropCode,

+ 126
- 1
lib/presentation/screens/plot_detail/sc_plot_parameter.dart View File

import 'package:farm_tpf/custom_model/EnvironmentParameter.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/utils/const_string.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:farm_tpf/utils/formatter.dart';

import 'bloc/plot_parameter_bloc.dart';


class PlotParameterScreen extends StatefulWidget { class PlotParameterScreen extends StatefulWidget {
final int cropId;
PlotParameterScreen({@required this.cropId});
@override @override
_PlotParameterScreenState createState() => _PlotParameterScreenState(); _PlotParameterScreenState createState() => _PlotParameterScreenState();
} }
class _PlotParameterScreenState extends State<PlotParameterScreen> { class _PlotParameterScreenState extends State<PlotParameterScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container();
return BlocProvider(
create: (context) => PlotParameterBloc(repository: Repository())
..add(DataFetched(cropId: widget.cropId)),
child: HoldInfinityWidget(
cropId: widget.cropId,
),
);
}
}

class HoldInfinityWidget extends StatelessWidget {
final int cropId;
HoldInfinityWidget({@required this.cropId});
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: InfinityView(
cropId: cropId,
));
}
}

class InfinityView extends StatefulWidget {
final int cropId;
InfinityView({@required this.cropId});
@override
_InfinityViewState createState() => _InfinityViewState();
}

class _InfinityViewState extends State<InfinityView> {
final _scrollController = ScrollController();
final _scrollThreshold = 250.0;
PlotParameterBloc _plotParameterBloc;

@override
void initState() {
_scrollController.addListener(() {
final maxScroll = _scrollController.position.maxScrollExtent;
final currentScroll = _scrollController.position.pixels;
if (maxScroll - currentScroll < _scrollThreshold) {
_plotParameterBloc.add(DataFetched(cropId: widget.cropId));
}
});
_plotParameterBloc = BlocProvider.of<PlotParameterBloc>(context);
super.initState();
}

@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(child: BlocBuilder<PlotParameterBloc, PlotParameterState>(
builder: (context, state) {
if (state is PlotParameterFailure) {
return Center(child: Text(state.errorString));
}
if (state is PlotParameterSuccess) {
if (state.items.isEmpty) {
return Center(child: Text(label_list_empty));
}
return RefreshIndicator(
child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return index >= state.items.length
? BottomLoader()
: ItemInfinityWidget(item: state.items[index]);
},
itemCount: state.hasReachedMax
? state.items.length
: state.items.length + 1,
controller: _scrollController,
),
onRefresh: () async {
_plotParameterBloc.add(OnRefresh(cropId: widget.cropId));
});
}
return Center(
child: LoadingListPage(),
);
},
))
],
);
}

@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
}

class ItemInfinityWidget extends StatelessWidget {
final EnvironmentParameter item;

const ItemInfinityWidget({Key key, @required this.item}) : super(key: key);

@override
Widget build(BuildContext context) {
return Card(
child: ListTile(
title: Text(
"${item.name ?? ''}",
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(
item.index.formatNumtoStringDecimal(),
style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
),
trailing: Text(item.executeDate.format_DDMMYY_HHmm()),
),
);
} }
} }

Loading…
Cancel
Save