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 a75000c3..eabf3e37 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -11,15 +11,18 @@ class VehicleHistoryScreen extends StatefulWidget { } class _VehicleHistoryScreenState extends State - with Remotable { + with Pageable { final apiCall = PhpGroup.getVehiclesByProperty; + int count = 0; + final PagingController _pagingController = + PagingController(firstPageKey: 1); @override void initState() { super.initState(); _pagingController.addPageRequestListener( - (dynamic pageKey) => _fetch( - hasData: () async { + (dynamic pageKey) => fetchPage( + dataProvider: () async { final newItems = await apiCall.call(pageKey.toString()); if (newItems.jsonBody == null) return (false, null); final List vehicles = @@ -31,27 +34,19 @@ class _VehicleHistoryScreenState extends State }); return (vehicles.isNotEmpty, vehicles); }, - onNotHas: () { - _showNoMoreDataSnackBar(context); - setState(() { - // _hasData = false; - // _loading = false; - }); + onDataUnavailable: () { + setState(() {}); + showNoMoreDataSnackBar(context); }, - onHas: (vehicles) { - setState(() { - // _loading = false; - }); + onDataAvailable: (vehicles) { + setState(() {}); _pagingController.appendLastPage(vehicles); }, - onError: (e, s) { + onFetchError: (e, s) { DialogUtil.errorDefault(context); LogUtil.requestAPIFailed( "proccessRequest.php", "", "Consulta de Veículo", e, s); - setState(() { - // _hasData = false; - // _loading = false; - }); + setState(() {}); }, ), ); @@ -92,7 +87,7 @@ class _VehicleHistoryScreenState extends State return Column( children: [ _buildHeader(context), - _buildBody(), + _buildBody(context), ], ); } @@ -117,36 +112,23 @@ class _VehicleHistoryScreenState extends State ); } - Expanded _buildBody() { + Expanded _buildBody(BuildContext context) { final noDataFound = FFLocalizations.of(context).getVariableText( ptText: "Nenhum veículo encontrado!", enText: "No vehicle found", ); - return Expanded( - child: RefreshIndicator( - onRefresh: () async => _pagingController.refresh(), - child: PagedListView( - pagingController: _pagingController, - builderDelegate: PagedChildBuilderDelegate( - animateTransitions: true, - itemBuilder: (context, item, index) => - _generateItems(context, index, item), - // noMoreItemsIndicatorBuilder: , - newPageProgressIndicatorBuilder: (context) => - _buildLoadingIndicator(context), - firstPageProgressIndicatorBuilder: (context) => - _buildLoadingIndicator(context), - noItemsFoundIndicatorBuilder: (context) => - _buildNoDataFound(context, noDataFound), - firstPageErrorIndicatorBuilder: (context) => const Placeholder(), - newPageErrorIndicatorBuilder: (context) => const Placeholder(), - ), - ), - ), + return buildPaginatedListView( + noDataFound, + _pagingController, + _generateItems, ); } - Widget _generateItems(BuildContext context, int index, dynamic item) { + Widget _generateItems( + BuildContext context, + dynamic item, + int index, + ) { log('item: $item'); final bool? isOwner = item['isOwnerVehicle']; final IconData iconData = @@ -249,69 +231,3 @@ class _VehicleHistoryScreenState extends State } } } - -mixin Remotable on State { - final PagingController _pagingController = - PagingController(firstPageKey: 1); - - double offset = 0.0; - // bool _hasData = true; - // bool _loading = true; - int count = 0; - - Future _fetch({ - required Future<(bool, dynamic)> Function() hasData, - required void Function(dynamic) onHas, - required void Function() onNotHas, - required void Function(Object, StackTrace) onError, - }) async { - // if (!_hasData || !_loading) return; - try { - final (bool, dynamic) data = await hasData(); - if (data.$1) - onHas(data.$2); - else - onNotHas(); - } catch (e, s) { - onError(e, s); - } - } - - void _showNoMoreDataSnackBar(BuildContext context) { - final message = FFLocalizations.of(context).getVariableText( - ptText: "Não há mais dados.", - enText: "No more data.", - ); - - showSnackbar(context, message, true); - } - - Widget _buildNoDataFound(BuildContext context, String title) { - final headerFontSize = LimitedFontSizeUtil.getHeaderFontSize(context); - // final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context); - return Expanded( - child: Center( - child: Text( - title, - style: TextStyle( - fontFamily: 'Nunito', - fontSize: headerFontSize, - ), - ), - ), - ); - } - - Widget _buildLoadingIndicator(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(vertical: 15), - child: Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - FlutterFlowTheme.of(context).primary, - ), - ), - ), - ); - } -} diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index 4a01ca63..eafe8305 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -13,6 +13,7 @@ import 'package:hub/features/module/index.dart'; import 'package:hub/flutter_flow/index.dart'; import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart'; import 'package:hub/shared/extensions/index.dart'; +import 'package:hub/shared/mixins/pageable_mixin.dart'; import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/license_util.dart'; import 'package:hub/shared/utils/limited_text_size.dart'; diff --git a/lib/shared/mixins/pageable_mixin.dart b/lib/shared/mixins/pageable_mixin.dart new file mode 100644 index 00000000..e2cf1493 --- /dev/null +++ b/lib/shared/mixins/pageable_mixin.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:hub/flutter_flow/index.dart'; +import 'package:hub/shared/utils/limited_text_size.dart'; +import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; + +extension PagedListViewExtension + on PagedSliverList {} + +mixin Pageable on State { + Expanded buildPaginatedListView( + String noDataFound, + PagingController pg, + Widget Function(BuildContext, Y, int) itemBuilder) { + final theme = FlutterFlowTheme.of(context); + + return Expanded( + child: RefreshIndicator( + backgroundColor: theme.primaryBackground, + color: theme.primary, + onRefresh: () async => pg.refresh(), + child: PagedListView( + pagingController: pg, + builderDelegate: PagedChildBuilderDelegate( + animateTransitions: true, + + itemBuilder: (context, item, index) => + itemBuilder(context, item, index), + // noMoreItemsIndicatorBuilder: , + newPageProgressIndicatorBuilder: (context) => + buildLoadingIndicator(context), + firstPageProgressIndicatorBuilder: (context) => + buildLoadingIndicator(context), + noItemsFoundIndicatorBuilder: (context) => + buildNoDataFound(context, noDataFound), + firstPageErrorIndicatorBuilder: (context) => const Placeholder(), + newPageErrorIndicatorBuilder: (context) => const Placeholder(), + ), + ), + ), + ); + } + + Future fetchPage({ + required Future<(bool, dynamic)> Function() dataProvider, + required void Function(dynamic data) onDataAvailable, + required void Function() onDataUnavailable, + required void Function(Object error, StackTrace stackTrace) onFetchError, + }) async { + try { + final (bool isDataAvailable, dynamic data) = await dataProvider(); + if (isDataAvailable) { + onDataAvailable(data); + } else { + onDataUnavailable(); + } + } catch (error, stackTrace) { + onFetchError(error, stackTrace); + } + } + + void showNoMoreDataSnackBar(BuildContext context) { + final message = FFLocalizations.of(context).getVariableText( + ptText: "Não há mais dados.", + enText: "No more data.", + ); + + showSnackbar(context, message, true); + } + + Widget buildNoDataFound(BuildContext context, String title) { + final headerFontSize = LimitedFontSizeUtil.getHeaderFontSize(context); + // final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context); + return Expanded( + child: Center( + child: Text( + title, + style: TextStyle( + fontFamily: 'Nunito', + fontSize: headerFontSize, + ), + ), + ), + ); + } + + Widget buildLoadingIndicator(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + FlutterFlowTheme.of(context).primary, + ), + ), + ), + ); + } +}