WIP - paginacao
This commit is contained in:
parent
b2df549066
commit
16f43bbab8
|
@ -6,24 +6,19 @@ part of 'vehicles_on_the_property.dart';
|
||||||
class VehicleHistoryScreen extends StatefulWidget {
|
class VehicleHistoryScreen extends StatefulWidget {
|
||||||
VehicleHistoryScreen(this.model, {super.key});
|
VehicleHistoryScreen(this.model, {super.key});
|
||||||
late VehicleModel model;
|
late VehicleModel model;
|
||||||
late Future<void> _future;
|
|
||||||
List<dynamic> _wrap = [];
|
|
||||||
int _pageNumber = 1;
|
|
||||||
bool _hasData = false;
|
|
||||||
bool _loading = false;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<VehicleHistoryScreen> createState() => _VehicleHistoryScreenState();
|
State<VehicleHistoryScreen> createState() => _VehicleHistoryScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
||||||
with _FetchingMixin, _ScrollControllerMixin, _CardItemMixin {
|
with Remotable {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_initializeScrollController();
|
_initializeScrollController();
|
||||||
widget._future = _fetch();
|
_future = _fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -37,13 +32,13 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (widget._hasData == false &&
|
if (_hasData == false &&
|
||||||
widget._pageNumber <= 1 &&
|
_pageNumber <= 1 &&
|
||||||
widget._loading == false)
|
_loading == false)
|
||||||
_buildNoDataFound(context, limitedHeaderTextSize)
|
_buildNoDataFound(context, limitedHeaderTextSize)
|
||||||
else if (widget._hasData == true || widget._pageNumber >= 1)
|
else if (_hasData == true || _pageNumber >= 1)
|
||||||
_buildVehicleList(context, limitedBodyTextSize),
|
_buildHistoryList(context, limitedBodyTextSize),
|
||||||
if (widget._hasData == true && widget._loading == true)
|
if (_hasData == true && _loading == true)
|
||||||
_buildLoadingIndicator(context),
|
_buildLoadingIndicator(context),
|
||||||
].addToStart(const SizedBox(height: 0)),
|
].addToStart(const SizedBox(height: 0)),
|
||||||
);
|
);
|
||||||
|
@ -72,10 +67,10 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildVehicleList(BuildContext context, double limitedBodyTextSize) {
|
Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: FutureBuilder<void>(
|
child: FutureBuilder<List<Widget?>>(
|
||||||
future: widget._future,
|
future: _future,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
return Center(child: CircularProgressIndicator());
|
return Center(child: CircularProgressIndicator());
|
||||||
|
@ -86,13 +81,13 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const BouncingScrollPhysics(),
|
physics: const BouncingScrollPhysics(),
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
itemCount: widget._wrap.length + 1,
|
itemCount: _wrap.length + 1,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
return _buildHeader(context, limitedBodyTextSize);
|
return _buildHeader(context, limitedBodyTextSize);
|
||||||
} else {
|
} else {
|
||||||
Map<String, dynamic> item = widget._wrap[index - 1];
|
Widget? item = _wrap[index - 1];
|
||||||
return _buildVehicleItem(context, item);
|
return _wrap[index - 1] ?? SizedBox.shrink();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -102,19 +97,6 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildVehicleItem(BuildContext context, Map<String, dynamic> item) {
|
|
||||||
return FutureBuilder<Widget>(
|
|
||||||
future: _item(context, item),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
|
||||||
return snapshot.data ?? Container();
|
|
||||||
} else {
|
|
||||||
return Center(child: CircularProgressIndicator());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildHeader(BuildContext context, double limitedBodyTextSize) {
|
Widget _buildHeader(BuildContext context, double limitedBodyTextSize) {
|
||||||
log('amountRegister: ${widget.model.amountRegister}');
|
log('amountRegister: ${widget.model.amountRegister}');
|
||||||
return Padding(
|
return Padding(
|
||||||
|
@ -147,48 +129,36 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mixin for Scroll Controller
|
|
||||||
mixin _ScrollControllerMixin on _FetchingMixin {
|
|
||||||
late ScrollController _scrollController;
|
|
||||||
|
|
||||||
void _initializeScrollController() {
|
|
||||||
_scrollController = ScrollController()
|
|
||||||
..addListener(() {
|
|
||||||
if (_scrollController.position.atEdge &&
|
|
||||||
_scrollController.position.pixels != 0) {
|
|
||||||
_loadMore();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _loadMore() {
|
|
||||||
if (widget._hasData == true) {
|
|
||||||
widget._pageNumber++;
|
|
||||||
widget._future = _fetch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mixin for Fetch Visits
|
// Mixin for Fetch Visits
|
||||||
mixin _FetchingMixin on State<VehicleHistoryScreen> {
|
mixin Remotable on State<VehicleHistoryScreen> {
|
||||||
Future<ApiCallResponse?> _fetch() async {
|
late Future<List<Widget?>> _future;
|
||||||
|
List<Widget?> _wrap = [];
|
||||||
|
int _pageNumber = 1;
|
||||||
|
bool _hasData = true;
|
||||||
|
bool _loading = true;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
|
||||||
|
Future<List<Widget?>> _fetch() async {
|
||||||
|
if (!widget._hasData || !widget._loading) return [];
|
||||||
|
|
||||||
|
setState(() => widget._loading = true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setState(() => widget._loading = true);
|
var response = await PhpGroup.getVehiclesByProperty.call(widget._pageNumber.toString());
|
||||||
|
final List<dynamic> vehicles = response.jsonBody['vehicles'] as List<dynamic>? ?? [];
|
||||||
var response = await PhpGroup.getVehiclesByProperty
|
|
||||||
.call(widget._pageNumber.toString());
|
|
||||||
|
|
||||||
final List<dynamic> vehicles = response.jsonBody['vehicles'] ?? [];
|
|
||||||
safeSetState(() => widget.count = response.jsonBody['total_rows'] ?? 0);
|
safeSetState(() => widget.count = response.jsonBody['total_rows'] ?? 0);
|
||||||
|
|
||||||
if (vehicles.isNotEmpty) {
|
if (vehicles.isNotEmpty) {
|
||||||
setState(() {
|
setState(() {
|
||||||
widget._wrap.addAll(vehicles);
|
|
||||||
widget._hasData = true;
|
widget._hasData = true;
|
||||||
widget._loading = false;
|
widget._loading = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
|
||||||
|
return _generateItems(context, vehicles);
|
||||||
}
|
}
|
||||||
|
|
||||||
_showNoMoreDataSnackBar(context);
|
_showNoMoreDataSnackBar(context);
|
||||||
|
@ -198,17 +168,16 @@ mixin _FetchingMixin on State<VehicleHistoryScreen> {
|
||||||
widget._loading = false;
|
widget._loading = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
return null;
|
return [];
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
DialogUtil.errorDefault(context);
|
DialogUtil.errorDefault(context);
|
||||||
LogUtil.requestAPIFailed(
|
LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículo", e, s);
|
||||||
"proccessRequest.php", "", "Consulta de Veículo", e, s);
|
|
||||||
setState(() {
|
setState(() {
|
||||||
widget._hasData = false;
|
widget._hasData = false;
|
||||||
widget._loading = false;
|
widget._loading = false;
|
||||||
});
|
});
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showNoMoreDataSnackBar(BuildContext context) {
|
void _showNoMoreDataSnackBar(BuildContext context) {
|
||||||
|
@ -219,47 +188,43 @@ mixin _FetchingMixin on State<VehicleHistoryScreen> {
|
||||||
|
|
||||||
showSnackbar(context, message, true);
|
showSnackbar(context, message, true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Mixin for Card Item
|
Future<List<Widget?>> _generateItems(BuildContext context, List<dynamic> uItem) async {
|
||||||
mixin _CardItemMixin on _FetchingMixin {
|
if (!widget._hasData) return [];
|
||||||
Future<Widget> _item(BuildContext context, Map<String, dynamic> uItem) async {
|
|
||||||
final bool? isOwner = uItem['isOwnerVehicle'];
|
|
||||||
final IconData? iconData = isOwner == null
|
|
||||||
? null
|
|
||||||
: isOwner == true
|
|
||||||
? Symbols.no_crash
|
|
||||||
: Symbols.directions_car;
|
|
||||||
final FreCardIcon? cardIcon = isOwner != null
|
|
||||||
? FreCardIcon(
|
|
||||||
height: 50,
|
|
||||||
width: 100,
|
|
||||||
icon: Icon(iconData, size: 80, opticalSize: 10))
|
|
||||||
: null;
|
|
||||||
|
|
||||||
final String? tag = uItem['tag'];
|
List<Widget?> items = [];
|
||||||
final bool containTag = tag.isNotNullAndEmpty;
|
|
||||||
final Map<String, String> labelsHashMap =
|
|
||||||
_generateLabelsHashMap(context, uItem, tag, containTag);
|
|
||||||
|
|
||||||
final statusHashMapList = await _generateStatusHashMapList(uItem);
|
for (var uItem in uItem) {
|
||||||
|
final bool? isOwner = uItem['isOwnerVehicle'];
|
||||||
|
final IconData? iconData = isOwner == true ? Symbols.no_crash : Symbols.directions_car;
|
||||||
|
final FreCardIcon? cardIcon = isOwner != null
|
||||||
|
? FreCardIcon(height: 50, width: 100, icon: Icon(iconData, size: 80, opticalSize: 10))
|
||||||
|
: null;
|
||||||
|
|
||||||
Future<void> onTapCardItemAction() async {
|
final String? tag = uItem['tag'];
|
||||||
await _handleCardItemTap(context, cardIcon, uItem);
|
final bool containTag = tag.isNotNullAndEmpty;
|
||||||
|
final Map<String, String> labelsHashMap = _generateLabelsHashMap(context, uItem, tag, containTag);
|
||||||
|
|
||||||
|
final statusHashMapList = await _generateStatusHashMapList(uItem);
|
||||||
|
|
||||||
|
Future<void> onTapCardItemAction() async {
|
||||||
|
await _handleCardItemTap(context, cardIcon, uItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
final statusLinkedHashMap = statusHashMapList.map((map) => LinkedHashMap<String, Color>.from(map)).toList();
|
||||||
|
final length = statusLinkedHashMap.expand((e) => [e.length]);
|
||||||
|
|
||||||
|
items.add(CardItemTemplateComponentWidget(
|
||||||
|
icon: cardIcon,
|
||||||
|
labelsHashMap: labelsHashMap,
|
||||||
|
statusHashMap: statusHashMapList,
|
||||||
|
onTapCardItemAction: onTapCardItemAction,
|
||||||
|
itemWidthFactor: length == 1 ? 0.25 : 0.50,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
final statusLinkedHashMap = statusHashMapList
|
widget._wrap.addAll(items);
|
||||||
.map((map) => LinkedHashMap<String, Color>.from(map))
|
return items;
|
||||||
.toList();
|
|
||||||
final length = statusLinkedHashMap.expand((e) => [e.length]);
|
|
||||||
|
|
||||||
return CardItemTemplateComponentWidget(
|
|
||||||
icon: cardIcon,
|
|
||||||
labelsHashMap: labelsHashMap,
|
|
||||||
statusHashMap: statusHashMapList,
|
|
||||||
onTapCardItemAction: onTapCardItemAction,
|
|
||||||
itemWidthFactor: length == 1 ? 0.25 : 0.50,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> _generateLabelsHashMap(BuildContext context,
|
Map<String, String> _generateLabelsHashMap(BuildContext context,
|
||||||
|
@ -316,4 +281,26 @@ mixin _CardItemMixin on _FetchingMixin {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
late ScrollController _scrollController;
|
||||||
|
|
||||||
|
void _initializeScrollController() {
|
||||||
|
_scrollController = ScrollController()
|
||||||
|
..addListener(() {
|
||||||
|
print('ScrollController');
|
||||||
|
if(!widget._hasData) return;
|
||||||
|
if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent) {
|
||||||
|
print('ScrollController -> loadMore');
|
||||||
|
_loadMore();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadMore() {
|
||||||
|
if (widget._hasData) {
|
||||||
|
widget._pageNumber++;
|
||||||
|
widget._loading = true;
|
||||||
|
widget._future = _fetch();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue