convert user dialogs to native XF options

This commit is contained in:
Kyle Spearrin 2017-12-22 22:41:48 -05:00
parent 7a19c50ec0
commit 0270cf6e45
28 changed files with 90 additions and 133 deletions

View file

@ -7,7 +7,6 @@ using Bit.App.Abstractions;
using XLabs.Ioc; using XLabs.Ioc;
using Plugin.Settings.Abstractions; using Plugin.Settings.Abstractions;
using Plugin.Connectivity.Abstractions; using Plugin.Connectivity.Abstractions;
using Acr.UserDialogs;
using Android.Content; using Android.Content;
using System.Reflection; using System.Reflection;
using Xamarin.Forms.Platform.Android; using Xamarin.Forms.Platform.Android;
@ -77,12 +76,10 @@ namespace Bit.Android
_appOptions, _appOptions,
Resolver.Resolve<IAuthService>(), Resolver.Resolve<IAuthService>(),
Resolver.Resolve<IConnectivity>(), Resolver.Resolve<IConnectivity>(),
Resolver.Resolve<IUserDialogs>(),
Resolver.Resolve<IDatabaseService>(), Resolver.Resolve<IDatabaseService>(),
Resolver.Resolve<ISyncService>(), Resolver.Resolve<ISyncService>(),
_settings, _settings,
Resolver.Resolve<ILockService>(), Resolver.Resolve<ILockService>(),
Resolver.Resolve<IGoogleAnalyticsService>(),
Resolver.Resolve<ILocalizeService>(), Resolver.Resolve<ILocalizeService>(),
Resolver.Resolve<IAppInfoService>(), Resolver.Resolve<IAppInfoService>(),
Resolver.Resolve<IAppSettingsService>(), Resolver.Resolve<IAppSettingsService>(),

View file

@ -23,7 +23,6 @@ using Android.App.Assist;
using Bit.Android.Autofill; using Bit.Android.Autofill;
using System.Linq; using System.Linq;
using Plugin.Settings.Abstractions; using Plugin.Settings.Abstractions;
using Acr.UserDialogs;
using Android.Views.InputMethods; using Android.Views.InputMethods;
namespace Bit.Android.Services namespace Bit.Android.Services
@ -31,16 +30,13 @@ namespace Bit.Android.Services
public class DeviceActionService : IDeviceActionService public class DeviceActionService : IDeviceActionService
{ {
private readonly IAppSettingsService _appSettingsService; private readonly IAppSettingsService _appSettingsService;
private readonly IUserDialogs _userDialogs;
private bool _cameraPermissionsDenied; private bool _cameraPermissionsDenied;
private DateTime? _lastAction; private DateTime? _lastAction;
public DeviceActionService( public DeviceActionService(
IAppSettingsService appSettingsService, IAppSettingsService appSettingsService)
IUserDialogs userDialogs)
{ {
_appSettingsService = appSettingsService; _appSettingsService = appSettingsService;
_userDialogs = userDialogs;
} }
private Context CurrentContext => CrossCurrentActivity.Current.Activity; private Context CurrentContext => CrossCurrentActivity.Current.Activity;
@ -312,7 +308,7 @@ namespace Bit.Android.Services
activity.StartActivity(intent); activity.StartActivity(intent);
} }
public void LaunchApp(string appName) public async Task LaunchAppAsync(string appName, Page page)
{ {
var activity = (MainActivity)CurrentContext; var activity = (MainActivity)CurrentContext;
if(_lastAction.LastActionWasRecent()) if(_lastAction.LastActionWasRecent())
@ -325,7 +321,7 @@ namespace Bit.Android.Services
var launchIntent = activity.PackageManager.GetLaunchIntentForPackage(appName); var launchIntent = activity.PackageManager.GetLaunchIntentForPackage(appName);
if(launchIntent == null) if(launchIntent == null)
{ {
_userDialogs.Alert(string.Format(AppResources.CannotOpenApp, appName)); await page.DisplayAlert(null, string.Format(AppResources.CannotOpenApp, appName), AppResources.Ok);
} }
else else
{ {

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xamarin.Forms;
namespace Bit.App.Abstractions namespace Bit.App.Abstractions
{ {
@ -18,6 +19,6 @@ namespace Bit.App.Abstractions
void DismissKeyboard(); void DismissKeyboard();
void OpenAccessibilitySettings(); void OpenAccessibilitySettings();
void OpenAutofillSettings(); void OpenAutofillSettings();
void LaunchApp(string appName); Task LaunchAppAsync(string appName, Page page);
} }
} }

View file

@ -9,8 +9,6 @@ using Plugin.Settings.Abstractions;
using Bit.App.Controls; using Bit.App.Controls;
using Plugin.Connectivity.Abstractions; using Plugin.Connectivity.Abstractions;
using System.Net; using System.Net;
using Acr.UserDialogs;
using XLabs.Ioc;
using System.Reflection; using System.Reflection;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.App.Utilities; using Bit.App.Utilities;
@ -21,14 +19,12 @@ namespace Bit.App
public class App : Application public class App : Application
{ {
private AppOptions _options; private AppOptions _options;
private readonly IAuthService _authService;
private readonly IDatabaseService _databaseService; private readonly IDatabaseService _databaseService;
private readonly IConnectivity _connectivity; private readonly IConnectivity _connectivity;
private readonly IUserDialogs _userDialogs;
private readonly ISyncService _syncService; private readonly ISyncService _syncService;
private readonly IAuthService _authService;
private readonly ISettings _settings; private readonly ISettings _settings;
private readonly ILockService _lockService; private readonly ILockService _lockService;
private readonly IGoogleAnalyticsService _googleAnalyticsService;
private readonly ILocalizeService _localizeService; private readonly ILocalizeService _localizeService;
private readonly IAppInfoService _appInfoService; private readonly IAppInfoService _appInfoService;
private readonly IAppSettingsService _appSettingsService; private readonly IAppSettingsService _appSettingsService;
@ -38,26 +34,22 @@ namespace Bit.App
AppOptions options, AppOptions options,
IAuthService authService, IAuthService authService,
IConnectivity connectivity, IConnectivity connectivity,
IUserDialogs userDialogs,
IDatabaseService databaseService, IDatabaseService databaseService,
ISyncService syncService, ISyncService syncService,
ISettings settings, ISettings settings,
ILockService lockService, ILockService lockService,
IGoogleAnalyticsService googleAnalyticsService,
ILocalizeService localizeService, ILocalizeService localizeService,
IAppInfoService appInfoService, IAppInfoService appInfoService,
IAppSettingsService appSettingsService, IAppSettingsService appSettingsService,
IDeviceActionService deviceActionService) IDeviceActionService deviceActionService)
{ {
_options = options ?? new AppOptions(); _options = options ?? new AppOptions();
_authService = authService;
_databaseService = databaseService; _databaseService = databaseService;
_connectivity = connectivity; _connectivity = connectivity;
_userDialogs = userDialogs;
_syncService = syncService; _syncService = syncService;
_authService = authService;
_settings = settings; _settings = settings;
_lockService = lockService; _lockService = lockService;
_googleAnalyticsService = googleAnalyticsService;
_localizeService = localizeService; _localizeService = localizeService;
_appInfoService = appInfoService; _appInfoService = appInfoService;
_appSettingsService = appSettingsService; _appSettingsService = appSettingsService;

View file

@ -13,7 +13,6 @@ namespace Bit.App.Pages
public class EnvironmentPage : ExtendedContentPage public class EnvironmentPage : ExtendedContentPage
{ {
private IAppSettingsService _appSettings; private IAppSettingsService _appSettings;
private IUserDialogs _userDialogs;
private IDeviceActionService _deviceActionService; private IDeviceActionService _deviceActionService;
private IGoogleAnalyticsService _googleAnalyticsService; private IGoogleAnalyticsService _googleAnalyticsService;
@ -21,7 +20,6 @@ namespace Bit.App.Pages
: base(updateActivity: false) : base(updateActivity: false)
{ {
_appSettings = Resolver.Resolve<IAppSettingsService>(); _appSettings = Resolver.Resolve<IAppSettingsService>();
_userDialogs = Resolver.Resolve<IUserDialogs>();
_deviceActionService = Resolver.Resolve<IDeviceActionService>(); _deviceActionService = Resolver.Resolve<IDeviceActionService>();
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>(); _googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
@ -170,7 +168,8 @@ namespace Bit.App.Pages
BaseUrlCell.Entry.Text = FixUrl(BaseUrlCell.Entry.Text); BaseUrlCell.Entry.Text = FixUrl(BaseUrlCell.Entry.Text);
if(!Uri.TryCreate(BaseUrlCell.Entry.Text, UriKind.Absolute, out result)) if(!Uri.TryCreate(BaseUrlCell.Entry.Text, UriKind.Absolute, out result))
{ {
_userDialogs.Alert(string.Format(AppResources.FormattedIncorrectly, AppResources.ServerUrl)); await DisplayAlert(null, string.Format(AppResources.FormattedIncorrectly, AppResources.ServerUrl),
AppResources.Ok);
return; return;
} }
} }
@ -184,7 +183,8 @@ namespace Bit.App.Pages
WebVaultUrlCell.Entry.Text = FixUrl(WebVaultUrlCell.Entry.Text); WebVaultUrlCell.Entry.Text = FixUrl(WebVaultUrlCell.Entry.Text);
if(!Uri.TryCreate(WebVaultUrlCell.Entry.Text, UriKind.Absolute, out result)) if(!Uri.TryCreate(WebVaultUrlCell.Entry.Text, UriKind.Absolute, out result))
{ {
_userDialogs.Alert(string.Format(AppResources.FormattedIncorrectly, AppResources.WebVaultUrl)); await DisplayAlert(null, string.Format(AppResources.FormattedIncorrectly, AppResources.WebVaultUrl),
AppResources.Ok);
return; return;
} }
} }
@ -198,7 +198,8 @@ namespace Bit.App.Pages
ApiUrlCell.Entry.Text = FixUrl(ApiUrlCell.Entry.Text); ApiUrlCell.Entry.Text = FixUrl(ApiUrlCell.Entry.Text);
if(!Uri.TryCreate(ApiUrlCell.Entry.Text, UriKind.Absolute, out result)) if(!Uri.TryCreate(ApiUrlCell.Entry.Text, UriKind.Absolute, out result))
{ {
_userDialogs.Alert(string.Format(AppResources.FormattedIncorrectly, AppResources.ApiUrl)); await DisplayAlert(null, string.Format(AppResources.FormattedIncorrectly, AppResources.ApiUrl),
AppResources.Ok);
return; return;
} }
} }
@ -212,7 +213,8 @@ namespace Bit.App.Pages
IdentityUrlCell.Entry.Text = FixUrl(IdentityUrlCell.Entry.Text); IdentityUrlCell.Entry.Text = FixUrl(IdentityUrlCell.Entry.Text);
if(!Uri.TryCreate(IdentityUrlCell.Entry.Text, UriKind.Absolute, out result)) if(!Uri.TryCreate(IdentityUrlCell.Entry.Text, UriKind.Absolute, out result))
{ {
_userDialogs.Alert(string.Format(AppResources.FormattedIncorrectly, AppResources.IdentityUrl)); await DisplayAlert(null, string.Format(AppResources.FormattedIncorrectly, AppResources.IdentityUrl),
AppResources.Ok);
return; return;
} }
} }
@ -226,7 +228,8 @@ namespace Bit.App.Pages
IconsUrlCell.Entry.Text = FixUrl(IconsUrlCell.Entry.Text); IconsUrlCell.Entry.Text = FixUrl(IconsUrlCell.Entry.Text);
if(!Uri.TryCreate(IconsUrlCell.Entry.Text, UriKind.Absolute, out result)) if(!Uri.TryCreate(IconsUrlCell.Entry.Text, UriKind.Absolute, out result))
{ {
_userDialogs.Alert(string.Format(AppResources.FormattedIncorrectly, AppResources.IconsUrl)); await DisplayAlert(null, string.Format(AppResources.FormattedIncorrectly, AppResources.IconsUrl),
AppResources.Ok);
return; return;
} }
} }

View file

@ -15,12 +15,10 @@ namespace Bit.App.Pages
public BaseLockPage() public BaseLockPage()
: base(false, false) : base(false, false)
{ {
UserDialogs = Resolver.Resolve<IUserDialogs>();
AuthService = Resolver.Resolve<IAuthService>(); AuthService = Resolver.Resolve<IAuthService>();
_deviceActionService = Resolver.Resolve<IDeviceActionService>(); _deviceActionService = Resolver.Resolve<IDeviceActionService>();
} }
protected IUserDialogs UserDialogs { get; set; }
protected IAuthService AuthService { get; set; } protected IAuthService AuthService { get; set; }
protected override bool OnBackButtonPressed() protected override bool OnBackButtonPressed()
@ -31,7 +29,8 @@ namespace Bit.App.Pages
protected async Task LogoutAsync() protected async Task LogoutAsync()
{ {
if(!await UserDialogs.ConfirmAsync(AppResources.LogoutConfirmation, null, AppResources.Yes, AppResources.Cancel)) var confirmed = await DisplayAlert(null, AppResources.LogoutConfirmation, AppResources.Yes, AppResources.Cancel);
if(!confirmed)
{ {
return; return;
} }

View file

@ -159,7 +159,7 @@ namespace Bit.App.Pages
{ {
// TODO: keep track of invalid attempts and logout? // TODO: keep track of invalid attempts and logout?
UserDialogs.Alert(AppResources.InvalidMasterPassword); await DisplayAlert(null, AppResources.InvalidMasterPassword, AppResources.Ok);
PasswordCell.Entry.Text = string.Empty; PasswordCell.Entry.Text = string.Empty;
PasswordCell.Entry.Focus(); PasswordCell.Entry.Focus();
} }

View file

@ -113,7 +113,7 @@ namespace Bit.App.Pages
PinControl.Dispose(); PinControl.Dispose();
} }
protected void PinEntered(object sender, EventArgs args) protected async void PinEntered(object sender, EventArgs args)
{ {
if(_lastAction.LastActionWasRecent()) if(_lastAction.LastActionWasRecent())
{ {
@ -125,13 +125,13 @@ namespace Bit.App.Pages
{ {
_appSettingsService.Locked = false; _appSettingsService.Locked = false;
PinControl.Entry.Unfocus(); PinControl.Entry.Unfocus();
Navigation.PopModalAsync(); await Navigation.PopModalAsync();
} }
else else
{ {
// TODO: keep track of invalid attempts and logout? // TODO: keep track of invalid attempts and logout?
UserDialogs.Alert(AppResources.InvalidPIN); await DisplayAlert(null, AppResources.InvalidPIN, AppResources.Ok);
Model.PIN = string.Empty; Model.PIN = string.Empty;
PinControl.Entry.Focus(); PinControl.Entry.Focus();
} }

View file

@ -377,7 +377,7 @@ namespace Bit.App.Pages
} }
else if(!response.Succeeded) else if(!response.Succeeded)
{ {
_userDialogs.Alert(AppResources.VerificationEmailNotSent); await DisplayAlert(null, AppResources.VerificationEmailNotSent, AppResources.Ok);
} }
} }
@ -406,6 +406,7 @@ namespace Bit.App.Pages
var response = await _authService.TokenPostTwoFactorAsync(_providerType.Value, token, RememberCell.On, var response = await _authService.TokenPostTwoFactorAsync(_providerType.Value, token, RememberCell.On,
_email, _masterPasswordHash, _key); _email, _masterPasswordHash, _key);
_userDialogs.HideLoading(); _userDialogs.HideLoading();
if(!response.Success) if(!response.Success)
{ {
ListenYubiKey(true); ListenYubiKey(true);

View file

@ -127,6 +127,7 @@ namespace Bit.App.Pages
_userDialogs.ShowLoading(AppResources.Submitting, MaskType.Black); _userDialogs.ShowLoading(AppResources.Submitting, MaskType.Black);
var response = await _accountApiRepository.PostPasswordHintAsync(request); var response = await _accountApiRepository.PostPasswordHintAsync(request);
_userDialogs.HideLoading(); _userDialogs.HideLoading();
if(!response.Succeeded) if(!response.Succeeded)
{ {
await DisplayAlert(AppResources.AnErrorHasOccurred, response.Errors.FirstOrDefault()?.Message, AppResources.Ok); await DisplayAlert(AppResources.AnErrorHasOccurred, response.Errors.FirstOrDefault()?.Message, AppResources.Ok);

View file

@ -216,6 +216,7 @@ namespace Bit.App.Pages
_userDialogs.ShowLoading(AppResources.CreatingAccount, MaskType.Black); _userDialogs.ShowLoading(AppResources.CreatingAccount, MaskType.Black);
var response = await _accountsApiRepository.PostRegisterAsync(request); var response = await _accountsApiRepository.PostRegisterAsync(request);
_userDialogs.HideLoading(); _userDialogs.HideLoading();
if(!response.Succeeded) if(!response.Succeeded)
{ {
await DisplayAlert(AppResources.AnErrorHasOccurred, response.Errors.FirstOrDefault()?.Message, await DisplayAlert(AppResources.AnErrorHasOccurred, response.Errors.FirstOrDefault()?.Message,

View file

@ -86,7 +86,6 @@ namespace Bit.App.Pages
_userDialogs.ShowLoading(AppResources.Saving, MaskType.Black); _userDialogs.ShowLoading(AppResources.Saving, MaskType.Black);
var saveResult = await _folderService.SaveAsync(folder); var saveResult = await _folderService.SaveAsync(folder);
_userDialogs.HideLoading(); _userDialogs.HideLoading();
if(saveResult.Succeeded) if(saveResult.Succeeded)
@ -97,11 +96,11 @@ namespace Bit.App.Pages
} }
else if(saveResult.Errors.Count() > 0) else if(saveResult.Errors.Count() > 0)
{ {
await _userDialogs.AlertAsync(saveResult.Errors.First().Message, AppResources.AnErrorHasOccurred); await DisplayAlert(AppResources.AnErrorHasOccurred, saveResult.Errors.First().Message, AppResources.Ok);
} }
else else
{ {
await _userDialogs.AlertAsync(AppResources.AnErrorHasOccurred); await DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
} }
}, ToolbarItemOrder.Default, 0); }, ToolbarItemOrder.Default, 0);

View file

@ -100,7 +100,6 @@ namespace Bit.App.Pages
_userDialogs.ShowLoading(AppResources.Saving, MaskType.Black); _userDialogs.ShowLoading(AppResources.Saving, MaskType.Black);
var saveResult = await _folderService.SaveAsync(folder); var saveResult = await _folderService.SaveAsync(folder);
_userDialogs.HideLoading(); _userDialogs.HideLoading();
if(saveResult.Succeeded) if(saveResult.Succeeded)
@ -111,11 +110,11 @@ namespace Bit.App.Pages
} }
else if(saveResult.Errors.Count() > 0) else if(saveResult.Errors.Count() > 0)
{ {
await _userDialogs.AlertAsync(saveResult.Errors.First().Message, AppResources.AnErrorHasOccurred); await DisplayAlert(AppResources.AnErrorHasOccurred, saveResult.Errors.First().Message, AppResources.Ok);
} }
else else
{ {
await _userDialogs.AlertAsync(AppResources.AnErrorHasOccurred); await DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
} }
}, ToolbarItemOrder.Default, 0); }, ToolbarItemOrder.Default, 0);
@ -157,7 +156,8 @@ namespace Bit.App.Pages
// TODO: Validate the delete operation. ex. Cannot delete a folder that has ciphers in it? // TODO: Validate the delete operation. ex. Cannot delete a folder that has ciphers in it?
if(!await _userDialogs.ConfirmAsync(AppResources.DoYouReallyWantToDelete, null, AppResources.Yes, AppResources.No)) var confirmed = await DisplayAlert(null, AppResources.DoYouReallyWantToDelete, AppResources.Yes, AppResources.No);
if(!confirmed)
{ {
return; return;
} }
@ -173,11 +173,11 @@ namespace Bit.App.Pages
} }
else if(deleteTask.Errors.Count() > 0) else if(deleteTask.Errors.Count() > 0)
{ {
await _userDialogs.AlertAsync(deleteTask.Errors.First().Message, AppResources.AnErrorHasOccurred); await DisplayAlert(AppResources.AnErrorHasOccurred, deleteTask.Errors.First().Message, AppResources.Ok);
} }
else else
{ {
await _userDialogs.AlertAsync(AppResources.AnErrorHasOccurred); await DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
} }
} }

View file

@ -1,8 +1,6 @@
using System; using System;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Acr.UserDialogs;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.App.Models.Page; using Bit.App.Models.Page;
@ -16,12 +14,10 @@ namespace Bit.App.Pages
public class SettingsListFoldersPage : ExtendedContentPage public class SettingsListFoldersPage : ExtendedContentPage
{ {
private readonly IFolderService _folderService; private readonly IFolderService _folderService;
private readonly IUserDialogs _userDialogs;
public SettingsListFoldersPage() public SettingsListFoldersPage()
{ {
_folderService = Resolver.Resolve<IFolderService>(); _folderService = Resolver.Resolve<IFolderService>();
_userDialogs = Resolver.Resolve<IUserDialogs>();
Init(); Init();
} }

View file

@ -14,7 +14,6 @@ namespace Bit.App.Pages
public class SettingsPage : ExtendedContentPage public class SettingsPage : ExtendedContentPage
{ {
private readonly IAuthService _authService; private readonly IAuthService _authService;
private readonly IUserDialogs _userDialogs;
private readonly ISettings _settings; private readonly ISettings _settings;
private readonly IFingerprint _fingerprint; private readonly IFingerprint _fingerprint;
private readonly IPushNotificationService _pushNotification; private readonly IPushNotificationService _pushNotification;
@ -28,7 +27,6 @@ namespace Bit.App.Pages
public SettingsPage() public SettingsPage()
{ {
_authService = Resolver.Resolve<IAuthService>(); _authService = Resolver.Resolve<IAuthService>();
_userDialogs = Resolver.Resolve<IUserDialogs>();
_settings = Resolver.Resolve<ISettings>(); _settings = Resolver.Resolve<ISettings>();
_fingerprint = Resolver.Resolve<IFingerprint>(); _fingerprint = Resolver.Resolve<IFingerprint>();
_pushNotification = Resolver.Resolve<IPushNotificationService>(); _pushNotification = Resolver.Resolve<IPushNotificationService>();
@ -271,8 +269,9 @@ namespace Bit.App.Pages
private async void TwoStepCell_Tapped(object sender, EventArgs e) private async void TwoStepCell_Tapped(object sender, EventArgs e)
{ {
if(!await _userDialogs.ConfirmAsync(AppResources.TwoStepLoginConfirmation, null, AppResources.Yes, var confirmed = await DisplayAlert(null, AppResources.TwoStepLoginConfirmation, AppResources.Yes,
AppResources.Cancel)) AppResources.Cancel);
if(!confirmed)
{ {
return; return;
} }
@ -349,7 +348,9 @@ namespace Bit.App.Pages
private async void LogOutCell_Tapped(object sender, EventArgs e) private async void LogOutCell_Tapped(object sender, EventArgs e)
{ {
if(!await _userDialogs.ConfirmAsync(AppResources.LogoutConfirmation, null, AppResources.Yes, AppResources.Cancel)) var confirmed = await DisplayAlert(null, AppResources.LogoutConfirmation, AppResources.Yes,
AppResources.Cancel);
if(!confirmed)
{ {
return; return;
} }
@ -359,8 +360,9 @@ namespace Bit.App.Pages
private async void ChangeMasterPasswordCell_Tapped(object sender, EventArgs e) private async void ChangeMasterPasswordCell_Tapped(object sender, EventArgs e)
{ {
if(!await _userDialogs.ConfirmAsync(AppResources.ChangePasswordConfirmation, null, AppResources.Yes, var confirmed = await DisplayAlert(null, AppResources.ChangePasswordConfirmation, AppResources.Yes,
AppResources.Cancel)) AppResources.Cancel);
if(!confirmed)
{ {
return; return;
} }
@ -371,8 +373,9 @@ namespace Bit.App.Pages
private async void ChangeEmailCell_Tapped(object sender, EventArgs e) private async void ChangeEmailCell_Tapped(object sender, EventArgs e)
{ {
if(!await _userDialogs.ConfirmAsync(AppResources.ChangeEmailConfirmation, null, AppResources.Yes, var confirmed = await DisplayAlert(null, AppResources.ChangeEmailConfirmation, AppResources.Yes,
AppResources.Cancel)) AppResources.Cancel);
if(!confirmed)
{ {
return; return;
} }

View file

@ -1,7 +1,4 @@
using System; using System;
using System.Threading.Tasks;
using Acr.UserDialogs;
using Bit.App.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;
using Xamarin.Forms; using Xamarin.Forms;
using XLabs.Ioc; using XLabs.Ioc;
@ -13,14 +10,12 @@ namespace Bit.App.Pages
{ {
public class SettingsPinPage : ExtendedContentPage public class SettingsPinPage : ExtendedContentPage
{ {
private readonly IUserDialogs _userDialogs;
private readonly ISettings _settings; private readonly ISettings _settings;
private Action<SettingsPinPage> _pinEnteredAction; private Action<SettingsPinPage> _pinEnteredAction;
public SettingsPinPage(Action<SettingsPinPage> pinEnteredAction) public SettingsPinPage(Action<SettingsPinPage> pinEnteredAction)
{ {
_pinEnteredAction = pinEnteredAction; _pinEnteredAction = pinEnteredAction;
_userDialogs = Resolver.Resolve<IUserDialogs>();
_settings = Resolver.Resolve<ISettings>(); _settings = Resolver.Resolve<ISettings>();
Init(); Init();

View file

@ -14,13 +14,11 @@ namespace Bit.App.Pages
{ {
public class ToolsExtensionPage : ExtendedContentPage public class ToolsExtensionPage : ExtendedContentPage
{ {
private readonly IUserDialogs _userDialogs;
private readonly ISettings _settings; private readonly ISettings _settings;
private readonly IGoogleAnalyticsService _googleAnalyticsService; private readonly IGoogleAnalyticsService _googleAnalyticsService;
public ToolsExtensionPage() public ToolsExtensionPage()
{ {
_userDialogs = Resolver.Resolve<IUserDialogs>();
_settings = Resolver.Resolve<ISettings>(); _settings = Resolver.Resolve<ISettings>();
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>(); _googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
Model = new AppExtensionPageModel(_settings); Model = new AppExtensionPageModel(_settings);

View file

@ -1,6 +1,4 @@
using System; using System;
using System.Threading.Tasks;
using Acr.UserDialogs;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.App.Resources; using Bit.App.Resources;
@ -13,13 +11,11 @@ namespace Bit.App.Pages
{ {
public class ToolsPage : ExtendedContentPage public class ToolsPage : ExtendedContentPage
{ {
private readonly IUserDialogs _userDialogs;
private readonly IGoogleAnalyticsService _googleAnalyticsService; private readonly IGoogleAnalyticsService _googleAnalyticsService;
private readonly IDeviceInfoService _deviceInfoService; private readonly IDeviceInfoService _deviceInfoService;
public ToolsPage() public ToolsPage()
{ {
_userDialogs = Resolver.Resolve<IUserDialogs>();
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>(); _googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>(); _deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
@ -144,8 +140,9 @@ namespace Bit.App.Pages
private async void ImportCell_Tapped(object sender, EventArgs e) private async void ImportCell_Tapped(object sender, EventArgs e)
{ {
if(!await _userDialogs.ConfirmAsync(AppResources.ImportItemsConfirmation, null, AppResources.Yes, var confirmed = await DisplayAlert(null, AppResources.ImportItemsConfirmation, AppResources.Yes,
AppResources.Cancel)) AppResources.Cancel);
if(!confirmed)
{ {
return; return;
} }

View file

@ -339,7 +339,7 @@ namespace Bit.App.Pages
} }
else else
{ {
_userDialogs.Alert(AppResources.AuthenticatorKeyReadError); await DisplayAlert(null, AppResources.AuthenticatorKeyReadError, AppResources.Ok);
} }
}); });
}); });
@ -772,11 +772,11 @@ namespace Bit.App.Pages
} }
else if(saveTask.Errors.Count() > 0) else if(saveTask.Errors.Count() > 0)
{ {
await _userDialogs.AlertAsync(saveTask.Errors.First().Message, AppResources.AnErrorHasOccurred); await DisplayAlert(AppResources.AnErrorHasOccurred, saveTask.Errors.First().Message, AppResources.Ok);
} }
else else
{ {
await _userDialogs.AlertAsync(AppResources.AnErrorHasOccurred); await DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
} }
}, ToolbarItemOrder.Default, 0); }, ToolbarItemOrder.Default, 0);

View file

@ -162,7 +162,6 @@ namespace Bit.App.Pages
_userDialogs.ShowLoading(AppResources.Saving, MaskType.Black); _userDialogs.ShowLoading(AppResources.Saving, MaskType.Black);
var saveTask = await _cipherService.EncryptAndSaveAttachmentAsync(_cipher, _fileBytes, FileLabel.Text); var saveTask = await _cipherService.EncryptAndSaveAttachmentAsync(_cipher, _fileBytes, FileLabel.Text);
_userDialogs.HideLoading(); _userDialogs.HideLoading();
if(saveTask.Succeeded) if(saveTask.Succeeded)
@ -175,11 +174,11 @@ namespace Bit.App.Pages
} }
else if(saveTask.Errors.Count() > 0) else if(saveTask.Errors.Count() > 0)
{ {
await _userDialogs.AlertAsync(saveTask.Errors.First().Message, AppResources.AnErrorHasOccurred); await DisplayAlert(AppResources.AnErrorHasOccurred, saveTask.Errors.First().Message, AppResources.Ok);
} }
else else
{ {
await _userDialogs.AlertAsync(AppResources.AnErrorHasOccurred); await DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
} }
}, ToolbarItemOrder.Default, 0); }, ToolbarItemOrder.Default, 0);
@ -261,7 +260,9 @@ namespace Bit.App.Pages
((ListView)sender).SelectedItem = null; ((ListView)sender).SelectedItem = null;
if(!await _userDialogs.ConfirmAsync(AppResources.DoYouReallyWantToDelete, null, AppResources.Yes, AppResources.No)) var confirmed = await DisplayAlert(null, AppResources.DoYouReallyWantToDelete, AppResources.Yes,
AppResources.No);
if(!confirmed)
{ {
return; return;
} }
@ -278,11 +279,11 @@ namespace Bit.App.Pages
} }
else if(saveTask.Errors.Count() > 0) else if(saveTask.Errors.Count() > 0)
{ {
await _userDialogs.AlertAsync(saveTask.Errors.First().Message, AppResources.AnErrorHasOccurred); await DisplayAlert(AppResources.AnErrorHasOccurred, saveTask.Errors.First().Message, AppResources.Ok);
} }
else else
{ {
await _userDialogs.AlertAsync(AppResources.AnErrorHasOccurred); await DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
} }
} }
@ -311,7 +312,7 @@ namespace Bit.App.Pages
private async Task ShowUpdateKeyAsync() private async Task ShowUpdateKeyAsync()
{ {
var confirmed = await _userDialogs.ConfirmAsync(AppResources.UpdateKey, AppResources.FeatureUnavailable, var confirmed = await DisplayAlert(AppResources.FeatureUnavailable, AppResources.UpdateKey,
AppResources.LearnMore, AppResources.Cancel); AppResources.LearnMore, AppResources.Cancel);
if(confirmed) if(confirmed)
{ {

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Acr.UserDialogs;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.App.Models.Page; using Bit.App.Models.Page;
@ -46,7 +45,6 @@ namespace Bit.App.Pages
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>(); _deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
DeviceActionService = Resolver.Resolve<IDeviceActionService>(); DeviceActionService = Resolver.Resolve<IDeviceActionService>();
_settingsService = Resolver.Resolve<ISettingsService>(); _settingsService = Resolver.Resolve<ISettingsService>();
UserDialogs = Resolver.Resolve<IUserDialogs>();
_appSettingsService = Resolver.Resolve<IAppSettingsService>(); _appSettingsService = Resolver.Resolve<IAppSettingsService>();
GoogleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>(); GoogleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
@ -61,7 +59,6 @@ namespace Bit.App.Pages
private SearchToolBarItem SearchItem { get; set; } private SearchToolBarItem SearchItem { get; set; }
private AddCipherToolBarItem AddCipherItem { get; set; } private AddCipherToolBarItem AddCipherItem { get; set; }
private IGoogleAnalyticsService GoogleAnalyticsService { get; set; } private IGoogleAnalyticsService GoogleAnalyticsService { get; set; }
private IUserDialogs UserDialogs { get; set; }
private IDeviceActionService DeviceActionService { get; set; } private IDeviceActionService DeviceActionService { get; set; }
private string Uri { get; set; } private string Uri { get; set; }
@ -237,9 +234,9 @@ namespace Bit.App.Pages
bool doAutofill = true; bool doAutofill = true;
if(cipher.Fuzzy) if(cipher.Fuzzy)
{ {
doAutofill = await UserDialogs.ConfirmAsync( doAutofill = await DisplayAlert(null,
string.Format(AppResources.BitwardenAutofillServiceMatchConfirm, _name), string.Format(AppResources.BitwardenAutofillServiceMatchConfirm, _name),
okText: AppResources.Yes, cancelText: AppResources.No); AppResources.Yes, AppResources.No);
} }
if(doAutofill) if(doAutofill)

View file

@ -117,7 +117,6 @@ namespace Bit.App.Pages
_userDialogs.ShowLoading(AppResources.Saving, MaskType.Black); _userDialogs.ShowLoading(AppResources.Saving, MaskType.Black);
var saveTask = await _cipherService.SaveAsync(_cipher); var saveTask = await _cipherService.SaveAsync(_cipher);
_userDialogs.HideLoading(); _userDialogs.HideLoading();
if(saveTask.Succeeded) if(saveTask.Succeeded)
@ -128,11 +127,11 @@ namespace Bit.App.Pages
} }
else if(saveTask.Errors.Count() > 0) else if(saveTask.Errors.Count() > 0)
{ {
await _userDialogs.AlertAsync(saveTask.Errors.First().Message, AppResources.AnErrorHasOccurred); await DisplayAlert(AppResources.AnErrorHasOccurred, saveTask.Errors.First().Message, AppResources.Ok);
} }
else else
{ {
await _userDialogs.AlertAsync(AppResources.AnErrorHasOccurred); await DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
} }
}, ToolbarItemOrder.Default, 0); }, ToolbarItemOrder.Default, 0);

View file

@ -615,7 +615,6 @@ namespace Bit.App.Pages
_userDialogs.ShowLoading(AppResources.Saving, MaskType.Black); _userDialogs.ShowLoading(AppResources.Saving, MaskType.Black);
var saveTask = await _cipherService.SaveAsync(Cipher); var saveTask = await _cipherService.SaveAsync(Cipher);
_userDialogs.HideLoading(); _userDialogs.HideLoading();
if(saveTask.Succeeded) if(saveTask.Succeeded)
@ -626,11 +625,11 @@ namespace Bit.App.Pages
} }
else if(saveTask.Errors.Count() > 0) else if(saveTask.Errors.Count() > 0)
{ {
await _userDialogs.AlertAsync(saveTask.Errors.First().Message, AppResources.AnErrorHasOccurred); await DisplayAlert(AppResources.AnErrorHasOccurred, saveTask.Errors.First().Message, AppResources.Ok);
} }
else else
{ {
await _userDialogs.AlertAsync(AppResources.AnErrorHasOccurred); await DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
} }
}, ToolbarItemOrder.Default, 0); }, ToolbarItemOrder.Default, 0);
@ -810,7 +809,7 @@ namespace Bit.App.Pages
} }
else else
{ {
_userDialogs.Alert(AppResources.AuthenticatorKeyReadError); await DisplayAlert(null, AppResources.AuthenticatorKeyReadError, AppResources.Ok);
} }
}); });
}); });
@ -821,7 +820,7 @@ namespace Bit.App.Pages
private async void GenerateCell_Tapped(object sender, EventArgs e) private async void GenerateCell_Tapped(object sender, EventArgs e)
{ {
if(!string.IsNullOrWhiteSpace(LoginPasswordCell.Entry.Text) if(!string.IsNullOrWhiteSpace(LoginPasswordCell.Entry.Text)
&& !await _userDialogs.ConfirmAsync(AppResources.PasswordOverrideAlert, null, AppResources.Yes, AppResources.No)) && !(await DisplayAlert(null, AppResources.PasswordOverrideAlert, AppResources.Yes, AppResources.No)))
{ {
return; return;
} }
@ -854,7 +853,9 @@ namespace Bit.App.Pages
return; return;
} }
if(!await _userDialogs.ConfirmAsync(AppResources.DoYouReallyWantToDelete, null, AppResources.Yes, AppResources.No)) var confirmed = await DisplayAlert(null, AppResources.DoYouReallyWantToDelete, AppResources.Yes,
AppResources.No);
if(!confirmed)
{ {
return; return;
} }
@ -871,11 +872,11 @@ namespace Bit.App.Pages
} }
else if(deleteTask.Errors.Count() > 0) else if(deleteTask.Errors.Count() > 0)
{ {
await _userDialogs.AlertAsync(deleteTask.Errors.First().Message, AppResources.AnErrorHasOccurred); await DisplayAlert(AppResources.AnErrorHasOccurred, deleteTask.Errors.First().Message, AppResources.Ok);
} }
else else
{ {
await _userDialogs.AlertAsync(AppResources.AnErrorHasOccurred); await DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
} }
} }

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Acr.UserDialogs;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.App.Resources; using Bit.App.Resources;
@ -21,7 +20,6 @@ namespace Bit.App.Pages
private readonly IFolderService _folderService; private readonly IFolderService _folderService;
private readonly ICollectionService _collectionService; private readonly ICollectionService _collectionService;
private readonly ICipherService _cipherService; private readonly ICipherService _cipherService;
private readonly IUserDialogs _userDialogs;
private readonly IConnectivity _connectivity; private readonly IConnectivity _connectivity;
private readonly IDeviceActionService _deviceActionService; private readonly IDeviceActionService _deviceActionService;
private readonly ISyncService _syncService; private readonly ISyncService _syncService;
@ -39,7 +37,6 @@ namespace Bit.App.Pages
_collectionService = Resolver.Resolve<ICollectionService>(); _collectionService = Resolver.Resolve<ICollectionService>();
_cipherService = Resolver.Resolve<ICipherService>(); _cipherService = Resolver.Resolve<ICipherService>();
_connectivity = Resolver.Resolve<IConnectivity>(); _connectivity = Resolver.Resolve<IConnectivity>();
_userDialogs = Resolver.Resolve<IUserDialogs>();
_deviceActionService = Resolver.Resolve<IDeviceActionService>(); _deviceActionService = Resolver.Resolve<IDeviceActionService>();
_syncService = Resolver.Resolve<ISyncService>(); _syncService = Resolver.Resolve<ISyncService>();
_pushNotification = Resolver.Resolve<IPushNotificationService>(); _pushNotification = Resolver.Resolve<IPushNotificationService>();
@ -119,7 +116,7 @@ namespace Bit.App.Pages
Title = AppResources.MyVault; Title = AppResources.MyVault;
} }
protected override void OnAppearing() protected async override void OnAppearing()
{ {
base.OnAppearing(); base.OnAppearing();
MessagingCenter.Subscribe<Application, bool>(Application.Current, "SyncCompleted", (sender, success) => MessagingCenter.Subscribe<Application, bool>(Application.Current, "SyncCompleted", (sender, success) =>
@ -145,29 +142,16 @@ namespace Bit.App.Pages
if(Device.RuntimePlatform == Device.iOS) if(Device.RuntimePlatform == Device.iOS)
{ {
var pushPromptShow = _settings.GetValueOrDefault(Constants.PushInitialPromptShown, false); var pushPromptShow = _settings.GetValueOrDefault(Constants.PushInitialPromptShown, false);
Action registerAction = () =>
{
if(!pushPromptShow || DateTime.UtcNow - lastPushRegistration > TimeSpan.FromDays(1))
{
_pushNotification.Register();
}
};
if(!pushPromptShow) if(!pushPromptShow)
{ {
_settings.AddOrUpdateValue(Constants.PushInitialPromptShown, true); _settings.AddOrUpdateValue(Constants.PushInitialPromptShown, true);
_userDialogs.Alert(new AlertConfig await DisplayAlert(AppResources.EnableAutomaticSyncing, AppResources.PushNotificationAlert,
{ AppResources.OkGotIt);
Message = AppResources.PushNotificationAlert,
Title = AppResources.EnableAutomaticSyncing,
OnAction = registerAction,
OkText = AppResources.OkGotIt
});
} }
else
if(!pushPromptShow || DateTime.UtcNow - lastPushRegistration > TimeSpan.FromDays(1))
{ {
// Check push registration once per day _pushNotification.Register();
registerAction();
} }
} }
else if(Device.RuntimePlatform == Device.Android && else if(Device.RuntimePlatform == Device.Android &&

View file

@ -133,11 +133,11 @@ namespace Bit.App.Pages
LoginUriCell = new LabeledValueCell(AppResources.Website, button1Image: "launch.png"); LoginUriCell = new LabeledValueCell(AppResources.Website, button1Image: "launch.png");
LoginUriCell.Value.SetBinding(Label.TextProperty, nameof(VaultViewCipherPageModel.LoginUriHost)); LoginUriCell.Value.SetBinding(Label.TextProperty, nameof(VaultViewCipherPageModel.LoginUriHost));
LoginUriCell.Button1.SetBinding(IsVisibleProperty, nameof(VaultViewCipherPageModel.ShowLoginLaunch)); LoginUriCell.Button1.SetBinding(IsVisibleProperty, nameof(VaultViewCipherPageModel.ShowLoginLaunch));
LoginUriCell.Button1.Command = new Command(() => LoginUriCell.Button1.Command = new Command(async () =>
{ {
if(Device.RuntimePlatform == Device.Android && Model.LoginUri.StartsWith("androidapp://")) if(Device.RuntimePlatform == Device.Android && Model.LoginUri.StartsWith("androidapp://"))
{ {
_deviceActionService.LaunchApp(Model.LoginUri); await _deviceActionService.LaunchAppAsync(Model.LoginUri, this);
} }
else if(Model.LoginUri.StartsWith("http://") || Model.LoginUri.StartsWith("https://")) else if(Model.LoginUri.StartsWith("http://") || Model.LoginUri.StartsWith("https://"))
{ {
@ -433,7 +433,7 @@ namespace Bit.App.Pages
{ {
if(!_tokenService.TokenPremium && !cipher.OrganizationUseTotp) if(!_tokenService.TokenPremium && !cipher.OrganizationUseTotp)
{ {
_userDialogs.Alert(AppResources.PremiumRequired); await DisplayAlert(null, AppResources.PremiumRequired, AppResources.Ok);
return; return;
} }
@ -447,22 +447,23 @@ namespace Bit.App.Pages
if(!_deviceActionService.CanOpenFile(attachment.Name)) if(!_deviceActionService.CanOpenFile(attachment.Name))
{ {
await _userDialogs.AlertAsync(AppResources.UnableToOpenFile, null, AppResources.Ok); await DisplayAlert(null, AppResources.UnableToOpenFile, AppResources.Ok);
return; return;
} }
_userDialogs.ShowLoading(AppResources.Downloading, MaskType.Black); _userDialogs.ShowLoading(AppResources.Downloading, MaskType.Black);
var data = await _cipherService.DownloadAndDecryptAttachmentAsync(attachment.Url, cipher.OrganizationId); var data = await _cipherService.DownloadAndDecryptAttachmentAsync(attachment.Url, cipher.OrganizationId);
_userDialogs.HideLoading(); _userDialogs.HideLoading();
if(data == null) if(data == null)
{ {
await _userDialogs.AlertAsync(AppResources.UnableToDownloadFile, null, AppResources.Ok); await DisplayAlert(null, AppResources.UnableToDownloadFile, AppResources.Ok);
return; return;
} }
if(!_deviceActionService.OpenFile(data, attachment.Id, attachment.Name)) if(!_deviceActionService.OpenFile(data, attachment.Id, attachment.Name))
{ {
await _userDialogs.AlertAsync(AppResources.UnableToOpenFile, null, AppResources.Ok); await DisplayAlert(null, AppResources.UnableToOpenFile, AppResources.Ok);
return; return;
} }
} }

View file

@ -164,9 +164,8 @@ namespace Bit.App.Utilities
public static async void AddCipher(Page page, string folderId) public static async void AddCipher(Page page, string folderId)
{ {
var type = await Resolver.Resolve<IUserDialogs>().ActionSheetAsync( var type = await page.DisplayActionSheet(AppResources.SelectTypeAdd, AppResources.Cancel, null,
AppResources.SelectTypeAdd, AppResources.Cancel, null, null, AppResources.TypeLogin, AppResources.TypeLogin, AppResources.TypeCard, AppResources.TypeIdentity, AppResources.TypeSecureNote);
AppResources.TypeCard, AppResources.TypeIdentity, AppResources.TypeSecureNote);
var selectedType = CipherType.SecureNote; var selectedType = CipherType.SecureNote;
if(type == AppResources.Cancel) if(type == AppResources.Cancel)

View file

@ -16,12 +16,10 @@ namespace Bit.UWP
null, null,
Resolver.Resolve<IAuthService>(), Resolver.Resolve<IAuthService>(),
Resolver.Resolve<IConnectivity>(), Resolver.Resolve<IConnectivity>(),
Resolver.Resolve<IUserDialogs>(),
Resolver.Resolve<IDatabaseService>(), Resolver.Resolve<IDatabaseService>(),
Resolver.Resolve<ISyncService>(), Resolver.Resolve<ISyncService>(),
Resolver.Resolve<ISettings>(), Resolver.Resolve<ISettings>(),
Resolver.Resolve<ILockService>(), Resolver.Resolve<ILockService>(),
Resolver.Resolve<IGoogleAnalyticsService>(),
Resolver.Resolve<ILocalizeService>(), Resolver.Resolve<ILocalizeService>(),
Resolver.Resolve<IAppInfoService>(), Resolver.Resolve<IAppInfoService>(),
Resolver.Resolve<IAppSettingsService>(), Resolver.Resolve<IAppSettingsService>(),

View file

@ -60,12 +60,10 @@ namespace Bit.iOS
null, null,
Resolver.Resolve<IAuthService>(), Resolver.Resolve<IAuthService>(),
Resolver.Resolve<IConnectivity>(), Resolver.Resolve<IConnectivity>(),
Resolver.Resolve<IUserDialogs>(),
Resolver.Resolve<IDatabaseService>(), Resolver.Resolve<IDatabaseService>(),
Resolver.Resolve<ISyncService>(), Resolver.Resolve<ISyncService>(),
Resolver.Resolve<ISettings>(), Resolver.Resolve<ISettings>(),
_lockService, _lockService,
Resolver.Resolve<IGoogleAnalyticsService>(),
Resolver.Resolve<ILocalizeService>(), Resolver.Resolve<ILocalizeService>(),
Resolver.Resolve<IAppInfoService>(), Resolver.Resolve<IAppInfoService>(),
Resolver.Resolve<IAppSettingsService>(), Resolver.Resolve<IAppSettingsService>(),