notificaciones al pedir servicio y al enviar mensaje de chat

This commit is contained in:
Felipe
2024-04-25 11:15:33 -05:00
parent 76be1f1f1a
commit e1049f7281
15 changed files with 411 additions and 304 deletions
+42 -118
View File
@@ -8,6 +8,7 @@ import 'package:injector/injector.dart';
import 'package:intl/intl.dart';
import 'package:prosappco/blocs/chat_bloc/chat_bloc.dart';
import 'package:prosappco/components/general_reputation.dart';
import 'package:prosappco/local_notifications/local_notifications.dart';
import 'package:service_repository/service_repository.dart';
import 'package:user_repository/user_repository.dart';
@@ -26,6 +27,7 @@ class _ChatScreenState extends State<ChatScreen> {
final FocusNode _messageFocusNode = FocusNode();
List<dynamic>? _userInfo;
DateTime? _lastNotificationTime;
@override
void initState() {
@@ -177,126 +179,8 @@ class _ChatScreenState extends State<ChatScreen> {
),
);
} else {
// Indicador de carga opcional si se desea mostrar mientras se carga la información por primera vez.
return const Center(child: CircularProgressIndicator());
}
// if (snapshot.connectionState == ConnectionState.waiting) {
// return const Center(child: CircularProgressIndicator());
// } else {
// if (snapshot.hasError) {
// return Center(
// child: Text('Error inesperado: ${snapshot.error}'),
// );
// } else {
// final userInfo = snapshot.data![0] as MyUser;
// return Container(
// padding: const EdgeInsets.symmetric(vertical: 8),
// color: const Color(0xFFD6F4FF),
// alignment: Alignment.topCenter,
// child: ListTile(
// leading: Container(
// width: 60,
// height: 60,
// decoration: BoxDecoration(
// color: Colors.grey.shade300,
// shape: BoxShape.circle,
// image: userInfo.picture == null
// ? null
// : DecorationImage(
// image: NetworkImage(
// userInfo.picture ?? ''),
// fit: BoxFit.contain,
// ),
// ),
// child: userInfo.picture == null
// ? Icon(
// CupertinoIcons.person,
// color: Colors.grey.shade400,
// size: 40,
// )
// : null,
// ),
// title: Text(
// userInfo.name ?? '',
// overflow: TextOverflow.ellipsis,
// style: const TextStyle(
// fontSize: 15,
// fontWeight: FontWeight.w600,
// ),
// ),
// subtitle: widget.service.userId ==
// FirebaseAuth.instance.currentUser!.uid
// ? GeneralReputation(
// userId: widget.service.professionalId,
// builder: (context, reputation) {
// final average = reputation.averagePro;
// final total = reputation.totalPro;
// return Row(
// children: [
// RatingBar.builder(
// initialRating:
// calculoRating(average),
// minRating: 1,
// direction: Axis.horizontal,
// allowHalfRating: true,
// itemCount: 5,
// itemSize: 25,
// maxRating: 5,
// itemBuilder: (context, _) =>
// const Icon(
// Icons.star,
// color: Color(0xFF2BA4EC),
// ),
// onRatingUpdate: (rating) {},
// ignoreGestures: true,
// ),
// const SizedBox(width: 5),
// Text(
// '${average.toStringAsFixed(1)} (${total.toString()})',
// ),
// ],
// );
// })
// : GeneralReputation(
// userId: widget.service.userId,
// builder: (context, reputation) {
// final average = reputation.average;
// final total = reputation.total;
// return Row(
// children: [
// RatingBar.builder(
// initialRating:
// calculoRating(average),
// minRating: 1,
// direction: Axis.horizontal,
// allowHalfRating: true,
// itemCount: 5,
// itemSize: 25,
// maxRating: 5,
// itemBuilder: (context, _) =>
// const Icon(
// Icons.star,
// color: Color(0xFF2BA4EC),
// ),
// onRatingUpdate: (rating) {},
// ignoreGestures: true,
// ),
// const SizedBox(width: 5),
// Text(
// '${average.toStringAsFixed(1)} (${total.toString()})',
// ),
// ],
// );
// },
// ),
// ),
// );
// }
// }
},
),
Expanded(
@@ -353,6 +237,26 @@ class _ChatScreenState extends State<ChatScreen> {
serviceId: widget.service.id!,
message: message,
));
if (_userInfo != null) {
final userInfo = _userInfo![0] as MyUser;
if (userInfo.token == null) return;
if (_lastNotificationTime == null ||
DateTime.now().difference(
_lastNotificationTime!) >
const Duration(minutes: 5)) {
LocalNotifications.sendPushNotification(
userInfo.token!,
'Nuevo mensaje',
'Tienes un nuevo mensaje de ${userInfo.name}',
);
_lastNotificationTime = DateTime.now();
}
}
_messageController.clear();
_messageFocusNode.requestFocus();
},
@@ -375,6 +279,26 @@ class _ChatScreenState extends State<ChatScreen> {
serviceId: widget.service.id!,
message: message,
));
if (_userInfo != null) {
final userInfo = _userInfo![0] as MyUser;
if (userInfo.token == null) return;
if (_lastNotificationTime == null ||
DateTime.now().difference(
_lastNotificationTime!) >
const Duration(minutes: 5)) {
LocalNotifications.sendPushNotification(
userInfo.token!,
'Nuevo mensaje',
'Tienes un nuevo mensaje de ${userInfo.name}',
);
_lastNotificationTime = DateTime.now();
}
}
_messageController.clear();
_messageFocusNode.requestFocus();
},
+12 -9
View File
@@ -180,7 +180,7 @@ class UserCalendarScreenState extends State<UserCalendarScreen> {
schedule.range2Hour2!,
);
return rangesItemList(ranges, _services);
return rangesItemList(ranges, _services, today);
}
List<TimeOfDay> ranges1 = TimeOfDayUtils.genRanges(
@@ -193,26 +193,29 @@ class UserCalendarScreenState extends State<UserCalendarScreen> {
);
return [
...rangesItemList(ranges1, _services),
...rangesItemList(ranges2, _services),
...rangesItemList(ranges1, _services, today),
...rangesItemList(ranges2, _services, today),
];
}
bool _isHora1Ocupada(TimeOfDay hora1, List<ServiceEntity>? events) {
bool _isHora1Ocupada(
TimeOfDay hora1, List<ServiceEntity>? events, DateTime selectedDay) {
if (events != null) {
for (ServiceEntity event in events) {
if (hora1 == event.range1Hour1) {
return true;
if (selectedDay.toString() == event.day) {
if (hora1 == event.range1Hour1) {
return true;
}
}
}
}
return false;
}
List<Widget> rangesItemList(
List<TimeOfDay> ranges, List<ServiceEntity>? events) {
List<Widget> rangesItemList(List<TimeOfDay> ranges,
List<ServiceEntity>? events, DateTime selectedDay) {
return ranges.map((time) {
if (_isHora1Ocupada(time, events)) {
if (_isHora1Ocupada(time, events, selectedDay)) {
return Card(
elevation: 4,
margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
+23 -5
View File
@@ -13,9 +13,11 @@ import 'package:injector/injector.dart';
import 'package:intl/intl.dart';
import 'package:professional_repository/professional_repository.dart';
import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart';
import 'package:prosappco/blocs/notification_bloc/notification_bloc.dart';
import 'package:prosappco/blocs/professional_list_bloc/professional_list_bloc.dart';
import 'package:prosappco/blocs/service_bloc/service_bloc.dart';
import 'package:prosappco/constansts.dart';
import 'package:prosappco/local_notifications/local_notifications.dart';
import 'package:prosappco/screens/lists/professional_list_screen.dart';
import 'package:prosappco/screens/user/user_service_screen.dart';
import 'package:prosappco/utils/time_of_day_extension.dart';
@@ -86,6 +88,10 @@ class _UserMapScreenState extends State<UserMapScreen> {
}
}
// void requestNotificationPermission() async {
// context.read<NotificationBloc>().requestPermission();
// }
void _loadSettings() {
settingRepository.getSettings().then(
(value) => setState(() {
@@ -172,10 +178,13 @@ class _UserMapScreenState extends State<UserMapScreen> {
elevation: 3,
minimumSize: const Size(50, 50),
),
child: const Icon(
child: Icon(
Icons.menu,
color: Colors.black,
size: 35,
size: context.select(
(NotificationBloc bloc) =>
bloc.state.status.index > 0 ? 35 : 35,
),
),
onPressed: () {
Scaffold.of(context).openDrawer();
@@ -318,6 +327,9 @@ class _UserMapScreenState extends State<UserMapScreen> {
decoration: const InputDecoration(
prefixIcon: Icon(Icons.assignment_ind_rounded),
suffixIcon: Icon(Icons.arrow_drop_down),
// hintText: context.select(
// (NotificationBloc bloc) => '${bloc.state.status}',
// ),
hintText: 'Selecciona un profesional',
),
),
@@ -386,7 +398,7 @@ class _UserMapScreenState extends State<UserMapScreen> {
onPressed: isLoading
? null
: () {
// tODO: Crear servicio
if (profesionalSeleccionado == null) return;
if (serviceLocationPreference ==
ServiceLocationPreferences.office) {
if (settings?.tarifas == true) {
@@ -487,7 +499,14 @@ class _UserMapScreenState extends State<UserMapScreen> {
// TODO: error inesperado
}
// clear inputs
if (profesionalSeleccionado!.myUser.token != null) {
LocalNotifications.sendPushNotification(
profesionalSeleccionado!.myUser.token!,
'Nuevo servicio',
'Tienes una nueva solicitud de servicio pendiente',
);
}
fechaSeleccionada = null;
horaSeleccionada = null;
profesionalSeleccionado = null;
@@ -538,7 +557,6 @@ class _UserMapScreenState extends State<UserMapScreen> {
borderRadius: BorderRadius.circular(10),
),
),
//x
child: const Icon(
CupertinoIcons.xmark,
color: Colors.white,