flutter-freaccess-hub/lib/commons/components/molecules/message_well/widget.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();
});