forked from eatvio/eatvio_app
feat(notifications): added push notifications navigation handling and fixed ws notification parsing
This commit is contained in:
@@ -349,23 +349,31 @@ class NotificationsCubit extends Cubit<NotificationsState> {
|
||||
void _handleNotification(String notificationData) {
|
||||
final json = jsonDecode(notificationData) as Map<String, dynamic>;
|
||||
|
||||
// Улучшенная логика определения типа уведомления
|
||||
// Улучшенная логика определения типа уведомления (порядок: database_type → type → notification_class_name)
|
||||
String? stringifiedType;
|
||||
|
||||
// Сначала проверяем поле 'type' в корне JSON
|
||||
if (json.containsKey('type') && json['type'] != null) {
|
||||
// Сначала проверяем поле 'database_type' в корне JSON
|
||||
if (json.containsKey('database_type') && json['database_type'] != null) {
|
||||
stringifiedType = json['database_type'].toString();
|
||||
log('Found database_type in root: $stringifiedType');
|
||||
}
|
||||
// Затем поле 'type' в корне
|
||||
else if (json.containsKey('type') && json['type'] != null) {
|
||||
stringifiedType = json['type'].toString();
|
||||
log('Found type in root: $stringifiedType');
|
||||
}
|
||||
// Затем проверяем поле 'notification_class_name' в корне JSON
|
||||
// Затем поле 'notification_class_name' в корне
|
||||
else if (json.containsKey('notification_class_name') && json['notification_class_name'] != null) {
|
||||
stringifiedType = json['notification_class_name'].toString();
|
||||
log('Found notification_class_name in root: $stringifiedType');
|
||||
}
|
||||
// Если есть поле 'data', проверяем внутри него
|
||||
// Если есть поле 'data', проверяем внутри него в том же порядке
|
||||
else if (json.containsKey('data') && json['data'] is Map<String, dynamic>) {
|
||||
final data = json['data'] as Map<String, dynamic>;
|
||||
if (data.containsKey('type') && data['type'] != null) {
|
||||
if (data.containsKey('database_type') && data['database_type'] != null) {
|
||||
stringifiedType = data['database_type'].toString();
|
||||
log('Found database_type in data: $stringifiedType');
|
||||
} else if (data.containsKey('type') && data['type'] != null) {
|
||||
stringifiedType = data['type'].toString();
|
||||
log('Found type in data: $stringifiedType');
|
||||
} else if (data.containsKey('notification_class_name') && data['notification_class_name'] != null) {
|
||||
|
||||
@@ -147,17 +147,16 @@ void _navigateToBottomNavRoute(BuildContext context, String path, [Object? extra
|
||||
}
|
||||
}
|
||||
|
||||
void _navigateToEntity(BuildContext context, String type, int id, int? commentId) {
|
||||
if (type.contains('BlogPost')) {
|
||||
context.push(RouteConstants.blogPostScreen, extra: {'id': id, 'highlightedCommentId': commentId});
|
||||
} else if (type.contains('Recipe')) {
|
||||
// TODO: aboutRecipesScreen требует recipe slug, в уведомлении только id — навигация отключена
|
||||
} else if (type.contains('Plan')) {
|
||||
// TODO: aboutPlanScreen требует slug плана, в уведомлении только id — навигация отключена
|
||||
} else if (type.contains('Diet')) {
|
||||
if (id > 0) {
|
||||
context.push(RouteConstants.aboutDietScreen, extra: {'id': id, 'highlightedCommentId': commentId});
|
||||
}
|
||||
void _navigateToEntity(BuildContext context, CommentedEntityType type, int id, int? commentId) {
|
||||
switch (type) {
|
||||
case CommentedEntityType.blogPost:
|
||||
context.push(RouteConstants.blogPostScreen, extra: {'id': id, 'highlightedCommentId': commentId});
|
||||
case CommentedEntityType.diet:
|
||||
if (id > 0) {
|
||||
context.push(RouteConstants.aboutDietScreen, extra: {'id': id, 'highlightedCommentId': commentId});
|
||||
}
|
||||
case CommentedEntityType.unknown:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +183,6 @@ class _PlanSubscriptionCanceledToAuthorWidget extends StatelessWidget {
|
||||
final PlanSubscriptionCanceledToAuthorNotification notification;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return _BaseNotificationWidget(
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Отмена подписки. Клиент ${notification.customerName} отказался от плана "${notification.planName}"',
|
||||
@@ -201,7 +199,6 @@ class _ChosenPlanStartedToClientWidget extends StatelessWidget {
|
||||
final ChosenPlanStartedToClientNotification notification;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return _BaseNotificationWidget(
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Ваш план "${notification.planName}" начался! Удачи! 🚀',
|
||||
@@ -218,7 +215,6 @@ class _ChosenPlanTomorrowReminderToClientWidget extends StatelessWidget {
|
||||
final ChosenPlanTomorrowReminderToClientNotification notification;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return _BaseNotificationWidget(
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Напоминание: Завтра старт плана "${notification.planName}"',
|
||||
@@ -250,7 +246,6 @@ class _ConsultantLeftCommentWidget extends StatelessWidget {
|
||||
final ConsultantLeftCommentNotification notification;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return _BaseNotificationWidget(
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Новый комментарий от консультанта (за ${notification.date.format('dd.MM.yyyy')})',
|
||||
@@ -283,7 +278,6 @@ class _ChosenPlanFinishedToClientWidget extends StatelessWidget {
|
||||
final ChosenPlanFinishedToClientNotification notification;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return _BaseNotificationWidget(
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Поздравляем! План «${notification.planName}» успешно завершен! 🏆',
|
||||
@@ -297,7 +291,6 @@ class _PlanSubscriptionCanceledToCustomerWidget extends StatelessWidget {
|
||||
final PlanSubscriptionCanceledToCustomerNotification notification;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return _BaseNotificationWidget(
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Подписка на план "${notification.planName}" отменена.',
|
||||
@@ -311,7 +304,6 @@ class _ChosenPlanStartedToConsultantWidget extends StatelessWidget {
|
||||
final ChosenPlanStartedToConsultantNotification notification;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return _BaseNotificationWidget(
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Начало работы: План "${notification.planName}" с клиентом ${notification.customerName}',
|
||||
@@ -325,7 +317,6 @@ class _ChosenPlanTomorrowReminderToConsultantWidget extends StatelessWidget {
|
||||
final ChosenPlanTomorrowReminderToConsultantNotification notification;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return _BaseNotificationWidget(
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Напоминание: Завтра старт работы с ${notification.customerName} по плану "${notification.planName}"',
|
||||
@@ -339,7 +330,6 @@ class _PlanSubscriptionPaidToAuthorWidget extends StatelessWidget {
|
||||
final PlanSubscriptionPaidToAuthorNotification notification;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return _BaseNotificationWidget(
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Оплата получена! Клиент ${notification.customerName} оплатил план "${notification.planName}" 💰',
|
||||
@@ -548,11 +538,6 @@ class _ComplaintToModerationForUserWidget extends StatelessWidget {
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Ваша жалоба принята и находится на модерации.',
|
||||
createdAt: notification.createdAt,
|
||||
onTap: (['Plan', 'Recipe'].contains(notification.entityType) || notification.entityId <= 0 || notification.entityType.isEmpty)
|
||||
? null
|
||||
: () {
|
||||
_navigateToEntity(context, notification.entityType, notification.entityId, null);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -566,7 +551,7 @@ class _CommentRepliedWidget extends StatelessWidget {
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Вам ответили в комментариях к: ${notification.entityName}',
|
||||
createdAt: notification.createdAt,
|
||||
onTap: (['Plan', 'Recipe'].contains(notification.commentedEntityType) || notification.commentedEntityId <= 0 || notification.commentId == null)
|
||||
onTap: (notification.commentedEntityType == CommentedEntityType.unknown || notification.commentedEntityId <= 0)
|
||||
? null
|
||||
: () {
|
||||
_navigateToEntity(context, notification.commentedEntityType, notification.commentedEntityId, notification.commentId);
|
||||
@@ -600,9 +585,11 @@ class _EntityCommentedWidget extends StatelessWidget {
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Новый комментарий к вашей публикации "${notification.entityTranslatedType}": ${notification.entityName}',
|
||||
createdAt: notification.createdAt,
|
||||
onTap: () {
|
||||
_navigateToEntity(context, notification.entityType, notification.entityId, notification.commentId);
|
||||
},
|
||||
onTap: (notification.entityType == CommentedEntityType.unknown || notification.entityId <= 0)
|
||||
? null
|
||||
: () {
|
||||
_navigateToEntity(context, notification.entityType, notification.entityId, notification.commentId);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user