using System; using System.Threading.Tasks; using System.Windows.Input; using Bit.App.Abstractions; using Bit.App.Resources; using Bit.App.Utilities; using Bit.Core.Abstractions; using Bit.Core.Services; using Bit.Core.Utilities; using Xamarin.CommunityToolkit.ObjectModel; using Xamarin.Essentials; using Xamarin.Forms; namespace Bit.App.Pages { public class ScanPageViewModel : BaseViewModel { private bool _showScanner = true; private string _totpAuthenticationKey; private IPlatformUtilsService _platformUtilsService; private IDeviceActionService _deviceActionService; private ILogger _logger; public ScanPageViewModel() { ToggleScanModeCommand = new AsyncCommand(ToggleScanMode, onException: HandleException); _platformUtilsService = ServiceContainer.Resolve("platformUtilsService"); _deviceActionService = ServiceContainer.Resolve("deviceActionService"); _logger = ServiceContainer.Resolve(); InitAsync().FireAndForget(); } public async Task InitAsync() { try { await Device.InvokeOnMainThreadAsync(async () => { var hasCameraPermission = await PermissionManager.CheckAndRequestPermissionAsync(new Permissions.Camera()); HasCameraPermission = hasCameraPermission == PermissionStatus.Granted; ShowScanner = hasCameraPermission == PermissionStatus.Granted; }); if (!HasCameraPermission) { return; } InitScannerCommand.Execute(null); } catch (System.Exception ex) { HandleException(ex); } } public ICommand ToggleScanModeCommand { get; set; } public ICommand InitScannerCommand { get; set; } public bool HasCameraPermission { get; set; } public string ScanQrPageTitle => ShowScanner ? AppResources.ScanQrTitle : AppResources.AuthenticatorKeyScanner; public string CameraInstructionTop => ShowScanner ? AppResources.PointYourCameraAtTheQRCode : AppResources.OnceTheKeyIsSuccessfullyEntered; public string TotpAuthenticationKey { get => _totpAuthenticationKey; set => SetProperty(ref _totpAuthenticationKey, value, additionalPropertyNames: new string[] { nameof(ToggleScanModeLabel) }); } public bool ShowScanner { get => _showScanner; set => SetProperty(ref _showScanner, value, additionalPropertyNames: new string[] { nameof(ToggleScanModeLabel), nameof(ScanQrPageTitle), nameof(CameraInstructionTop) }); } private async Task ToggleScanMode() { var cameraPermission = await PermissionManager.CheckAndRequestPermissionAsync(new Permissions.Camera()); HasCameraPermission = cameraPermission == PermissionStatus.Granted; if (!HasCameraPermission) { var openAppSettingsResult = await _platformUtilsService.ShowDialogAsync(AppResources.EnableCamerPermissionToUseTheScanner, title: string.Empty, confirmText: AppResources.Settings, cancelText: AppResources.NoThanks); if (openAppSettingsResult) { _deviceActionService.OpenAppSettings(); } return; } ShowScanner = !ShowScanner; InitScannerCommand.Execute(null); } public FormattedString ToggleScanModeLabel { get { var fs = new FormattedString(); fs.Spans.Add(new Span { Text = ShowScanner ? AppResources.CannotScanQRCode : AppResources.CannotAddAuthenticatorKey, TextColor = ThemeManager.GetResourceColor("TitleTextColor") }); fs.Spans.Add(new Span { Text = ShowScanner ? AppResources.EnterKeyManually : AppResources.ScanQRCode, TextColor = ThemeManager.GetResourceColor("ScanningToggleModeTextColor") }); return fs; } } private void HandleException(Exception ex) { Xamarin.Essentials.MainThread.InvokeOnMainThreadAsync(async () => { await _deviceActionService.HideLoadingAsync(); await _platformUtilsService.ShowDialogAsync(AppResources.GenericErrorMessage); }).FireAndForget(); _logger.Exception(ex); } } }