WIP - paginacao

This commit is contained in:
jantunesmessias 2025-02-06 18:01:47 -03:00
parent b2df549066
commit 16f43bbab8
1 changed files with 91 additions and 104 deletions

View File

@ -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<void> _future;
List<dynamic> _wrap = [];
int _pageNumber = 1;
bool _hasData = false;
bool _loading = false;
int count = 0;
@override
State<VehicleHistoryScreen> createState() => _VehicleHistoryScreenState();
}
class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
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<VehicleHistoryScreen>
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<VehicleHistoryScreen>
);
}
Widget _buildVehicleList(BuildContext context, double limitedBodyTextSize) {
Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) {
return Expanded(
child: FutureBuilder<void>(
future: widget._future,
child: FutureBuilder<List<Widget?>>(
future: _future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
@ -86,13 +81,13 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
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<String, dynamic> 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<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) {
log('amountRegister: ${widget.model.amountRegister}');
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 _FetchingMixin on State<VehicleHistoryScreen> {
Future<ApiCallResponse?> _fetch() async {
mixin Remotable on State<VehicleHistoryScreen> {
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 {
setState(() => widget._loading = true);
var response = await PhpGroup.getVehiclesByProperty
.call(widget._pageNumber.toString());
final List<dynamic> vehicles = response.jsonBody['vehicles'] ?? [];
var response = await PhpGroup.getVehiclesByProperty.call(widget._pageNumber.toString());
final List<dynamic> vehicles = response.jsonBody['vehicles'] as List<dynamic>? ?? [];
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<VehicleHistoryScreen> {
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<VehicleHistoryScreen> {
showSnackbar(context, message, true);
}
}
// Mixin for Card Item
mixin _CardItemMixin on _FetchingMixin {
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;
Future<List<Widget?>> _generateItems(BuildContext context, List<dynamic> uItem) async {
if (!widget._hasData) return [];
final String? tag = uItem['tag'];
final bool containTag = tag.isNotNullAndEmpty;
final Map<String, String> labelsHashMap =
_generateLabelsHashMap(context, uItem, tag, containTag);
List<Widget?> 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<void> onTapCardItemAction() async {
await _handleCardItemTap(context, cardIcon, uItem);
final String? tag = uItem['tag'];
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
.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._wrap.addAll(items);
return items;
}
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();
}
}
}