private void SaveNotification(int challengeEntryId, ChallengeNotification challengeNotification)
        {
            using var serviceScope = Context.CreateScope();
            var notificationPersistence = ServiceScopeHelper.GetService <NotificationPersistence>(serviceScope);

            var _ = notificationPersistence.AddToDb(challengeEntryId, challengeNotification);
        }
        public SignalRActor()
        {
            Receive <ChallengeEntrySavedMessage>(message =>
            {
                using var serviceScope  = Context.CreateScope();
                var challengeHubContext = ServiceScopeHelper.GetService <IHubContext <ChallengeHub> >(serviceScope);

                challengeHubContext.Clients.All.SendAsync(
                    "NewChallengeIssued",
                    message.ChallengeEntry.Id,
                    message.ChallengeEntry.CommunityName,
                    message.ChallengeEntry.FromPlayer,
                    message.ChallengeEntry.ToPlayer,
                    message.ChallengeEntry.Status.ToString(),
                    message.ChallengeEntry.Date.FormatDateTime());
            });

            Receive <ChallengeStatusUpdatedMessage>(message =>
            {
                using var serviceScope  = Context.CreateScope();
                var challengeHubContext = ServiceScopeHelper.GetService <IHubContext <ChallengeHub> >(serviceScope);

                challengeHubContext.Clients.All.SendAsync(
                    "ChallengeStatusChanged",
                    message.ChallengeEntry.Id,
                    message.NewStatus.ToString());
            });
        }
        public ChallengeActor()
        {
            Receive <ChallengeIssuedMessage>(message =>
            {
                using var serviceScope   = Context.CreateScope();
                var challengePersistence = ServiceScopeHelper.GetService <ChallengePersistence>(serviceScope);

                var eventStream = Context.System.EventStream;

                var newChallenge = new ChallengeEntry
                {
                    CommunityName = message.SendChallengeModel.CommunityName,
                    FromPlayer    = message.SendChallengeModel.FromPlayer,
                    ToPlayer      = message.SendChallengeModel.ToPlayer,
                    Status        = ChallengeStatus.Challenging,
                    Date          = message.TimeStamp
                };

                challengePersistence.AddToDb(newChallenge).ContinueWith(saveChallengeTask =>
                                                                        eventStream.Publish(new ChallengeEntrySavedMessage(ChallengeEntry: saveChallengeTask.Result)));
            });

            Receive <FirebaseInitialChallengeNotificationSentMessage>(message =>
                                                                      UpdateStatusForChallengeEntry(
                                                                          message.ChallengeEntry.Id, ChallengeStatus.Challenged, message.ChallengeNotification.Date));

            Receive <ChallengeAcceptedMessage>(message =>
                                               UpdateStatusForChallengeEntry(message.ChallengeEntryId, ChallengeStatus.Accepting, message.TimeStamp));

            Receive <ChallengeDeclinedMessage>(message =>
                                               UpdateStatusForChallengeEntry(message.ChallengeEntryId, ChallengeStatus.Declining, message.TimeStamp));

            Receive <FirebaseChallengeResponseNotificationSentMessage>(message =>
            {
                var newStatus = message.ChallengeNotification.Type == NotificationType.Accepted
                    ? ChallengeStatus.Accepted
                    : ChallengeStatus.Declined;
                UpdateStatusForChallengeEntry(message.ChallengeEntry.Id, newStatus, message.ChallengeNotification.Date);
            });

            Receive <GetChallengesMessage>(_ =>
            {
                var serviceScope         = Context.CreateScope();
                var challengePersistence = ServiceScopeHelper.GetService <ChallengePersistence>(serviceScope);

                challengePersistence
                .GetAllFromDb()
                .ContinueWith(getChallengesTask =>
                {
                    serviceScope.Dispose();
                    return(new GetChallengesResponse(ChallengeEntries: getChallengesTask.Result));
                })
                .PipeTo(Sender);
            });
        }
        private void UpdateStatusForChallengeEntry(int challengeEntryId, ChallengeStatus newStatus, DateTime timestamp)
        {
            using var serviceScope = Context.CreateScope();
            var challengePersistence = ServiceScopeHelper.GetService <ChallengePersistence>(serviceScope);

            var eventStream = Context.System.EventStream;

            challengePersistence.UpdateStatusInDb(challengeEntryId, newStatus, timestamp)
            .ContinueWith(updateTask =>
                          eventStream.Publish(
                              new ChallengeStatusUpdatedMessage
                                  (ChallengeEntry: updateTask.Result, NewStatus: newStatus)));
        }
        private void SendResponseViaFirebaseAndPublishEvent(
            ChallengeEntry challengeEntry, NotificationType notificationType)
        {
            using var serviceScope = Context.CreateScope();
            var firebaseMessagingService = ServiceScopeHelper.GetService <FirebaseMessagingService>(serviceScope);

            var eventStream = Context.System.EventStream;

            firebaseMessagingService.SendMessageWithResponseToChallenge(challengeEntry, notificationType)
            .ContinueWith(sendToFirebaseTask =>
                          eventStream.Publish(
                              new FirebaseChallengeResponseNotificationSentMessage
                              (
                                  ChallengeEntry: challengeEntry,
                                  ChallengeNotification: sendToFirebaseTask.Result
                              )));
        }
        public NotificationActor()
        {
            Receive <FirebaseInitialChallengeNotificationSentMessage>(message =>
                                                                      SaveNotification(message.ChallengeEntry.Id, message.ChallengeNotification));

            Receive <FirebaseChallengeResponseNotificationSentMessage>(message =>
                                                                       SaveNotification(message.ChallengeEntry.Id, message.ChallengeNotification));

            Receive <GetNotificationsMessage>(_ =>
            {
                var serviceScope            = Context.CreateScope();
                var notificationPersistence = ServiceScopeHelper.GetService <NotificationPersistence>(serviceScope);

                notificationPersistence
                .GetAllFromDb()
                .ContinueWith(getNotificationsTask =>
                {
                    serviceScope.Dispose();
                    return(new GetNotificationsResponse(Notifications: getNotificationsTask.Result));
                })
                .PipeTo(Sender);
            });
        }
        public FirebaseActor()
        {
            Receive <ChallengeEntrySavedMessage>(message =>
            {
                using var serviceScope       = Context.CreateScope();
                var firebaseMessagingService =
                    ServiceScopeHelper.GetService <FirebaseMessagingService>(serviceScope);

                var eventStream = Context.System.EventStream;
                firebaseMessagingService.SendMessageWithInitialChallenge(message.ChallengeEntry)
                .ContinueWith(sendToFirebaseTask =>
                              eventStream.Publish(
                                  new FirebaseInitialChallengeNotificationSentMessage
                                  (
                                      ChallengeEntry: message.ChallengeEntry,
                                      ChallengeNotification: sendToFirebaseTask.Result
                                  )));
            });

            Receive <ChallengeStatusUpdatedMessage>(message =>
            {
                switch (message.NewStatus)
                {
                case ChallengeStatus.Accepting:
                    SendResponseViaFirebaseAndPublishEvent(message.ChallengeEntry, NotificationType.Accepted);
                    break;

                case ChallengeStatus.Declining:
                    SendResponseViaFirebaseAndPublishEvent(message.ChallengeEntry, NotificationType.Declined);
                    break;

                default:
                    // No Firebase action required for other status changes
                    return;
                }
            });
        }