add infinite_scroll_View
This commit is contained in:
parent
05b3a612ba
commit
b0e4e86391
|
@ -529,7 +529,7 @@ void setAppLanguage(BuildContext context, String language) =>
|
|||
void setDarkModeSetting(BuildContext context, ThemeMode themeMode) =>
|
||||
App.of(context).setThemeMode(themeMode);
|
||||
|
||||
void showSnackbar(
|
||||
void showSnackbarMessenger(
|
||||
BuildContext context,
|
||||
String message,
|
||||
bool error, {
|
||||
|
@ -573,6 +573,47 @@ void showSnackbar(
|
|||
);
|
||||
}
|
||||
|
||||
SnackBar showSnackbar(
|
||||
BuildContext context,
|
||||
String message,
|
||||
bool error, {
|
||||
bool loading = false,
|
||||
int duration = 4,
|
||||
}) {
|
||||
return SnackBar(
|
||||
content: Row(
|
||||
children: [
|
||||
if (loading)
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(end: 10.0),
|
||||
child: SizedBox(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(
|
||||
color: FlutterFlowTheme.of(context).info,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
message,
|
||||
style: TextStyle(
|
||||
color: FlutterFlowTheme.of(context).info,
|
||||
fontSize: LimitedFontSizeUtil.getBodyFontSize(context),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
duration: Duration(seconds: duration),
|
||||
backgroundColor: error
|
||||
? FlutterFlowTheme.of(context).error
|
||||
: FlutterFlowTheme.of(context).success,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void showAlertDialog(BuildContext context, String title, String content,
|
||||
Future<void> Function() action) {
|
||||
double limitedBodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
|
@ -785,5 +826,3 @@ double computeGradientAlignmentY(double evaluatedAngle) {
|
|||
}
|
||||
return double.parse(roundTo(y, 2));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
|
|||
)
|
||||
.then((message) {
|
||||
if (message != null || message != '') {
|
||||
showSnackbar(
|
||||
showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Successfully resolved visit',
|
||||
|
@ -308,7 +308,7 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
|
|||
false,
|
||||
);
|
||||
} else {
|
||||
showSnackbar(context, message, true);
|
||||
showSnackbarMessenger(context, message, true);
|
||||
}
|
||||
}).whenComplete(() {
|
||||
safeSetState(() {
|
||||
|
|
|
@ -474,7 +474,7 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
|||
context.pop(value);
|
||||
|
||||
if (value == false) {
|
||||
showSnackbar(
|
||||
showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Erro ao excluir pet',
|
||||
|
@ -483,7 +483,7 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
|||
true,
|
||||
);
|
||||
} else if (value == true) {
|
||||
showSnackbar(
|
||||
showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Success deleting pet',
|
||||
|
@ -494,7 +494,7 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
|||
}
|
||||
}).catchError((err, stack) {
|
||||
context.pop();
|
||||
showSnackbar(
|
||||
showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Error deleting pet',
|
||||
|
|
|
@ -472,7 +472,7 @@ class ScheduleCompleteVisitPageModel
|
|||
context.pop(value);
|
||||
|
||||
if (value == false) {
|
||||
showSnackbar(
|
||||
showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Error blocking visit',
|
||||
|
@ -481,7 +481,7 @@ class ScheduleCompleteVisitPageModel
|
|||
true,
|
||||
);
|
||||
} else if (value == true) {
|
||||
showSnackbar(
|
||||
showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Success canceling visit',
|
||||
|
@ -492,7 +492,7 @@ class ScheduleCompleteVisitPageModel
|
|||
}
|
||||
}).catchError((err, stack) {
|
||||
context.pop();
|
||||
showSnackbar(
|
||||
showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Error blocking visit',
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
part of 'vehicles_on_the_property.dart';
|
||||
|
||||
/// [VehicleHistoryScreen] is a StatefulWidget that displays a list of vehicles.
|
||||
|
||||
// ignore: must_be_immutable
|
||||
/// Widget que exibe o histórico de veículos na propriedade.
|
||||
class VehicleHistoryScreen extends StatefulWidget {
|
||||
final VehicleModel model;
|
||||
|
||||
VehicleHistoryScreen(this.model, {super.key});
|
||||
late VehicleModel model;
|
||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
final builderKey = GlobalKey();
|
||||
|
||||
@override
|
||||
State<VehicleHistoryScreen> createState() => _VehicleHistoryScreenState();
|
||||
|
@ -15,167 +12,268 @@ class VehicleHistoryScreen extends StatefulWidget {
|
|||
|
||||
class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
||||
with Remotable {
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_pagingController.dispose();
|
||||
}
|
||||
final apiCall = PhpGroup.getVehiclesByProperty;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initializeScrollController();
|
||||
_pagingController.addPageRequestListener(_fetch);
|
||||
_pagingController.addPageRequestListener(
|
||||
(dynamic pageKey) => _fetch(
|
||||
hasData: () async {
|
||||
final newItems = await apiCall.call(pageKey.toString());
|
||||
if (newItems.jsonBody == null) return (false, null);
|
||||
final List<dynamic> vehicles =
|
||||
(newItems.jsonBody['vehicles'] as List<dynamic>?) ?? [];
|
||||
_pagingController.nextPageKey = pageKey + 1;
|
||||
|
||||
safeSetState(() {
|
||||
count = newItems.jsonBody['total_rows'] ?? 0;
|
||||
});
|
||||
return (vehicles.isNotEmpty, vehicles);
|
||||
},
|
||||
onNotHas: () {
|
||||
_showNoMoreDataSnackBar(context);
|
||||
setState(() {
|
||||
// _hasData = false;
|
||||
// _loading = false;
|
||||
});
|
||||
},
|
||||
onHas: (vehicles) {
|
||||
setState(() {
|
||||
// _loading = false;
|
||||
});
|
||||
_pagingController.appendLastPage(vehicles);
|
||||
},
|
||||
onError: (e, s) {
|
||||
DialogUtil.errorDefault(context);
|
||||
LogUtil.requestAPIFailed(
|
||||
"proccessRequest.php", "", "Consulta de Veículo", e, s);
|
||||
setState(() {
|
||||
// _hasData = false;
|
||||
// _loading = false;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
_pagingController.addStatusListener(_showError);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pagingController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _showError(PagingStatus status) async {
|
||||
if (status == PagingStatus.subsequentPageError) {
|
||||
final message = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Something went wrong while fetching a new page.',
|
||||
ptText: 'Algo deu errado ao buscar uma nova página.',
|
||||
);
|
||||
final retry = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Retry',
|
||||
ptText: 'Recarregar',
|
||||
);
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message),
|
||||
action: SnackBarAction(
|
||||
label: retry,
|
||||
onPressed: () => _pagingController.retryLastFailedRequest(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
late final limitedHeaderTextSize =
|
||||
LimitedFontSizeUtil.getHeaderFontSize(context);
|
||||
late final double limitedBodyTextSize =
|
||||
LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
// if (_hasData == false &&
|
||||
// _pageNumber <= 1 &&
|
||||
// _loading == false)
|
||||
// _buildNoDataFound(context, limitedHeaderTextSize)
|
||||
// else if (_hasData == true || _pageNumber >= 1)
|
||||
_buildHistoryList(context, limitedBodyTextSize),
|
||||
// if (_hasData == true && _loading == true)
|
||||
// _buildLoadingIndicator(context),
|
||||
].addToStart(const SizedBox(height: 0)),
|
||||
_buildHeader(context),
|
||||
_buildBody(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildNoDataFound(BuildContext context, double limitedHeaderTextSize) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Center(
|
||||
child: Text(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Nenhum veículo encontrado!",
|
||||
enText: "No vehicle found",
|
||||
),
|
||||
style: TextStyle(
|
||||
fontFamily: 'Nunito',
|
||||
fontSize: limitedHeaderTextSize,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
Widget _buildHeader(BuildContext context) {
|
||||
final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
return SizedBox(
|
||||
height: 30,
|
||||
child: Center(
|
||||
child: Text(
|
||||
(widget.model.amountRegister == '0' ||
|
||||
widget.model.amountRegister == null)
|
||||
? ''
|
||||
: "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Veículos: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/$count",
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Nunito',
|
||||
fontSize: bodyFontSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) {
|
||||
Expanded _buildBody() {
|
||||
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<int, dynamic>(
|
||||
// separatorBuilder: (context, index) => const Divider(),
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate(
|
||||
builderDelegate: PagedChildBuilderDelegate<dynamic>(
|
||||
animateTransitions: true,
|
||||
itemBuilder: (context, item, index) =>
|
||||
_generateItems(context, index, item),
|
||||
firstPageErrorIndicatorBuilder: (context) => Placeholder(),
|
||||
newPageErrorIndicatorBuilder: (context) => Placeholder(),
|
||||
// noMoreItemsIndicatorBuilder: ,
|
||||
newPageProgressIndicatorBuilder: (context) =>
|
||||
_buildLoadingIndicator(context),
|
||||
firstPageProgressIndicatorBuilder: (context) =>
|
||||
_buildLoadingIndicator(context),
|
||||
noItemsFoundIndicatorBuilder: (context) =>
|
||||
_buildNoDataFound(context, noDataFound),
|
||||
firstPageErrorIndicatorBuilder: (context) => const Placeholder(),
|
||||
newPageErrorIndicatorBuilder: (context) => const Placeholder(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// ListView.builder(
|
||||
// shrinkWrap: true,
|
||||
// addAutomaticKeepAlives: true,
|
||||
// restorationId: '',
|
||||
// physics: const BouncingScrollPhysics(),
|
||||
// controller: _scrollController,
|
||||
// itemCount: _wrap.length,
|
||||
// itemBuilder: (context, index) => _generateItems(context, _wrap[index], index),
|
||||
Widget _generateItems(BuildContext context, int index, dynamic item) {
|
||||
log('item: $item');
|
||||
final bool? isOwner = item['isOwnerVehicle'];
|
||||
final IconData iconData =
|
||||
isOwner == true ? Symbols.garage : Symbols.directions_car;
|
||||
|
||||
// ),
|
||||
final FreCardIcon? cardIcon = isOwner != null
|
||||
? FreCardIcon(
|
||||
height: 50,
|
||||
width: 100,
|
||||
icon: Icon(iconData, size: 80, opticalSize: 10),
|
||||
)
|
||||
: null;
|
||||
|
||||
Widget _buildLoadingIndicator(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(top: 15, bottom: 15),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
FlutterFlowTheme.of(context).primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
final String? tag = item['tag'];
|
||||
final bool containTag = tag.isNotNullAndEmpty;
|
||||
final Map<String, String> labelsHashMap =
|
||||
_generateLabelsHashMap(context, item, tag, containTag);
|
||||
|
||||
final List<Map<String, Color>> statusHashMapList =
|
||||
_generateStatusHashMapList(item);
|
||||
|
||||
Future<void> onTapCardItemAction() async {
|
||||
await _handleCardItemTap(context, cardIcon, item);
|
||||
}
|
||||
|
||||
final statusLinkedHashMap = statusHashMapList
|
||||
.map((map) => LinkedHashMap<String, Color>.from(map))
|
||||
.toList();
|
||||
final length = statusLinkedHashMap.expand((e) => [e.length]);
|
||||
final double itemWidthFactor = length == 1 ? 0.25 : 0.50;
|
||||
|
||||
return CardItemTemplateComponentWidget(
|
||||
icon: cardIcon,
|
||||
labelsHashMap: labelsHashMap,
|
||||
statusHashMap: statusHashMapList,
|
||||
onTapCardItemAction: onTapCardItemAction,
|
||||
itemWidthFactor: itemWidthFactor,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, String> _generateLabelsHashMap(
|
||||
BuildContext context,
|
||||
Map<String, dynamic> item,
|
||||
String? tag,
|
||||
bool containTag,
|
||||
) {
|
||||
final localization = FFLocalizations.of(context);
|
||||
return {
|
||||
'${localization.getVariableText(ptText: "Placa", enText: "License Plate")}:':
|
||||
item['licensePlate'] ?? '',
|
||||
'${localization.getVariableText(ptText: "Modelo", enText: "Model")}:':
|
||||
item['model'] ?? '',
|
||||
'${localization.getVariableText(ptText: "Proprietário", enText: "Owner")}:':
|
||||
item['personName'] ?? '',
|
||||
if (containTag)
|
||||
'${localization.getVariableText(ptText: "Tag", enText: "Tag")}:':
|
||||
tag ?? '',
|
||||
};
|
||||
}
|
||||
|
||||
List<Map<String, Color>> _generateStatusHashMapList(
|
||||
Map<String, dynamic> item) {
|
||||
final statusHashMap = widget.model.generateStatusColorMap(item, false);
|
||||
return statusHashMap != null ? [statusHashMap] : [];
|
||||
}
|
||||
|
||||
Future<void> _handleCardItemTap(
|
||||
BuildContext context,
|
||||
FreCardIcon? cardIcon,
|
||||
Map<String, dynamic> item,
|
||||
) async {
|
||||
try {
|
||||
final dialogContent = widget.model.buildVehicleDetails(
|
||||
icon: cardIcon,
|
||||
item: item,
|
||||
context: context,
|
||||
model: widget.model,
|
||||
);
|
||||
|
||||
await showDialog(
|
||||
useSafeArea: true,
|
||||
context: context,
|
||||
builder: (context) => Dialog(
|
||||
alignment: Alignment.center,
|
||||
child: dialogContent,
|
||||
),
|
||||
).whenComplete(() {
|
||||
safeSetState(() {
|
||||
// _pagingController.refresh();
|
||||
});
|
||||
});
|
||||
} catch (e, s) {
|
||||
DialogUtil.errorDefault(context);
|
||||
LogUtil.requestAPIFailed(
|
||||
"proccessRequest.php", "", "Consulta de Veículos", e, s);
|
||||
safeSetState(() {
|
||||
// _hasData = false;
|
||||
// _loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mixin Remotable on State<VehicleHistoryScreen> {
|
||||
final PagingController<int, dynamic> _pagingController =
|
||||
PagingController<int, dynamic>(firstPageKey: 1);
|
||||
|
||||
// late ScrollController _scrollController;
|
||||
double offset = 0.0;
|
||||
List<dynamic> _wrap = [];
|
||||
int _pageNumber = 1;
|
||||
bool _hasData = true;
|
||||
bool _loading = true;
|
||||
// bool _hasData = true;
|
||||
// bool _loading = true;
|
||||
int count = 0;
|
||||
|
||||
Future<void> _fetch(dynamic pageKey) async {
|
||||
if (!_hasData || !_loading) return;
|
||||
print('hasHasData');
|
||||
// setState(() => _loading = true);
|
||||
Future<void> _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 {
|
||||
var newItems =
|
||||
await PhpGroup.getVehiclesByProperty.call(pageKey.toString());
|
||||
final bool isLastPage = newItems.jsonBody == null ||
|
||||
newItems.jsonBody == [] ||
|
||||
newItems.jsonBody == '';
|
||||
|
||||
if (newItems.jsonBody == null) {
|
||||
} else {
|
||||
final List<dynamic> vehicles =
|
||||
newItems.jsonBody['vehicles'] as List<dynamic>? ?? [];
|
||||
_pagingController.nextPageKey = pageKey + 1;
|
||||
|
||||
safeSetState(() => count = newItems.jsonBody['total_rows'] ?? 0);
|
||||
if (vehicles.isNotEmpty) {
|
||||
// setState(() {
|
||||
// _hasData = true;
|
||||
// _loading = false;
|
||||
// _wrap.addAll(vehicles);
|
||||
// });
|
||||
_pagingController.appendLastPage(vehicles);
|
||||
|
||||
return;
|
||||
}
|
||||
_showNoMoreDataSnackBar(context);
|
||||
setState(() {
|
||||
_hasData = false;
|
||||
_loading = false;
|
||||
});
|
||||
print('hasEmpty: ${_wrap.length}');
|
||||
return;
|
||||
}
|
||||
final (bool, dynamic) data = await hasData();
|
||||
if (data.$1)
|
||||
onHas(data.$2);
|
||||
else
|
||||
onNotHas();
|
||||
} catch (e, s) {
|
||||
DialogUtil.errorDefault(context);
|
||||
LogUtil.requestAPIFailed(
|
||||
"proccessRequest.php", "", "Consulta de Veículo", e, s);
|
||||
setState(() {
|
||||
_hasData = false;
|
||||
_loading = false;
|
||||
});
|
||||
print('hasError');
|
||||
return;
|
||||
onError(e, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,142 +286,32 @@ mixin Remotable on State<VehicleHistoryScreen> {
|
|||
showSnackbar(context, message, true);
|
||||
}
|
||||
|
||||
Widget _buildHeader(BuildContext context) {
|
||||
double limitedBodyTextSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
log('amountRegister: ${widget.model.amountRegister}');
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 30, top: 10),
|
||||
child: Text(
|
||||
(widget.model.amountRegister == '0' ||
|
||||
widget.model.amountRegister == null)
|
||||
? ''
|
||||
: "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Veículos: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/$count",
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Nunito',
|
||||
fontSize: limitedBodyTextSize,
|
||||
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 _generateItems(BuildContext context, int index, dynamic item) {
|
||||
log('item: $item');
|
||||
|
||||
// return Placeholder();
|
||||
|
||||
// if (index == 0) return _buildHeader(context);
|
||||
|
||||
final bool? isOwner = item['isOwnerVehicle'];
|
||||
final IconData? iconData =
|
||||
isOwner == true ? Symbols.garage : Symbols.directions_car;
|
||||
final FreCardIcon? cardIcon = isOwner != null
|
||||
? FreCardIcon(
|
||||
height: 50,
|
||||
width: 100,
|
||||
icon: Icon(iconData, size: 80, opticalSize: 10))
|
||||
: null;
|
||||
|
||||
final String? tag = item['tag'];
|
||||
final bool containTag = tag.isNotNullAndEmpty;
|
||||
final Map<String, String> labelsHashMap =
|
||||
_generateLabelsHashMap(context, item, tag, containTag);
|
||||
|
||||
final List<Map<String, Color>> statusHashMapList =
|
||||
_generateStatusHashMapList(item);
|
||||
|
||||
Future<void> onTapCardItemAction() async {
|
||||
_handleCardItemTap(context, cardIcon, item);
|
||||
}
|
||||
|
||||
final statusLinkedHashMap = statusHashMapList
|
||||
.map((map) => LinkedHashMap<String, Color>.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 _buildLoadingIndicator(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 15),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
FlutterFlowTheme.of(context).primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, String> _generateLabelsHashMap(BuildContext context,
|
||||
Map<String, dynamic> uItem, String? tag, bool containTag) {
|
||||
return {
|
||||
'${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:':
|
||||
uItem['licensePlate'] ?? '',
|
||||
'${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:':
|
||||
uItem['model'] ?? '',
|
||||
'${FFLocalizations.of(context).getVariableText(ptText: "Proprietário", enText: "Owner")}:':
|
||||
uItem['personName'] ?? '',
|
||||
if (containTag)
|
||||
'${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:':
|
||||
tag ?? '',
|
||||
};
|
||||
}
|
||||
|
||||
List<Map<String, Color>> _generateStatusHashMapList(
|
||||
Map<String, dynamic> uItem) {
|
||||
final statusHashMap = widget.model.generateStatusColorMap(uItem, false);
|
||||
return statusHashMap != null ? [statusHashMap] : [];
|
||||
}
|
||||
|
||||
Future<void> _handleCardItemTap(BuildContext context, FreCardIcon? cardIcon,
|
||||
Map<String, dynamic> uItem) async {
|
||||
try {
|
||||
final dialogContent = widget.model.buildVehicleDetails(
|
||||
icon: cardIcon,
|
||||
item: uItem,
|
||||
context: context,
|
||||
model: widget.model,
|
||||
);
|
||||
|
||||
await showDialog(
|
||||
useSafeArea: true,
|
||||
context: context,
|
||||
builder: (context) =>
|
||||
Dialog(alignment: Alignment.center, child: dialogContent),
|
||||
).whenComplete(() {
|
||||
safeSetState(() {
|
||||
_pageNumber = 1;
|
||||
_fetch(1);
|
||||
});
|
||||
});
|
||||
} catch (e, s) {
|
||||
DialogUtil.errorDefault(context);
|
||||
LogUtil.requestAPIFailed(
|
||||
"proccessRequest.php", "", "Consulta de Veículos", e, s);
|
||||
safeSetState(() {
|
||||
_hasData = false;
|
||||
_loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _initializeScrollController() {
|
||||
// _scrollController = ScrollController(keepScrollOffset: true, initialScrollOffset: offset)
|
||||
// ..addListener(() {
|
||||
// print('ScrollController');
|
||||
// if(!_hasData) return;
|
||||
// if
|
||||
// // (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent)
|
||||
// (_scrollController.position.atEdge && _scrollController.position.pixels != 0)
|
||||
// {
|
||||
// print('ScrollController -> loadMore');
|
||||
// offset = _scrollController.offset;
|
||||
// _loadMore();
|
||||
// }
|
||||
// },);
|
||||
}
|
||||
|
||||
// void _loadMore() {
|
||||
// if (_hasData) {
|
||||
// _pageNumber+=1;
|
||||
// _loading = true;
|
||||
// _fetch(_pageNumber);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -71,7 +71,8 @@ class VehicleModel extends FlutterFlowModel<VehiclePage>
|
|||
Future<void> initAsync() async {
|
||||
amountRegister =
|
||||
await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key);
|
||||
autoApproval= await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key);
|
||||
autoApproval =
|
||||
await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key);
|
||||
}
|
||||
|
||||
bool isFormValid(BuildContext context, GlobalKey<FormState> formKey) {
|
||||
|
@ -91,7 +92,6 @@ mixin class _BaseVehiclePage {
|
|||
ApiCallResponse? vehicleResponse;
|
||||
String? amountRegister = '0';
|
||||
late final String? autoApproval;
|
||||
|
||||
|
||||
VoidCallback? onUpdateVehicle;
|
||||
VoidCallback? onRegisterVehicle;
|
||||
|
@ -240,10 +240,7 @@ mixin _VehicleUpdateScreenModel on _BaseVehiclePage {
|
|||
|
||||
/// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page.
|
||||
mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
||||
|
||||
|
||||
Map<String, Color>? generateStatusColorMap(dynamic uItem, bool isDetail) {
|
||||
|
||||
Map<String, Color>? generateStatusColorMap(dynamic uItem, bool isDetail) {
|
||||
if (autoApproval.toBoolean == true) return null;
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
final localization = FFLocalizations.of(context);
|
||||
|
@ -299,7 +296,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
return {};
|
||||
}
|
||||
|
||||
List<FFButtonWidget> generateActionButtons(dynamic item) {
|
||||
List<FFButtonWidget> generateActionButtons(dynamic item) {
|
||||
final Color iconButtonColor = FlutterFlowTheme.of(context).primaryText;
|
||||
final FFButtonOptions buttonOptions = FFButtonOptions(
|
||||
height: 40,
|
||||
|
@ -342,7 +339,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
ptText: 'Você tem certeza que deseja cancelar essa solicitação?',
|
||||
enText: 'Are you sure you want to delete this request?',
|
||||
),
|
||||
() async => processCancelRequest(item['status'], item));
|
||||
() async => processCancelRequest(item['status'], item));
|
||||
}
|
||||
|
||||
final deleteText = FFLocalizations.of(context)
|
||||
|
@ -359,7 +356,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
ptText: 'Você tem certeza que deseja excluir esse veículo?',
|
||||
enText: 'Are you sure you want to delete this vehicle?',
|
||||
),
|
||||
() async => processDeleteRequest(item),
|
||||
() async => processDeleteRequest(item),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -420,7 +417,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
// ignore: unrelated_type_equality_checks
|
||||
if (value.jsonBody['error'] == true) {
|
||||
final String errorMsg = value.jsonBody['error_msg'];
|
||||
return showSnackbar(
|
||||
return showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: errorMsg,
|
||||
|
@ -430,7 +427,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
);
|
||||
// ignore: unrelated_type_equality_checks
|
||||
}
|
||||
return showSnackbar(
|
||||
return showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Success deleting vehicle',
|
||||
|
@ -440,7 +437,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
);
|
||||
}).catchError((err, stack) {
|
||||
context.pop();
|
||||
return showSnackbar(
|
||||
return showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Error deleting vehicle',
|
||||
|
@ -473,7 +470,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
|
||||
if (value.jsonBody['error'] == true) {
|
||||
final String errorMsg = value.jsonBody['error_msg'];
|
||||
return showSnackbar(
|
||||
return showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: errorMsg,
|
||||
|
@ -482,7 +479,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
true,
|
||||
);
|
||||
}
|
||||
return showSnackbar(
|
||||
return showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Success canceling request',
|
||||
|
@ -492,7 +489,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
);
|
||||
} catch (err) {
|
||||
context.pop();
|
||||
return showSnackbar(
|
||||
return showSnackbarMessenger(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Error canceling request',
|
||||
|
@ -503,7 +500,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
}
|
||||
}
|
||||
|
||||
Future<ApiCallResponse> processCancelDeleteRequest(dynamic item) async{
|
||||
Future<ApiCallResponse> processCancelDeleteRequest(dynamic item) async {
|
||||
return await PhpGroup.deleteVehicle.call(
|
||||
vehicleId: item['vehicleId'],
|
||||
licensePlate: item['licensePlate'],
|
||||
|
@ -512,7 +509,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
);
|
||||
}
|
||||
|
||||
Future<ApiCallResponse> processCancelUpdateRequest(dynamic item) async {
|
||||
Future<ApiCallResponse> processCancelUpdateRequest(dynamic item) async {
|
||||
return await PhpGroup.deleteVehicle.call(
|
||||
vehicleId: item['vehicleId'],
|
||||
licensePlate: item['licensePlate'],
|
||||
|
@ -530,7 +527,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
);
|
||||
}
|
||||
|
||||
Map<String, String> generateLabelsHashMap(dynamic item) {
|
||||
Map<String, String> generateLabelsHashMap(dynamic item) {
|
||||
return {
|
||||
if (item['model'] != null && item['model'] != '')
|
||||
'${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:':
|
||||
|
@ -555,10 +552,10 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
required BuildContext context,
|
||||
required VehicleModel model,
|
||||
required FreCardIcon? icon,
|
||||
}) {
|
||||
final status = generateStatusColorMap(item, true);
|
||||
final buttons = generateActionButtons(item);
|
||||
final labels = generateLabelsHashMap(item);
|
||||
}) {
|
||||
final status = generateStatusColorMap(item, true);
|
||||
final buttons = generateActionButtons(item);
|
||||
final labels = generateLabelsHashMap(item);
|
||||
return DetailsComponentWidget(
|
||||
icon: icon,
|
||||
buttons: buttons,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:collection';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:hub/components/atomic_components/shared_components_atoms/custom_input.dart';
|
||||
|
|
Loading…
Reference in New Issue