From 16f43bbab8d4d866def321e0bdc3f8c0c538a4ae Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Thu, 6 Feb 2025 18:01:47 -0300 Subject: [PATCH] WIP - paginacao --- .../vehicle_history_screen.dart | 195 ++++++++---------- 1 file changed, 91 insertions(+), 104 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 773c4756..e20e6e36 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -6,24 +6,19 @@ part of 'vehicles_on_the_property.dart'; class VehicleHistoryScreen extends StatefulWidget { VehicleHistoryScreen(this.model, {super.key}); late VehicleModel model; - late Future _future; - List _wrap = []; - int _pageNumber = 1; - bool _hasData = false; - bool _loading = false; - int count = 0; + @override State createState() => _VehicleHistoryScreenState(); } class _VehicleHistoryScreenState extends State - with _FetchingMixin, _ScrollControllerMixin, _CardItemMixin { + with Remotable { @override void initState() { super.initState(); _initializeScrollController(); - widget._future = _fetch(); + _future = _fetch(); } @override @@ -37,13 +32,13 @@ class _VehicleHistoryScreenState extends State mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, children: [ - if (widget._hasData == false && - widget._pageNumber <= 1 && - widget._loading == false) + if (_hasData == false && + _pageNumber <= 1 && + _loading == false) _buildNoDataFound(context, limitedHeaderTextSize) - else if (widget._hasData == true || widget._pageNumber >= 1) - _buildVehicleList(context, limitedBodyTextSize), - if (widget._hasData == true && widget._loading == true) + else if (_hasData == true || _pageNumber >= 1) + _buildHistoryList(context, limitedBodyTextSize), + if (_hasData == true && _loading == true) _buildLoadingIndicator(context), ].addToStart(const SizedBox(height: 0)), ); @@ -72,10 +67,10 @@ class _VehicleHistoryScreenState extends State ); } - Widget _buildVehicleList(BuildContext context, double limitedBodyTextSize) { + Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) { return Expanded( - child: FutureBuilder( - future: widget._future, + child: FutureBuilder>( + future: _future, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); @@ -86,13 +81,13 @@ class _VehicleHistoryScreenState extends State shrinkWrap: true, physics: const BouncingScrollPhysics(), controller: _scrollController, - itemCount: widget._wrap.length + 1, + itemCount: _wrap.length + 1, itemBuilder: (context, index) { if (index == 0) { return _buildHeader(context, limitedBodyTextSize); } else { - Map item = widget._wrap[index - 1]; - return _buildVehicleItem(context, item); + Widget? item = _wrap[index - 1]; + return _wrap[index - 1] ?? SizedBox.shrink(); } }, ); @@ -102,19 +97,6 @@ class _VehicleHistoryScreenState extends State ); } - Widget _buildVehicleItem(BuildContext context, Map item) { - return FutureBuilder( - 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) { log('amountRegister: ${widget.model.amountRegister}'); return Padding( @@ -147,48 +129,36 @@ class _VehicleHistoryScreenState extends State } } -// 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 _FetchingMixin on State { - Future _fetch() async { +mixin Remotable on State { + late Future> _future; + List _wrap = []; + int _pageNumber = 1; + bool _hasData = true; + bool _loading = true; + int count = 0; + + + Future> _fetch() async { + if (!widget._hasData || !widget._loading) return []; + + setState(() => widget._loading = true); + try { - setState(() => widget._loading = true); - - var response = await PhpGroup.getVehiclesByProperty - .call(widget._pageNumber.toString()); - - final List vehicles = response.jsonBody['vehicles'] ?? []; + var response = await PhpGroup.getVehiclesByProperty.call(widget._pageNumber.toString()); + final List vehicles = response.jsonBody['vehicles'] as List? ?? []; safeSetState(() => widget.count = response.jsonBody['total_rows'] ?? 0); if (vehicles.isNotEmpty) { setState(() { - widget._wrap.addAll(vehicles); + widget._hasData = true; widget._loading = false; }); - return response; + + return _generateItems(context, vehicles); } _showNoMoreDataSnackBar(context); @@ -198,17 +168,16 @@ mixin _FetchingMixin on State { widget._loading = false; }); - return null; + return []; } catch (e, s) { DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - "proccessRequest.php", "", "Consulta de Veículo", e, s); + LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículo", e, s); setState(() { widget._hasData = false; widget._loading = false; }); + return []; } - return null; } void _showNoMoreDataSnackBar(BuildContext context) { @@ -219,47 +188,43 @@ mixin _FetchingMixin on State { showSnackbar(context, message, true); } -} -// Mixin for Card Item -mixin _CardItemMixin on _FetchingMixin { - Future _item(BuildContext context, Map 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; + Future> _generateItems(BuildContext context, List uItem) async { + if (!widget._hasData) return []; - final String? tag = uItem['tag']; - final bool containTag = tag.isNotNullAndEmpty; - final Map labelsHashMap = - _generateLabelsHashMap(context, uItem, tag, containTag); + List items = []; - 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 onTapCardItemAction() async { - await _handleCardItemTap(context, cardIcon, uItem); + final String? tag = uItem['tag']; + final bool containTag = tag.isNotNullAndEmpty; + final Map labelsHashMap = _generateLabelsHashMap(context, uItem, tag, containTag); + + final statusHashMapList = await _generateStatusHashMapList(uItem); + + Future onTapCardItemAction() async { + await _handleCardItemTap(context, cardIcon, uItem); + } + + final statusLinkedHashMap = statusHashMapList.map((map) => LinkedHashMap.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 - .map((map) => LinkedHashMap.from(map)) - .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, - ); + + widget._wrap.addAll(items); + return items; } Map _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(); + } + } }