Merge pull request #16 from FRE-Informatica/fix_message_pagination
FIX: Paginação da Tela de Mensagem
This commit is contained in:
commit
976205b096
|
@ -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
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PreferredSizeWidget buildAppBar(BuildContext 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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
@ -106,9 +178,9 @@ PreferredSizeWidget buildAppBar(BuildContext context) {
|
||||||
actions: const [],
|
actions: const [],
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
||||||
|
@ -344,4 +387,8 @@ Widget buildListItem(BuildContext context, dynamic jsonBody) {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue