forked from eatvio/eatvio_app
created notifications model and logic of type based parsing
This commit is contained in:
@@ -18,8 +18,7 @@ class WsManager {
|
|||||||
PrivateChannel? _privateDirectChatChannel;
|
PrivateChannel? _privateDirectChatChannel;
|
||||||
|
|
||||||
Stream<ChannelReadEvent>? get newMessagesStream => _privateMessagesChannel?.bind('App\\Events\\ChatMessageUpdated');
|
Stream<ChannelReadEvent>? get newMessagesStream => _privateMessagesChannel?.bind('App\\Events\\ChatMessageUpdated');
|
||||||
|
|
||||||
// TODO: change name of event to a right one
|
|
||||||
Stream<ChannelReadEvent>? get newNotificationsStream => _privateNotificationChannel?.bind('Illuminate\\Notifications\\Events\\BroadcastNotificationCreated');
|
Stream<ChannelReadEvent>? get newNotificationsStream => _privateNotificationChannel?.bind('Illuminate\\Notifications\\Events\\BroadcastNotificationCreated');
|
||||||
|
|
||||||
Stream<ChannelReadEvent>? get directChatStream => _privateDirectChatChannel?.bind('App\\Events\\ChatMessageUpdated');
|
Stream<ChannelReadEvent>? get directChatStream => _privateDirectChatChannel?.bind('App\\Events\\ChatMessageUpdated');
|
||||||
|
|||||||
@@ -1,25 +1,298 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
part 'notification_model.freezed.dart';
|
abstract class BaseNotificationModel {
|
||||||
part 'notification_model.g.dart';
|
abstract final NotificationType type;
|
||||||
|
|
||||||
@freezed
|
|
||||||
class NotificationModel with _$NotificationModel {
|
|
||||||
|
|
||||||
factory NotificationModel({
|
|
||||||
required NotificationType type
|
|
||||||
}) = _NotificationModel;
|
|
||||||
|
|
||||||
factory NotificationModel.fromJson(Map<String, dynamic> json) => _$NotificationModelFromJson(json);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PlanSubscriptionStartedToAuthorNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final String planName;
|
||||||
|
final String customerName;
|
||||||
|
final String chatId;
|
||||||
|
|
||||||
|
PlanSubscriptionStartedToAuthorNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.planName,
|
||||||
|
required this.customerName,
|
||||||
|
required this.chatId,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PlanSubscriptionStartedToAuthorNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory PlanSubscriptionStartedToAuthorNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlanSubscriptionCanceledToAuthorNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final String planName;
|
||||||
|
final String customerName;
|
||||||
|
|
||||||
|
PlanSubscriptionCanceledToAuthorNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.planName,
|
||||||
|
required this.customerName,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PlanSubscriptionCanceledToAuthorNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory PlanSubscriptionCanceledToAuthorNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChosenPlanStartedToClientNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final String planName;
|
||||||
|
final int planId;
|
||||||
|
|
||||||
|
ChosenPlanStartedToClientNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.planName,
|
||||||
|
required this.planId,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ChosenPlanStartedToClientNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory ChosenPlanStartedToClientNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChosenPlanTomorrowReminderToClientNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final String planName;
|
||||||
|
|
||||||
|
ChosenPlanTomorrowReminderToClientNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.planName,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ChosenPlanTomorrowReminderToClientNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory ChosenPlanTomorrowReminderToClientNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DiaryReminderNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
|
||||||
|
DiaryReminderNotification({required this.type});
|
||||||
|
|
||||||
|
factory DiaryReminderNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory DiaryReminderNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConsultantLeftCommentNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final DateTime date;
|
||||||
|
|
||||||
|
ConsultantLeftCommentNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.date,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ConsultantLeftCommentNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory ConsultantLeftCommentNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PersonalizedDietIsDefinedNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
|
||||||
|
PersonalizedDietIsDefinedNotification({required this.type});
|
||||||
|
|
||||||
|
factory PersonalizedDietIsDefinedNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory PersonalizedDietIsDefinedNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChosenPlanFinishedToClientNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final String planName;
|
||||||
|
ChosenPlanFinishedToClientNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.planName,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ChosenPlanFinishedToClientNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory ChosenPlanFinishedToClientNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlanSubscriptionCanceledToCustomerNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final String planName;
|
||||||
|
PlanSubscriptionCanceledToCustomerNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.planName,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PlanSubscriptionCanceledToCustomerNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory PlanSubscriptionCanceledToCustomerNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChosenPlanStartedToConsultantNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final String planName;
|
||||||
|
final String customerName;
|
||||||
|
ChosenPlanStartedToConsultantNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.planName,
|
||||||
|
required this.customerName,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ChosenPlanStartedToConsultantNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory ChosenPlanStartedToConsultantNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChosenPlanTomorrowReminderToConsultantNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final String planName;
|
||||||
|
final String customerName;
|
||||||
|
ChosenPlanTomorrowReminderToConsultantNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.planName,
|
||||||
|
required this.customerName,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ChosenPlanTomorrowReminderToConsultantNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory ChosenPlanTomorrowReminderToConsultantNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlanSubscriptionPaidToAuthorNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final String planName;
|
||||||
|
final String customerName;
|
||||||
|
PlanSubscriptionPaidToAuthorNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.planName,
|
||||||
|
required this.customerName,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PlanSubscriptionPaidToAuthorNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory PlanSubscriptionPaidToAuthorNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChosenPlanFinishedToConsultantNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
final String planName;
|
||||||
|
final String customerName;
|
||||||
|
final int planId;
|
||||||
|
ChosenPlanFinishedToConsultantNotification({
|
||||||
|
required this.type,
|
||||||
|
required this.planName,
|
||||||
|
required this.customerName,
|
||||||
|
required this.planId,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ChosenPlanFinishedToConsultantNotification.fromRest(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory ChosenPlanFinishedToConsultantNotification.fromWebSocket(Map<String, dynamic> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnknownNotification implements BaseNotificationModel {
|
||||||
|
@override
|
||||||
|
final NotificationType type;
|
||||||
|
UnknownNotification({
|
||||||
|
required this.type,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
enum NotificationType {
|
enum NotificationType {
|
||||||
@JsonValue('App\\Notifications\\UserSubscribedNotification')
|
|
||||||
userSubscribedNotification,
|
|
||||||
@JsonValue('App\\Notifications\\Plan\\PlanSubscriptionStartedToAuthor')
|
|
||||||
planSubscriptionStartedToAuthor,
|
planSubscriptionStartedToAuthor,
|
||||||
@JsonValue('App\\Notifications\\Plan\\PlanSubscriptionCanceledToAuthor')
|
|
||||||
planSubscriptionCanceledToAuthor,
|
planSubscriptionCanceledToAuthor,
|
||||||
|
chosenPlanStartedToClientNotification,
|
||||||
}
|
chosenPlanTomorrowReminderToClientNotification,
|
||||||
|
diaryReminderNotification,
|
||||||
|
consultantLeftComment,
|
||||||
|
personalizedDietIsDefined,
|
||||||
|
chosenPlanFinishedToClient,
|
||||||
|
planSubscriptionCanceledToCustomer,
|
||||||
|
chosenPlanStartedToConsultantNotification,
|
||||||
|
chosenPlanTomorrowReminderToConsultantNotification,
|
||||||
|
planSubscriptionPaidToAuthor,
|
||||||
|
chosenPlanFinishedToConsultant,
|
||||||
|
unknown;
|
||||||
|
|
||||||
|
static NotificationType getTypeFromString(String type) => switch (type) {
|
||||||
|
'App\\Notifications\\Plan\\PlanSubscriptionStartedToAuthor' => NotificationType.planSubscriptionStartedToAuthor,
|
||||||
|
'App\\Notifications\\Plan\\PlanSubscriptionCanceledToAuthor' => NotificationType.planSubscriptionCanceledToAuthor,
|
||||||
|
'App\\Notifications\\Plan\\ChosenPlanStartedToClientNotification' => NotificationType.chosenPlanStartedToClientNotification,
|
||||||
|
'App\\Notifications\\Plan\\ChosenPlanTomorrowReminderToClientNotification' => NotificationType.chosenPlanStartedToClientNotification,
|
||||||
|
'App\\Notifications\\DiaryReminderNotification' => NotificationType.diaryReminderNotification,
|
||||||
|
'App\\Notifications\\Plan\\ConsultantLeftComment' => NotificationType.consultantLeftComment,
|
||||||
|
'App\\Notifications\\Plan\\PersonalizedDietIsDefined' => NotificationType.personalizedDietIsDefined,
|
||||||
|
'App\\Notifications\\Plan\\ChosenPlanFinishedToClient' => NotificationType.chosenPlanFinishedToClient,
|
||||||
|
'App\\Notifications\\Plan\\PlanSubscriptionCanceledToCustomer' => NotificationType.planSubscriptionCanceledToCustomer,
|
||||||
|
'App\\Notifications\\Plan\\ChosenPlanStartedToConsultantNotification' => NotificationType.chosenPlanStartedToConsultantNotification,
|
||||||
|
'App\\Notifications\\Plan\\ChosenPlanTomorrowReminderToConsultantNotification' => NotificationType.chosenPlanTomorrowReminderToConsultantNotification,
|
||||||
|
'App\\Notifications\\Plan\\PlanSubscriptionPaidToAuthor' => NotificationType.planSubscriptionPaidToAuthor,
|
||||||
|
'App\\Notifications\\Plan\\ChosenPlanFinishedToConsultant' => NotificationType.chosenPlanFinishedToConsultant,
|
||||||
|
_ => NotificationType.unknown,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import 'package:eatvio_app/features/notifications/presentation/notifications_cub
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
class NotificationsCubit extends Cubit<NotificationsState> {
|
class NotificationsCubit extends Cubit<NotificationsState> {
|
||||||
final List<NotificationModel> _notifications = [];
|
final List<BaseNotificationModel> _notifications = [];
|
||||||
final WsManager wsManager;
|
final WsManager wsManager;
|
||||||
|
|
||||||
NotificationsCubit({required this.wsManager}) : super(const NotificationsState.empty()) {
|
NotificationsCubit({required this.wsManager}) : super(const NotificationsState.empty()) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ abstract class NotificationsState with _$NotificationsState {
|
|||||||
const factory NotificationsState.empty() = NotificationsStateEmpty;
|
const factory NotificationsState.empty() = NotificationsStateEmpty;
|
||||||
|
|
||||||
const factory NotificationsState.loaded({
|
const factory NotificationsState.loaded({
|
||||||
required List<NotificationModel> notifications,
|
required List<BaseNotificationModel> notifications,
|
||||||
required int notificationsCount,
|
required int notificationsCount,
|
||||||
}) = NotificationsStateLoaded;
|
}) = NotificationsStateLoaded;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
class NotificationWidget extends StatelessWidget {
|
class NotificationWidget extends StatelessWidget {
|
||||||
const NotificationWidget({super.key, required this.notification});
|
const NotificationWidget({super.key, required this.notification});
|
||||||
final NotificationModel notification;
|
final BaseNotificationModel notification;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// return (notification.type) {
|
// return (notification.type) {
|
||||||
@@ -12,4 +12,3 @@ class NotificationWidget extends StatelessWidget {
|
|||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:eatvio_app/features/notifications/models/notification_model.dart';
|
||||||
|
import 'package:eatvio_app/features/notifications/service/notifications_service.dart';
|
||||||
|
|
||||||
|
class NotificationsRepository {
|
||||||
|
final NotificationsService notificationsService;
|
||||||
|
NotificationsRepository({required this.notificationsService});
|
||||||
|
|
||||||
|
Future<List<BaseNotificationModel>?> getNotifications({required int page}) {
|
||||||
|
try {
|
||||||
|
return notificationsService.getNotifications(page: page);
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:eatvio_app/features/notifications/models/notification_model.dart';
|
||||||
|
|
||||||
|
class NotificationsService {
|
||||||
|
final Dio dio;
|
||||||
|
NotificationsService(this.dio);
|
||||||
|
|
||||||
|
Future<List<BaseNotificationModel>?> getNotifications({required int page}) async {
|
||||||
|
try {
|
||||||
|
final response = await dio.get('api/profile/notifications?page=$page');
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
final data = response.data['data'] as List<Map<String, dynamic>>;
|
||||||
|
final notifications = data.map((notificationJson) {
|
||||||
|
final stringifiedType = notificationJson['data']['notification_class_name'];
|
||||||
|
final type = NotificationType.getTypeFromString(stringifiedType);
|
||||||
|
return switch (type) {
|
||||||
|
NotificationType.planSubscriptionStartedToAuthor => PlanSubscriptionStartedToAuthorNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.planSubscriptionCanceledToAuthor => PlanSubscriptionCanceledToAuthorNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.chosenPlanStartedToClientNotification => ChosenPlanStartedToClientNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.chosenPlanTomorrowReminderToClientNotification => ChosenPlanTomorrowReminderToClientNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.diaryReminderNotification => DiaryReminderNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.consultantLeftComment => ConsultantLeftCommentNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.personalizedDietIsDefined => PersonalizedDietIsDefinedNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.chosenPlanFinishedToClient => ChosenPlanFinishedToClientNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.planSubscriptionCanceledToCustomer => PlanSubscriptionCanceledToAuthorNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.chosenPlanStartedToConsultantNotification => ChosenPlanStartedToConsultantNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.chosenPlanTomorrowReminderToConsultantNotification =>
|
||||||
|
ChosenPlanTomorrowReminderToConsultantNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.planSubscriptionPaidToAuthor => PlanSubscriptionPaidToAuthorNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.chosenPlanFinishedToConsultant => ChosenPlanFinishedToConsultantNotification.fromRest(notificationJson),
|
||||||
|
NotificationType.unknown => UnknownNotification(type: type),
|
||||||
|
};
|
||||||
|
}).toList();
|
||||||
|
return notifications;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user