121 lines
3.8 KiB
Dart
121 lines
3.8 KiB
Dart
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<PageKeyType, ItemType>
|
|
on PagedSliverList<PageKeyType, ItemType> {}
|
|
|
|
mixin Pageable<T extends StatefulWidget> on State<T> {
|
|
Expanded buildPaginatedListView<X, Y>(
|
|
String noDataFound,
|
|
PagingController<X, Y> 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<X, Y>(
|
|
pagingController: pg,
|
|
builderDelegate: PagedChildBuilderDelegate<Y>(
|
|
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<void> showError(PagingStatus status, PagingController pg) 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: () => pg.retryLastFailedRequest(),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> 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<Color>(
|
|
FlutterFlowTheme.of(context).primary,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|