344 lines
11 KiB
Dart
344 lines
11 KiB
Dart
import 'dart:async';
|
|
import 'dart:collection';
|
|
import 'dart:developer';
|
|
|
|
import 'package:hub/commons/actions/api_calls.dart';
|
|
import 'package:hub/app_state.dart';
|
|
import 'package:hub/commons/widgets/flutter_flow_theme.dart';
|
|
import 'package:hub/commons/widgets/flutter_flow_util.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:rxdart/rxdart.dart';
|
|
|
|
final dropdown = BehaviorSubject<LinkedHashMap<String, String>>.seeded(
|
|
LinkedHashMap.from({
|
|
'All': 'A',
|
|
}),
|
|
);
|
|
|
|
class MessageWellComponentWidget extends StatefulWidget {
|
|
const MessageWellComponentWidget({super.key});
|
|
|
|
@override
|
|
State<MessageWellComponentWidget> createState() =>
|
|
_MessageWellComponentWidgetState();
|
|
}
|
|
|
|
class _MessageWellComponentWidgetState
|
|
extends State<MessageWellComponentWidget> {
|
|
StreamSubscription? _dropdownSubscription;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
|
context.read<MessageWellNotifier>().fetchMessages();
|
|
});
|
|
|
|
_dropdownSubscription = dropdown.stream.listen((_) {
|
|
context.read<MessageWellNotifier>().fetchMessages();
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_dropdownSubscription?.cancel();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final messages = context.read<MessageWellNotifier>().getMessages();
|
|
return Align(
|
|
alignment: Alignment.center,
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 40.0),
|
|
child: SizedBox(
|
|
height: MediaQuery.of(context).size.height * 0.8,
|
|
child: Column(
|
|
children: [
|
|
_buildHandleMessageWell(context, FlutterFlowTheme.of(context)),
|
|
_buildMenuMessageWell(context, FlutterFlowTheme.of(context)),
|
|
Expanded(
|
|
child: ListView.builder(
|
|
itemCount: messages.length,
|
|
shrinkWrap: true,
|
|
physics: const AlwaysScrollableScrollPhysics(),
|
|
itemBuilder: (context, index) {
|
|
var message = messages[index];
|
|
return _buildMessageItem(context, message, index);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
|
|
Widget _buildMenuMessageWell(BuildContext context, FlutterFlowTheme theme) {
|
|
final dropdownItems = LinkedHashMap.from({
|
|
'All': 'A',
|
|
'Personal': 'O',
|
|
'Global': 'C',
|
|
});
|
|
return SizedBox(
|
|
key: UniqueKey(),
|
|
width: 200,
|
|
height: 40,
|
|
child: StreamBuilder<String>(
|
|
stream: dropdown.stream.map((event) => event.keys.first),
|
|
builder: (context, snapshot) {
|
|
final value = snapshot.data;
|
|
return DropdownButtonFormField<String>(
|
|
value: value,
|
|
decoration: InputDecoration(
|
|
isDense: true,
|
|
contentPadding: const EdgeInsets.symmetric(horizontal: 10.0),
|
|
errorBorder: OutlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: theme.error,
|
|
width: 2,
|
|
),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
enabledBorder: OutlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: theme.primary,
|
|
width: 2,
|
|
),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
focusedBorder: OutlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: theme.primary,
|
|
width: 2,
|
|
),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
disabledBorder: OutlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: theme.primary,
|
|
width: 2,
|
|
),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
focusedErrorBorder: OutlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: theme.error,
|
|
width: 2,
|
|
),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
border: OutlineInputBorder(
|
|
borderSide: BorderSide(
|
|
color: theme.primary,
|
|
width: 2,
|
|
),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
filled: true,
|
|
fillColor: theme.primary,
|
|
),
|
|
onChanged: (String? newValue) {
|
|
safeSetState(() => dropdown.value = LinkedHashMap.from({newValue!: dropdownItems[newValue].toString()}));
|
|
},
|
|
items: dropdownItems.entries
|
|
.map((entry) => DropdownMenuItem<String>(
|
|
value: entry.key,
|
|
child: Text(entry.key),
|
|
))
|
|
.toList(),
|
|
style: theme.bodyMedium.copyWith(
|
|
color: theme.primaryText,
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Text _buildHandleMessageWell(BuildContext context, FlutterFlowTheme theme) {
|
|
return Text(
|
|
FFLocalizations.of(context).getVariableText(
|
|
ptText: 'Mural de Mensagens',
|
|
enText: 'Message Wall',
|
|
),
|
|
style: theme.bodyMedium.copyWith(
|
|
fontFamily: 'Nunito Sans',
|
|
letterSpacing: 0.0,
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildMessageItem(
|
|
BuildContext context, dynamic message, int index) {
|
|
final theme = FlutterFlowTheme.of(context);
|
|
String formatMessageOrigin(String messageOrigin) {
|
|
final words = messageOrigin.split(' ');
|
|
final formattedWords = words.map((word) {
|
|
final firstLetter = word.substring(0, 1).toUpperCase();
|
|
final remainingLetters = word.substring(1).toLowerCase();
|
|
return '$firstLetter$remainingLetters';
|
|
});
|
|
return formattedWords.join(' ');
|
|
}
|
|
return GestureDetector(
|
|
onTap: () => {},
|
|
child: Padding(
|
|
padding: const EdgeInsets.fromLTRB(20, 5, 20, 5),
|
|
child: Container(
|
|
width: MediaQuery.of(context).size.width * 0.9,
|
|
height: 127.0,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
|
child: Container(
|
|
width: 64.0,
|
|
height: 64.0,
|
|
decoration: const BoxDecoration(shape: BoxShape.circle),
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.max,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const SizedBox(height: 8.0),
|
|
Center(
|
|
child: Text(
|
|
'~ ${formatMessageOrigin(message['MSG_ORIGEM_DESC'].toString())}',
|
|
style: theme.bodyMedium.copyWith(
|
|
fontFamily: 'Nunito Sans',
|
|
color: theme.primary,
|
|
fontSize: 14.0,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 8.0),
|
|
Expanded(
|
|
child: SingleChildScrollView(
|
|
scrollDirection: Axis.vertical,
|
|
child: Text(
|
|
formatMessageOrigin(message['MSG_TEXTO'].toString()),
|
|
style: theme.bodyMedium.copyWith(
|
|
fontFamily: 'Nunito Sans',
|
|
color: theme.bodyMedium.color,
|
|
fontSize: 14.0,
|
|
),
|
|
softWrap: true,
|
|
maxLines: 10,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
class MessageWellState {
|
|
final List<dynamic> messages;
|
|
int pageNumber;
|
|
final bool allowScrollInSingleChildScrollView;
|
|
|
|
MessageWellState({
|
|
required this.messages,
|
|
this.pageNumber = 1,
|
|
required this.allowScrollInSingleChildScrollView,
|
|
});
|
|
|
|
MessageWellState copyWith({
|
|
List<dynamic>? messages,
|
|
int? pageNumber,
|
|
bool? allowScrollInSingleChildScrollView,
|
|
}) {
|
|
return MessageWellState(
|
|
messages: messages ?? this.messages,
|
|
pageNumber: pageNumber ?? this.pageNumber,
|
|
allowScrollInSingleChildScrollView:
|
|
allowScrollInSingleChildScrollView ??
|
|
this.allowScrollInSingleChildScrollView,
|
|
);
|
|
}
|
|
}
|
|
|
|
class MessageWellNotifier extends StateNotifier<MessageWellState> {
|
|
var _totalPageNumber = 1;
|
|
int get totalPageNumber => _totalPageNumber;
|
|
|
|
set totalPageNumber(int value) {
|
|
_totalPageNumber = value;
|
|
}
|
|
|
|
MessageWellNotifier()
|
|
: super(MessageWellState(
|
|
messages: [],
|
|
allowScrollInSingleChildScrollView: true,
|
|
)) {
|
|
fetchMessages();
|
|
}
|
|
|
|
void fetchMessages() async {
|
|
if (state.pageNumber <= totalPageNumber) {
|
|
var apiCall = GetMessagesCall();
|
|
var response = await apiCall.call(
|
|
devUUID: FFAppState().devUUID.toString(),
|
|
userUUID: FFAppState().userUUID.toString(),
|
|
cliID: FFAppState().cliUUID.toString(),
|
|
atividade: 'getMensagens',
|
|
pageSize: '100',
|
|
pageNumber: state.pageNumber.toString(),
|
|
tipoDestino: dropdown.value.values.first,
|
|
);
|
|
if (response.statusCode == 200) {
|
|
var messagesData = response.jsonBody['mensagens'];
|
|
var newMessages = [...state.messages, ...messagesData];
|
|
state = state.copyWith(messages: newMessages);
|
|
// var rExp = RegExp(r'\d+')
|
|
// .allMatches(newMessages.toString())
|
|
// .map((e) => e.group(0))
|
|
// .toList();
|
|
// Provider.of<MessageCounter>(context, listen: false).setCounter(int.parse(response.jsonBody['total_pages']));
|
|
// totalPageNumber = int.parse(response.jsonBody['total_pages']);
|
|
} else {
|
|
log('Error fetching messages: ${response.statusCode}');
|
|
}
|
|
} else {
|
|
log('No more messages to fetch ...');
|
|
}
|
|
}
|
|
|
|
List<dynamic> getMessages() {
|
|
return state.messages;
|
|
}
|
|
void incrementPageNumber() {
|
|
if (state.pageNumber <= totalPageNumber) {
|
|
state = state.copyWith(pageNumber: state.pageNumber + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
final messageWellProvider =
|
|
StateNotifierProvider<MessageWellNotifier, MessageWellState>((ref) {
|
|
return MessageWellNotifier();
|
|
});
|