コード例 #1
0
        /// <summary>
        /// Sets the theme for the app.
        /// </summary>
        async Task SetAppTheme(AppThemeViewModel theme)
        {
            try
            {
                Application.Current.UserAppTheme = theme.Key;
                Settings.AppTheme = theme.Key;

                foreach (var item in AppThemes)
                {
                    item.IsSelected = false;
                }

                AppThemes.FirstOrDefault(x => x.Key == Settings.AppTheme).IsSelected = true;
                RaisePropertyChanged(nameof(AppThemes));

                //var statusBar = DependencyService.Get<IStatusBar>();
                //statusBar?.SetStatusBarColor((OSAppTheme)theme.Key, Color.Black);

                HapticFeedback.Perform(HapticFeedbackType.Click);

                AnalyticsService.Track("App Theme Changed", nameof(theme), ((OSAppTheme)theme.Key).ToString() ?? "null");
            }
            catch (Exception ex)
            {
                await DialogService.AlertAsync(Translations.error_couldntchangetheme, Translations.error_title, Translations.ok).ConfigureAwait(false);

                AnalyticsService.Report(ex);
            }
        }
コード例 #2
0
ファイル: IntroViewModel.cs プロジェクト: rayxxi/MVP
        async Task SignIn()
        {
            try
            {
                // Pop a sign in request up for the user.
                if (await AuthService.SignInAsync().ConfigureAwait(false))
                {
                    AnalyticsService.Track("User Logged In");

                    MainThread.BeginInvokeOnMainThread(() =>
                    {
                        NavigationHelper.SetRootView(nameof(TabbedMainPage), false);
                    });
                }
                else
                {
                    AnalyticsService.Track("Invalid MVP Account Used");
                    await DialogService.AlertAsync(Resources.Translations.error_nomvpaccount, Resources.Translations.error_title, Resources.Translations.ok);
                }
            }
            catch (Exception e)
            {
                AnalyticsService.Report(e);

                await DialogService.AlertAsync(Resources.Translations.error_unexpected, Resources.Translations.error_title, Resources.Translations.ok);
            }
        }
コード例 #3
0
        private async Task <bool> ValidateSave()
        {
            string msg = "";

            if (string.IsNullOrEmpty(CurrentPixKey?.Key))
            {
                msg += "- Chave não informada\n";
            }

            if (string.IsNullOrEmpty(CurrentPixKey?.Name))
            {
                msg += "- Nome não informado\n";
            }

            if (string.IsNullOrEmpty(CurrentPixKey?.City))
            {
                msg += "- Cidade não informada\n";
            }

            //if (string.IsNullOrEmpty(CurrentPixKey?.FinancialInstitution?.Name))
            //    msg += "- Selecione uma instituição financeira\n";

            if (!string.IsNullOrEmpty(msg))
            {
                await DialogService.AlertAsync(msg, "Ops! Parece que faltou algo");

                return(false);
            }

            return(true);
        }
コード例 #4
0
        async Task SignIn()
        {
            try
            {
                // Pop a sign in request up for the user.
                if (await AuthService.SignInAsync().ConfigureAwait(false))
                {
                    AnalyticsService.Track("User Logged In");

                    MainThread.BeginInvokeOnMainThread(() =>
                    {
                        NavigationHelper.SetRootView(nameof(TabbedMainPage), false);
                    });
                }
                else
                {
                    if (Device.RuntimePlatform == Device.iOS)
                    {
                        await OpenModalAsync(nameof(LoginPage), null, true);
                    }
                    else
                    {
                        await NavigateAsync(nameof(LoginPage), null);
                    }
                }
            }
            catch (Exception e)
            {
                AnalyticsService.Report(e);
                await DialogService.AlertAsync(Resources.Translations.error_unexpected, Resources.Translations.error_title, Resources.Translations.ok);
            }
        }
コード例 #5
0
        private async Task LoginAsync()
        {
            IsBusy = true;

            try
            {
                var logged = await userService.LoginAsync();

                if (logged)
                {
                    NavigationService.NavigateTo(Constants.HomePage, HistoryBehavior.ClearHistory);
                }
            }
            catch (InvalidOperationException)
            {
                /* Authentication was canceled by the user. */
                IsBusy = false;
            }
            catch
            {
                await DialogService.AlertAsync("An error occurred while logging in.");

                IsBusy = false;
            }
        }
コード例 #6
0
 protected virtual async void OnNetworkAvailabilityChanged()
 {
     if (!IsConnected)
     {
         await DialogService.AlertAsync("The device seems to be offline. Check your Internet connection.", "Network");
     }
 }
コード例 #7
0
        private async Task AcceptProofRequest()
        {
            if (_proofRecord.State != ProofState.Requested)
            {
                await DialogService.AlertAsync(string.Format(AppResources.ProofStateShouldBeMessage, ProofStateTranslator.Translate(ProofState.Requested)));

                return;
            }

            RequestedCredentials requestedCredentials = new RequestedCredentials()
            {
                RequestedAttributes = new Dictionary <string, RequestedAttribute>(),
                RequestedPredicates = new Dictionary <string, RequestedAttribute>()
            };

            foreach (ProofAttributeViewModel proofAttribute in Attributes)
            {
                if (proofAttribute.IsPredicate)
                {
                    requestedCredentials.RequestedPredicates.Add(proofAttribute.Id, new RequestedAttribute {
                        CredentialId = proofAttribute.CredentialId, Revealed = proofAttribute.IsRevealed
                    });
                }
                else
                {
                    requestedCredentials.RequestedAttributes.Add(proofAttribute.Id, new RequestedAttribute {
                        CredentialId = proofAttribute.CredentialId, Revealed = proofAttribute.IsRevealed
                    });
                }
            }

            // TODO: Mettre le Timestamp à null car lorsqu'il est présent, la création de la preuve ne marche pas. Pourquoi?
            //foreach (var keyValue in requestedCredentials.RequestedAttributes.Values)
            //{
            //    keyValue.Timestamp = null;
            //}

            var context = await _agentContextProvider.GetContextAsync();

            ProofRecord proofRecord = await _recordService.GetAsync <ProofRecord>(context.Wallet, _proofRecord.Id);

            var(msg, rec) = await _proofService.CreatePresentationAsync(context, proofRecord.Id, requestedCredentials);

            if (string.IsNullOrEmpty(proofRecord.ConnectionId))
            {
                await _messageService.SendAsync(context.Wallet, msg, proofRecord.GetTag("RecipientKey"), proofRecord.GetTag("ServiceEndpoint"));
            }
            else
            {
                ConnectionRecord connectionRecord = await _recordService.GetAsync <ConnectionRecord>(context.Wallet, proofRecord.ConnectionId);

                await _messageService.SendAsync(context.Wallet, msg, connectionRecord);
            }

            _eventAggregator.Publish(new ApplicationEvent {
                Type = ApplicationEventType.ProofRequestUpdated
            });

            await NavigationService.PopModalAsync();
        }
コード例 #8
0
        private async Task LoginAsync()
        {
            IsBusy      = true;
            IsLoggingIn = true;

            try
            {
                var isLogged = await userService.LoginAsync();

                this.CheckLoginResult(isLogged);
            }
            catch (InvalidOperationException)
            {
                /* Authentication was canceled by the user. */
            }
            catch
            {
                await DialogService.AlertAsync("An error occurred while logging in.");
            }
            finally
            {
                IsBusy      = false;
                IsLoggingIn = false;
            }
        }
コード例 #9
0
        private async void Alert(object sender, RoutedEventArgs e)
        {
            Log("Showing alert");
            var resolver = UseCustomResourceResolver.IsChecked.Value ? new CustomResolver() : null;
            var result   = await _dialog.AlertAsync(AlertTextBox.Text, resolver);

            Log($"Alert result: {result}");
        }
コード例 #10
0
ファイル: BaseViewModel.cs プロジェクト: rayxxi/MVP
        protected async Task <bool> VerifyInternetConnection()
        {
            if (Connectivity.NetworkAccess != NetworkAccess.Internet)
            {
                // Connection to internet is not available
                await DialogService.AlertAsync(Translations.error_offline, Translations.error_offline_title, Translations.ok).ConfigureAwait(false); return(false);
            }

            return(true);
        }
コード例 #11
0
        private async void ExecuteVerificarPokemonCommand()
        {
            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
            {
                await DialogService.AlertAsync("Erro na Camera", "Camera indisponivel.", "OK");

                return;
            }

            var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
            {
                Directory = "Pokemons",
                Name      = $"pokemon{DateTime.Now.ToString("ddMMyyyyHHmmss")}.jpg",
                PhotoSize = PhotoSize.Small
            });



            if (file == null)
            {
                await DialogService.AlertAsync("Erro na Camera", "Erro ao capturar a imagem.", "OK");

                return;
            }

            string  result  = string.Empty;
            Pokemon pokemon = null;

            using (var Dialog = UserDialogs.Instance.Loading("Processando..", null, null, true, MaskType.Black))
            {
                var fileInfo = new FileInfo(file.Path);

                result = await _CustomVision.GetClassifyImage(file);

                if (string.IsNullOrEmpty(result))
                {
                    await DialogService.AlertAsync("Pokedex", "Pokemon não encontrado.", "OK");

                    return;
                }

                pokemon = await _PokemonService.GetPokemon(result);
            }


            if (pokemon != null)
            {
                var parametros = new NavigationParameters();
                parametros.Add("pokemon", pokemon);

                await NavigationService.NavigateToAsync <PokemonViewModel>(parametros);
            }
        }
コード例 #12
0
 async void MvpApiService_RequestErrorOccurred(object sender, Services.Helpers.ApiServiceEventArgs e)
 {
     if (e.IsBadRequest)
     {
         await DialogService.AlertAsync(Translations.error_badrequest, Translations.error_title, Translations.ok);
     }
     else if (e.IsServerError)
     {
         await DialogService.AlertAsync(Translations.error_servererror, Translations.error_title, Translations.ok);
     }
 }
コード例 #13
0
        /// <summary>
        /// Deletes a contribution.
        /// </summary>
        async Task DeleteContribution()
        {
            try
            {
                // Shouldn't be getting here anyway, so no need for a message.
                if (!CanBeEdited)
                {
                    return;
                }

                if (!await VerifyInternetConnection())
                {
                    return;
                }
                // Ask for confirmation before deletion.
                var confirm = await DialogService.ConfirmAsync(Translations.contributiondetail_deleteconfirmation, Translations.warning_title, Translations.ok, Translations.cancel).ConfigureAwait(false);

                if (!confirm)
                {
                    return;
                }

                State = LayoutState.Loading;

                var isDeleted = await MvpApiService.DeleteContributionAsync(Contribution);

                if (isDeleted)
                {
                    // TODO: Pass back true to indicate it needs to refresh.
                    // TODO: Be a bit more sensible with muh threads plz.
                    MainThread.BeginInvokeOnMainThread(() => HapticFeedback.Perform(HapticFeedbackType.LongPress));
                    AnalyticsService.Track("Contribution Deleted");
                    await MainThread.InvokeOnMainThreadAsync(() => BackAsync());

                    //MessagingService.Current.SendMessage(MessageKeys.HardRefreshNeeded);
                    MessagingService.Current.SendMessage(MessageKeys.HardRefreshNeeded);
                }
                else
                {
                    await DialogService.AlertAsync(Translations.contributiondetail_notdeleted, Translations.error_title, Translations.ok).ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                AnalyticsService.Report(ex);
                await DialogService.AlertAsync(Translations.error_unexpected, Translations.error_title, Translations.ok).ConfigureAwait(false);
            }
            finally
            {
                State = LayoutState.None;
            }
        }
コード例 #14
0
        public async Task <bool> IsGalleryGrantedAsync()
        {
            var isGranted = await _permissionService.RequestPermissionAsync(FeaturePermission.Photos) == PermissionStatus.Granted;

            if (!isGranted)
            {
                await DialogService.AlertAsync("Allow using media library to pick photo", "Library usage", "OK");

                Cancel();
            }

            return(isGranted);
        }
コード例 #15
0
        public async Task <bool> IsCameraGrantedAsync()
        {
            var isGranted = await _permissionService.RequestPermissionAsync(FeaturePermission.Camera) == PermissionStatus.Granted;

            if (!isGranted)
            {
                await DialogService.AlertAsync("Allow using camera to take photo", "Camera usage", "OK");

                Cancel();
            }

            return(isGranted);
        }
コード例 #16
0
        async Task NavigationOccurred(WebNavigatedEventArgs e)
        {
            switch (e.Result)
            {
            case WebNavigationResult.Success:
                if (e.Url.Contains("code="))
                {
                    var myUri    = new Uri(e.Url);
                    var authCode = myUri.ExtractQueryValue("code");
                    var token    = await App.AuthService.RequestAuthorizationAsync(authCode);

                    if (string.IsNullOrEmpty(token))
                    {
                        // Not authed
                        AnalyticsService.Track("Invalid MVP Account Used");
                        await DialogService.AlertAsync(Resources.Translations.error_nomvpaccount, Resources.Translations.error_title, Resources.Translations.ok);
                    }
                    else
                    {
                        // Authed
                        await BackAsync();

                        AnalyticsService.Track("User Logged In");

                        MainThread.BeginInvokeOnMainThread(() =>
                        {
                            NavigationHelper.SetRootView(nameof(TabbedMainPage), false);
                        });
                    }
                }
                else if (e.Url.Contains("lc="))
                {
                    // Redirect to signin page if there's a bounce
                    WebSource = Constants.SignInUrl;
                }
                break;

            case WebNavigationResult.Failure:
                break;

            case WebNavigationResult.Timeout:
                break;

            case WebNavigationResult.Cancel:
                break;

            default:
                break;
            }
        }
コード例 #17
0
        /// <summary>
        /// Loads more contributions when scrolled to the bottom.
        /// </summary>
        async Task LoadMore()
        {
            if (IsLoadingMore)
            {
                return;
            }

            if (!await VerifyInternetConnection())
            {
                return;
            }

            try
            {
                IsLoadingMore = true;

                var contributionsList = await MvpApiService.GetContributionsAsync(Contributions.Count, pageSize).ConfigureAwait(false);

                if (contributionsList == null)
                {
                    await DialogService.AlertAsync(Translations.error_couldntloadmorecontributions, Translations.error_title, Translations.ok).ConfigureAwait(false);

                    return;
                }

                foreach (var item in contributionsList.Contributions.OrderByDescending(x => x.StartDate))
                {
                    Contributions.Add(item);
                }

                AnalyticsService.Track("More Contributions Loaded");

                // If we've reached the end, change the threshold.
                if (!contributionsList.Contributions.Any())
                {
                    ItemThreshold = -1;
                    return;
                }
            }
            catch (Exception ex)
            {
                AnalyticsService.Report(ex);
                await DialogService.AlertAsync(Translations.error_couldntloadmorecontributions, Translations.error_title, Translations.ok).ConfigureAwait(false);
            }
            finally
            {
                IsLoadingMore = false;
            }
        }
コード例 #18
0
        private async Task RefreshAsync()
        {
            IsBusy = true;

            try
            {
                await timelineService.LoadAsync();
            }
            catch
            {
                await DialogService.AlertAsync("An error occurred while refreshing the timeline.");
            }
            finally
            {
                MessengerInstance.Send(new NotificationMessage(Constants.RefreshCompleted));
                IsBusy = false;
            }
        }
コード例 #19
0
ファイル: LanguagePickerViewModel.cs プロジェクト: rayxxi/MVP
        /// <summary>
        /// Sets the app's language.
        /// </summary>
        async Task SetAppLanguage(LanguageViewModel language)
        {
            try
            {
                languageService.PreferredLanguage = language.CI;

                if (Device.RuntimePlatform == Device.Android)
                {
                    await DialogService.AlertAsync(Translations.please_reboot_app_language_change, Translations.warning_title, Translations.ok);
                }
            }
            catch (Exception ex)
            {
                await DialogService.AlertAsync(Translations.error_couldntchangelanguage, Translations.error_title, Translations.ok).ConfigureAwait(false);

                AnalyticsService.Report(ex);
            }
        }
コード例 #20
0
ファイル: App.xaml.cs プロジェクト: rayxxi/MVP
        /// <summary>
        /// Handles expired access tokens.
        /// </summary>
        async void MvpApiService_AccessTokenExpired(object sender, Services.Helpers.ApiServiceEventArgs e)
        {
            // If the access token expired, we need to sign in again,
            // because we might've lost our auth.
            var result = await AuthService.SignInAsync();

            if (!result)
            {
                // Show a message that data could not be refreshed. Also forward the user back to getting started
                // telling the user that a logout has occurred.
                await DialogService.AlertAsync(Translations.alert_error_unauthorized, Translations.error_title, Translations.ok);

                // Move the user over to Getting Started.
                await AuthService.SignOutAsync();

                var navHelper = Resolver.Resolve <INavigationHelper>();
                navHelper.SetRootView(nameof(IntroPage));
            }
        }
コード例 #21
0
        private async Task SendAsync()
        {
            IsBusy = true;

            try
            {
                // Sends the comment to the mobile app.
                await timelineService.SendCommentAsync(post, message);

                Message = null;
            }
            catch
            {
                await DialogService.AlertAsync("An error occurred while sending the comment.");
            }
            finally
            {
                IsBusy = false;
            }
        }
コード例 #22
0
        private async Task RefreshAsync()
        {
            IsBusy = true;

            try
            {
                await timelineService.LoadCommentsOfAsync(Post);

                RaisePropertyChanged(() => Post);
            }
            catch
            {
                await DialogService.AlertAsync("An error occurred while refreshing comments.");
            }
            finally
            {
                MessengerInstance.Send(new NotificationMessage(Constants.RefreshCompleted));
                IsBusy = false;
            }
        }
コード例 #23
0
        /// <summary>
        /// Sets the app icon to whatever the user chose.
        /// </summary>
        async Task SetAppIcon(AppIconViewModel icon)
        {
            try
            {
                var iconSwitcher = DependencyService.Get <IIconService>();

                if (iconSwitcher == null)
                {
                    return;
                }

                if (icon.Key == AppIcon.Default)
                {
                    await iconSwitcher?.SwitchAppIcon(null);
                }
                else
                {
                    await iconSwitcher?.SwitchAppIcon(icon.Key.ToString());
                }

                Settings.AppIcon = icon.Key;

                foreach (var item in AppIcons)
                {
                    item.IsSelected = false;
                }

                AppIcons.FirstOrDefault(x => x.Key == Settings.AppIcon).IsSelected = true;
                RaisePropertyChanged(nameof(AppIcons));

                HapticFeedback.Perform(HapticFeedbackType.Click);

                AnalyticsService.Track("App Icon Changed", nameof(icon), icon.Key.ToString() ?? "null");
            }
            catch (Exception ex)
            {
                await DialogService.AlertAsync(Translations.error_couldntchangeicon, Translations.error_title, Translations.ok).ConfigureAwait(false);

                AnalyticsService.Report(ex);
            }
        }
コード例 #24
0
        private async Task AcceptCredentialOffer(CredentialRecord credentialRecord)
        {
            if (credentialRecord.State != CredentialState.Offered)
            {
                await DialogService.AlertAsync(string.Format("res-CredentialStateShouldBe", CredentialState.Offered));

                await NavigationService.PopModalAsync();

                return;
            }

            await _poolConfigurator.ConfigurePoolsAsync();

            var context = await _agentContextProvider.GetContextAsync();

            var(msg, rec) = await _credentialService.CreateRequestAsync(context, credentialRecord.Id);

            var connectionRecord = await _connectionService.GetAsync(context, credentialRecord.ConnectionId);

            if (connectionRecord == null)
            {
                //await _messageService.SendAsync(context.Wallet, msg, conectionRecord.TheirVk ?? rec.GetTag("InvitationKey") ?? throw new InvalidOperationException("Cannot locate recipient Key"), conectionRecord.Endpoint.Uri,
                //    conectionRecord.Endpoint?.Verkey == null ? null : conectionRecord.Endpoint.Verkey, conectionRecord.MyVk);
                await DialogService.AlertAsync("Connection-less credentials not supported.");

                return;
            }
            else
            {
                await _messageService.SendAsync(context.Wallet, msg, connectionRecord);
            }

            _eventAggregator.Publish(new ApplicationEvent()
            {
                Type = ApplicationEventType.CredentialUpdated
            });

            await NavigationService.PopModalAsync();
        }
コード例 #25
0
        private async Task SendAsync()
        {
            IsBusy = true;

            try
            {
                // Sends the post to the mobile app.
                await timelineService.SendPostAsync(message, PostOnFacebook);

                Message = null;

                NavigationService.GoBack();
            }
            catch
            {
                await DialogService.AlertAsync("An error occurred while sending the post.");
            }
            finally
            {
                IsBusy = false;
            }
        }
コード例 #26
0
        private async Task RejectCredentialOffer()
        {
            if (_credential.State != CredentialState.Offered)
            {
                await DialogService.AlertAsync(string.Format("res-CredentialStateShouldBe", CredentialState.Offered));

                await NavigationService.PopModalAsync();

                return;
            }

            var context = await _agentContextProvider.GetContextAsync();

            await _credentialService.RejectOfferAsync(context, _credential.Id);

            _eventAggregator.Publish(new ApplicationEvent()
            {
                Type = ApplicationEventType.CredentialUpdated
            });

            await NavigationService.PopModalAsync();
        }
コード例 #27
0
 async Task SignIn()
 {
     try
     {
         // Pop a sign in request up for the user.
         if (await AuthService.SignInAsync().ConfigureAwait(false))
         {
             MainThread.BeginInvokeOnMainThread(() =>
             {
                 NavigationHelper.SetRootView(nameof(TabbedMainPage), false);
             });
         }
         else
         {
             await DialogService.AlertAsync("Couldn't authenticate you using the provided credentials. Are you sure you are using the account associated to your MVP ID?", Alerts.Error, Alerts.OK);
         }
     }
     catch (Exception e)
     {
         AnalyticsService.Report(e);
         await DialogService.AlertAsync(Alerts.UnexpectedError, Alerts.Error, Alerts.OK);
     }
 }
コード例 #28
0
        public override async void Activate(object parameter)
        {
            IsBusy = true;

            if (!await userService.EnsureLoggedInAsync())
            {
                return;
            }

            // Ensures user's information is notificated to the UI.
            RaisePropertyChanged(() => User);

            try
            {
                var postId = parameter.ToString();
                Post = await timelineService.GetPostAsync(postId);

                if (Post == null)
                {
                    NavigationService.GoBack();
                    return;
                }
            }
            catch
            {
                await DialogService.AlertAsync("An error occurred while getting post details.");

                NavigationService.GoBack();
            }
            finally
            {
                IsBusy = false;
            }

            base.Activate(parameter);
        }
コード例 #29
0
        public async Task ExecuteAuthorizeCommand()
        {
            var externalUrl = _accountService.CreateAuthorizationRequest();

            try
            {
                var codeResult = await WebAuthenticator.AuthenticateAsync(new Uri(externalUrl), new Uri(GlobalSettings.Instance.Callback));

                var code = codeResult.Properties["code"];

                if (!string.IsNullOrEmpty(code))
                {
                    using var loading = DialogService.Loading("Authenticating... please wait");
                    var loginResult = await _accountService.ExchangeCodeForToken(code);

                    if (loginResult.Item1 == helpers.Common.CallStatus.Success)
                    {
                        await NavigationService.PushAsync(new SuccessPage());
                    }
                    else
                    {
                        await DialogService.AlertAsync("Authentication is not successful, something went wrong", "Alert", "OK");
                    }
                }
            }
            catch (OperationCanceledException ex)
            {
                _ = ex;
                //await DialogService.AlertAsync("Login has been canceled.", "Alert", "OK");
            }
            catch (Exception ex)
            {
                _ = ex;
                await DialogService.AlertAsync("Authentication is not successful, something went wrong", "Alert", "OK");
            }
        }
コード例 #30
0
        async Task DeleteContribution()
        {
            try
            {
                // Shouldn't be getting here anyway, so no need for a message.
                if (!Contribution.StartDate.IsWithinCurrentAwardPeriod())
                {
                    return;
                }

                // Ask for confirmation before deletion.
                var confirm = await DialogService.ConfirmAsync("Are you sure you want to delete this contribution? You cannot undo this.", Alerts.HoldOn, Alerts.OK, Alerts.Cancel);

                if (!confirm)
                {
                    return;
                }

                var isDeleted = await MvpApiService.DeleteContributionAsync(Contribution);

                if (isDeleted)
                {
                    // TODO: Pass back true to indicate it needs to refresh.
                    await NavigationHelper.BackAsync().ConfigureAwait(false);
                }
                else
                {
                    await DialogService.AlertAsync("Your contribution could not be deleted. Perhaps it was already deleted, or it took place in the previous award period?", Alerts.Error, Alerts.OK);
                }
            }
            catch (Exception ex)
            {
                AnalyticsService.Report(ex);
                await DialogService.AlertAsync(Alerts.UnexpectedError, Alerts.Error, Alerts.OK).ConfigureAwait(false);
            }
        }