Merge pull request #16 from FRE-Informatica/fix_message_pagination

FIX: Paginação da Tela de Mensagem
This commit is contained in:
Jônatas Antunes Messias 2024-08-13 09:20:16 -03:00 committed by GitHub
commit 976205b096
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 334 additions and 281 deletions

View File

@ -1,4 +1,7 @@
PODS: PODS:
- connectivity_plus (0.0.1):
- Flutter
- FlutterMacOS
- device_info_plus (0.0.1): - device_info_plus (0.0.1):
- Flutter - Flutter
- DKImagePickerController/Core (4.3.9): - DKImagePickerController/Core (4.3.9):
@ -225,6 +228,7 @@ PODS:
- Flutter - Flutter
DEPENDENCIES: DEPENDENCIES:
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`)
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`) - firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
@ -271,6 +275,8 @@ SPEC REPOS:
- SwiftyGif - SwiftyGif
EXTERNAL SOURCES: EXTERNAL SOURCES:
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/darwin"
device_info_plus: device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios" :path: ".symlinks/plugins/device_info_plus/ios"
file_picker: file_picker:
@ -313,6 +319,7 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios" :path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
SPEC CHECKSUMS: SPEC CHECKSUMS:
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60

View File

@ -411,7 +411,6 @@ class ApiManager {
ApiCallOptions? options, ApiCallOptions? options,
http.Client? client, http.Client? client,
}) async { }) async {
log('makeApiCall -> $params.toString()');
final callOptions = options ?? final callOptions = options ??
ApiCallOptions( ApiCallOptions(

View File

@ -1,5 +1,3 @@
// import 'dart:js_interop';
import 'dart:developer'; import 'dart:developer';
import 'package:hub/app_state.dart'; import 'package:hub/app_state.dart';
@ -14,6 +12,7 @@ import 'package:hub/pages/message_history_page/message_history_page_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:hub/shared/utils/dialog_util.dart';
import 'package:hub/shared/utils/log_util.dart'; import 'package:hub/shared/utils/log_util.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -21,28 +20,52 @@ class MessageHistoryPageWidget extends StatefulWidget {
const MessageHistoryPageWidget({super.key}); const MessageHistoryPageWidget({super.key});
@override @override
State<MessageHistoryPageWidget> createState() => State<MessageHistoryPageWidget> createState() => _MessageHistoryPageWidgetState();
_MessageHistoryPageWidgetState();
} }
class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget> class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget> with TickerProviderStateMixin {
with TickerProviderStateMixin {
late MessageHistoryPageModel _model; late MessageHistoryPageModel _model;
final scaffoldKey = GlobalKey<ScaffoldState>(); final scaffoldKey = GlobalKey<ScaffoldState>();
int currentPage = 0;
int totalPage = 0; late ScrollController _scrollController;
int _pageNumber = 1;
final int _pageSize = 10;
bool _hasData = false;
bool _loading = false;
String _destinyType = "P";
late Future<void> _messageFuture;
List<dynamic> _messageWrap = [];
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_model = createModel(context, () => MessageHistoryPageModel()); _model = createModel(context, () => MessageHistoryPageModel());
_model.tabBarController = TabController( _messageFuture = fetchMessage();
vsync: this,
length: 3, _scrollController = ScrollController()..addListener(() {
initialIndex: 1, if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) {
)..addListener(() => setState(() {})); _loadMore();
}
});
_model.tabBarController = TabController(vsync: this, length: 3, initialIndex: 0)..addListener(() {
if (_model.tabBarController?.index == 0) {
_destinyType = "P";
} else if (_model.tabBarController?.index == 1) {
_destinyType = "A";
} else {
_destinyType = "T";
}
_pageNumber = 1;
_messageWrap = [];
_messageFuture = fetchMessage();
});
_model.textController ??= TextEditingController(); _model.textController ??= TextEditingController();
_model.textFieldFocusNode ??= FocusNode(); _model.textFieldFocusNode ??= FocusNode();
@ -51,7 +74,7 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
@override @override
void dispose() { void dispose() {
_model.dispose(); _model.dispose();
_scrollController.dispose();
super.dispose(); super.dispose();
} }
@ -66,13 +89,62 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
return Scaffold( return Scaffold(
key: scaffoldKey, key: scaffoldKey,
backgroundColor: FlutterFlowTheme.of(context).primaryBackground, backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
appBar: buildAppBar(context), appBar: _appBar(context),
body: buildBody(context, _model), body: _body(context),
); );
} }
Future<ApiCallResponse?> fetchMessage() async {
try {
setState(() => _loading = true);
var response = await PhpGroup.getMessagesCall.call(
devUUID: FFAppState().devUUID.toString(),
userUUID: FFAppState().userUUID.toString(),
cliID: FFAppState().cliUUID.toString(),
atividade: 'getMensagens',
pageSize: _pageSize.toString(),
pageNumber: _pageNumber.toString(),
tipoDestino: _destinyType,
);
final List<dynamic> messages = response.jsonBody['mensagens'] ?? [];
if (messages != null && messages.isNotEmpty) {
setState(() {
_messageWrap.addAll(messages);
_hasData = true;
_loading = false;
});
return response;
}
_showNoMoreDataSnackBar(context);
setState(() {
_hasData = false;
_loading = false;
});
return null;
} catch (e, s) {
DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Mensagems", e, s);
setState(() {
_hasData = false;
_loading = false;
});
}
} }
PreferredSizeWidget buildAppBar(BuildContext context) { void _loadMore() {
if (_hasData == true) {
_pageNumber++;
_messageFuture = fetchMessage();
}
}
PreferredSizeWidget _appBar(BuildContext context) {
return AppBar( return AppBar(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground, backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
@ -108,7 +180,7 @@ PreferredSizeWidget buildAppBar(BuildContext context) {
); );
} }
Widget buildBody(BuildContext context, MessageHistoryPageModel _model) { Widget _body(BuildContext context) {
return SafeArea( return SafeArea(
top: true, top: true,
child: Column( child: Column(
@ -151,102 +223,73 @@ Widget buildBody(BuildContext context, MessageHistoryPageModel _model) {
), ),
], ],
controller: _model.tabBarController, controller: _model.tabBarController,
onTap: (i) async { ),
[() async {}, () async {}][i](); ),
if (_hasData == false && _pageNumber <= 1 && _loading == false)
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Center(
child: Text(
FFLocalizations.of(context).getVariableText(
ptText: "Nenhuma mensagem encontrada!",
enText: "No message found"
)
),
)
],
),
)
else if (_hasData == true || _pageNumber >= 1)
Expanded(
child: FutureBuilder<void>(
future: _messageFuture,
builder: (context, snapshot) {
return ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
controller: _scrollController,
itemCount: _messageWrap.length,
itemBuilder: (context, index) {
final item = _messageWrap[index];
return _item(context, item);
}
);
}, },
), ),
), ),
Expanded( if (_hasData == true && _loading == true)
child: TabBarView(controller: _model.tabBarController, children: [ Container(
buildListView(context, _model, 'P'), padding: const EdgeInsets.only(top: 15, bottom: 15),
buildListView(context, _model, 'A'), child: Center(
buildListView(context, _model, 'T'), child: CircularProgressIndicator(
])), valueColor: AlwaysStoppedAnimation<Color>(
FlutterFlowTheme.of(context).primary,
),
),
),
)
].addToStart(const SizedBox(height: 0)), ].addToStart(const SizedBox(height: 0)),
), ),
); );
} }
Widget buildListView( void _showNoMoreDataSnackBar(BuildContext context) {
BuildContext context, MessageHistoryPageModel _model, String DestIndex) { ScaffoldMessenger.of(context).showSnackBar(
return Container( SnackBar(
width: double.infinity, content: Text(
height: double.infinity, FFLocalizations.of(context).getVariableText(ptText: "Não há mais dados.", enText: "No more data."),
decoration: const BoxDecoration(),
child: FutureBuilder<dynamic>(
future: Future(() async {
var body = {
'devUUID': FFAppState().devUUID.toString(),
'userUUID': FFAppState().userUUID.toString(),
'cliID': FFAppState().cliUUID.toString(),
'atividade': 'getMensagens',
'pageSize': '100',
'pageNumber': '1',
'tipoDestino': DestIndex.toString(),
};
try {
var response = await PhpGroup.getMessagesCall.call(
devUUID: body['devUUID'],
userUUID: body['userUUID'],
cliID: body['cliID'],
atividade: body['atividade'],
pageSize: body['pageSize'],
pageNumber: body['pageNumber'],
tipoDestino: DestIndex,
);
return response.jsonBody;
} catch (error, stack) {
LogUtil.requestAPIFailed('processRequest.php', jsonEncode(body),
'Mensagens não Encontradas', error, stack);
return {'mensagens': [], 'total_rows': 0};
}
}),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: SizedBox(
width: 50.0,
height: 50.0,
child: SpinKitCircle(
color: FlutterFlowTheme.of(context).primary,
size: 50.0,
), ),
), duration: const Duration(seconds: 3),
); backgroundColor: FlutterFlowTheme.of(context).primary,
}
if (snapshot.hasError == true ||
snapshot.data == null ||
!snapshot.hasData ||
snapshot.hasError) {
return const Center(
child: Text('Erro ao carregar mensagens'),
);
}
final mensagens = snapshot.data!['mensagens'];
final totalRows = snapshot.data!['total_rows'];
if (totalRows == 0 || mensagens == null || mensagens.isEmpty) {
return const Center(
child: Text('Nenhuma mensagem encontrada'),
);
}
return ListView.builder(
itemCount: totalRows,
addAutomaticKeepAlives: false,
addRepaintBoundaries: true,
cacheExtent: 1000.0,
itemBuilder: (BuildContext context, int index) {
return buildListItem(
context,
snapshot.data!['mensagens'][index],
);
},
);
},
), ),
); );
} }
Widget buildListItem(BuildContext context, dynamic jsonBody) {
Widget _item(BuildContext context, dynamic jsonBody) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 15), padding: const EdgeInsets.symmetric(horizontal: 15),
child: Card( child: Card(
@ -345,3 +388,7 @@ Widget buildListItem(BuildContext context, dynamic jsonBody) {
), ),
)); ));
} }
}