import 'dart:convert'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:prosappco/src/authentication/authentication_repository.dart'; import 'package:prosappco/src/components/photo_view.dart'; import 'package:prosappco/src/components/pop_appbar.dart'; import 'package:prosappco/src/models/chat_model.dart'; import 'package:prosappco/src/models/event_model.dart'; import 'package:prosappco/src/models/user_model.dart'; import 'package:prosappco/src/screens/professional.dart'; import 'package:prosappco/src/screens/professional_info.dart'; import 'package:http/http.dart' as http; class ChatScreen extends StatefulWidget { final String? eventoId; const ChatScreen({super.key, this.eventoId}); @override State createState() => _ChatScreenState(); } class _ChatScreenState extends State { final _textController = TextEditingController(); final uid = AuthenticationRepository.instance.getCurrentUserUid(); UserModel? user; Professional? professional; bool pro = false; Future sendPushNotification(String token) async { try { http.Response response = await http.post( Uri.parse('https://fcm.googleapis.com/fcm/send'), headers: { 'Content-Type': 'application/json; charset=UTF-8', 'Authorization': 'key=AAAAORdR-xU:APA91bF_wblg86jHAC-uexrXPHavYRlk5wge1Gf46m56V4J2D2L37Cp_hf46JZUzpvsWPSpqc5ewHelKI9LTifUG_s2mciMI6e5VLKo7E1R8btbNo7iaM9do2ctoyHKUm1atlZBdKaN2', }, body: jsonEncode( { 'notification': { 'body': 'Tienes un nuevo mensaje', 'title': 'Nuevo mensaje', }, 'priority': 'high', 'data': { 'click_action': 'FLUTTER_NOTIFICATION_CLICK', 'id': '1', 'status': 'done' }, 'to': token, }, ), ); response; } catch (e) { print('error al enviar notificacion $e'); } } @override void initState() { super.initState(); Event.getEventById(widget.eventoId!).then((event) { if (user == null) { if (uid != event.userId) { UserModel.getUser(event.userId).then( (UserModel s) => setState(() => user = s), ); } else { Professional.getProfessional(event.professionalId) .then((value) => {professional = value}); UserModel.getUser(event.professionalId).then( (UserModel s) => setState(() => {user = s, pro = true}), ); } } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: PopAppbar( onPressed: () { Navigator.pop(context); }, label: 'Chat'), body: Column( children: [ Container( decoration: BoxDecoration( boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.3), spreadRadius: 2, blurRadius: 3, offset: const Offset(0, 2), ), ], ), child: Container( padding: const EdgeInsets.symmetric(vertical: 8), color: const Color(0xFFD6F4FF), alignment: Alignment.topCenter, child: ListTile( leading: GestureDetector( onTap: () { if (pro) { Navigator.of(context).push( CupertinoPageRoute( builder: (BuildContext context) { return ProfessionalInfoScreen( professional: professional!, ); }, ), ); } }, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: ReferencePhoto( ref: user?.photo, size: 55, sizeCircle: 60, ), ), ), title: Text( '${user?.name}', style: const TextStyle( color: Colors.black, fontWeight: FontWeight.w600), ), subtitle: Text(user?.profession ?? ''), trailing: const Icon(Icons.keyboard_arrow_right), ), ), ), Expanded( child: SingleChildScrollView( padding: const EdgeInsets.only(top: 10), reverse: true, child: streamB(uid!), ), ), Container( alignment: Alignment.bottomCenter, width: MediaQuery.of(context).size.width, child: Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 18), width: MediaQuery.of(context).size.width, child: Row( children: [ Expanded( child: TextFormField( controller: _textController, style: const TextStyle(color: Colors.black), decoration: InputDecoration( hintText: 'Mensaje', hintStyle: TextStyle(color: Colors.grey[600], fontSize: 16), border: OutlineInputBorder( borderSide: const BorderSide( color: Colors.grey, width: 1.0), borderRadius: BorderRadius.circular(50)), focusedBorder: OutlineInputBorder( borderSide: const BorderSide( color: Colors.grey, width: 1.0), borderRadius: BorderRadius.circular(50)), contentPadding: const EdgeInsets.symmetric( horizontal: 20, vertical: 15), filled: true, fillColor: Colors.grey[200], ), onFieldSubmitted: (value) async { String muestra = _textController.text.trim(); if (muestra.isNotEmpty) { final nuevoMensaje = MessageModel( user: uid!, content: _textController.text.trimLeft().trimRight(), timestamp: DateTime.now()); final nuevoMensajeMap = { 'user': nuevoMensaje.user, 'content': nuevoMensaje.content, 'timestamp': nuevoMensaje.timestamp, }; FirebaseFirestore.instance .collection('chats') .doc(widget.eventoId) .update({ 'message': FieldValue.arrayUnion([nuevoMensajeMap]) }); if (user?.token != '') { sendPushNotification(user!.token!); } // if (user?.token != '') { // final mensajesQuerySnapshot = // await FirebaseFirestore.instance // .collection('chats') // .doc(widget.eventoId) // .get(); // final mensajes = // mensajesQuerySnapshot.data()?['message']; // if (mensajes != null && mensajes.isNotEmpty) { // final ultimoMensaje = mensajes.last; // final ultimoMensajeUser = ultimoMensaje['user']; // if (ultimoMensajeUser == uid) { // // El último mensaje fue enviado por ti, no se envía la notificación // } else { // sendPushNotification(user!.token!); // } // } else { // sendPushNotification(user!.token!); // } // } _textController.clear(); } }, ), ), const SizedBox(width: 12), GestureDetector( onTap: () async { String muestra = _textController.text.trim(); if (muestra.isNotEmpty) { final nuevoMensaje = MessageModel( user: uid!, content: _textController.text.trimLeft().trimRight(), timestamp: DateTime.now()); final nuevoMensajeMap = { 'user': nuevoMensaje.user, 'content': nuevoMensaje.content, 'timestamp': nuevoMensaje.timestamp, }; FirebaseFirestore.instance .collection('chats') .doc(widget.eventoId) .update({ 'message': FieldValue.arrayUnion([nuevoMensajeMap]) }); if (user?.token != '') { final mensajesQuerySnapshot = await FirebaseFirestore .instance .collection('chats') .doc(widget.eventoId) .get(); final mensajes = mensajesQuerySnapshot.data()?['message']; if (mensajes != null && mensajes.isNotEmpty) { final ultimoMensaje = mensajes.last; final ultimoMensajeUser = ultimoMensaje['user']; if (ultimoMensajeUser == uid) { // El último mensaje fue enviado por ti, no se envía la notificación } else { sendPushNotification(user!.token!); } } else { sendPushNotification(user!.token!); } } _textController.clear(); } }, child: Container( height: 50, width: 50, decoration: BoxDecoration( color: Theme.of(context).primaryColor, borderRadius: BorderRadius.circular(30), ), child: const Center( child: Icon( Icons.send, color: Colors.white, ), ), ), ) ], ), ), ), ], ), ); } StreamBuilder>> streamB(String uid) { return StreamBuilder( stream: FirebaseFirestore.instance .collection('chats') .doc(widget.eventoId) .snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) { return const Center(child: CircularProgressIndicator()); } final data = snapshot.data!; final chat = ChatModel.fromDocumentSnapshot(data); return Column( children: [ ...chat.messages.map( (e) => uid != e.user ? ListTile( title: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: const EdgeInsets.only(right: 60), padding: const EdgeInsets.symmetric( vertical: 10, horizontal: 16), decoration: BoxDecoration( color: Colors.grey.shade200, borderRadius: const BorderRadius.only( topRight: Radius.circular(20), bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20), ), ), child: Text( e.content, style: const TextStyle(fontSize: 16), ), ), const SizedBox(width: 5), Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: Text( DateFormat('h:mm a').format(e.timestamp), style: const TextStyle( color: Colors.grey, fontSize: 12), ), ), ], ), ) : ListTile( title: Column( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end, children: [ Container( margin: const EdgeInsets.only(left: 60), padding: const EdgeInsets.symmetric( vertical: 10, horizontal: 16, ), decoration: const BoxDecoration( color: Color(0xFFD5EFFF), borderRadius: BorderRadius.only( topLeft: Radius.circular(20), bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20), ), ), child: Text( e.content, style: const TextStyle(fontSize: 16), ), ), const SizedBox(width: 5), Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: Text( DateFormat('h:mm a').format(e.timestamp), style: const TextStyle( color: Colors.grey, fontSize: 12, ), ), ), ], ), ), ) ], ); }, ); } }