public AddressViewModel(HdPubKey model, KeyManager km, ReceiveTabViewModel owner) { Global = Locator.Current.GetService <Global>(); KeyManager = km; Owner = owner; IsHardwareWallet = km.IsHardwareWallet; Model = model; ClipboardNotificationVisible = false; ClipboardNotificationOpacity = 0; _label = model.Label; this.WhenAnyValue(x => x.IsExpanded) .ObserveOn(RxApp.TaskpoolScheduler) .Where(x => x) .Take(1) .Select(x => { var encoder = new QrEncoder(); encoder.TryEncode(Address, out var qrCode); return(qrCode.Matrix.InternalArray); }) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(qr => QrCode = qr, onError: ex => Logger.LogError(ex)); // Catch the exceptions everywhere (e.g.: Select) except in Subscribe. Global.UiConfig .WhenAnyValue(x => x.LurkingWifeMode) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => { this.RaisePropertyChanged(nameof(IsLurkingWifeMode)); this.RaisePropertyChanged(nameof(Address)); this.RaisePropertyChanged(nameof(Label)); }).DisposeWith(Disposables); this.WhenAnyValue(x => x.Label) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(newLabel => { if (InEditMode) { KeyManager keyManager = KeyManager; HdPubKey hdPubKey = keyManager.GetKeys(x => Model == x).FirstOrDefault(); if (hdPubKey != default) { hdPubKey.SetLabel(newLabel, kmToFile: keyManager); } } }); _expandMenuCaption = this .WhenAnyValue(x => x.IsExpanded) .Select(x => (x ? "Hide " : "Show ") + "QR Code") .ObserveOn(RxApp.MainThreadScheduler) .ToProperty(this, x => x.ExpandMenuCaption) .DisposeWith(Disposables); ToggleQrCode = ReactiveCommand.Create(() => IsExpanded = !IsExpanded); SaveQRCode = ReactiveCommand.CreateFromTask(SaveQRCodeAsync); CopyAddress = ReactiveCommand.CreateFromTask(TryCopyToClipboardAsync); CopyLabel = ReactiveCommand.CreateFromTask(async() => await Application.Current.Clipboard.SetTextAsync(Label ?? string.Empty)); ChangeLabel = ReactiveCommand.Create(() => InEditMode = true); DisplayAddressOnHw = ReactiveCommand.CreateFromTask(async() => { var client = new HwiClient(Global.Network); using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); try { await client.DisplayAddressAsync(KeyManager.MasterFingerprint.Value, Model.FullKeyPath, cts.Token); } catch (HwiException) { await PinPadViewModel.UnlockAsync(); await client.DisplayAddressAsync(KeyManager.MasterFingerprint.Value, Model.FullKeyPath, cts.Token); } }); LockAddress = ReactiveCommand.CreateFromTask(async() => { Model.SetKeyState(KeyState.Locked, km); owner.InitializeAddresses(); bool isAddressCopied = await Application.Current.Clipboard.GetTextAsync() == Address; if (isAddressCopied) { await Application.Current.Clipboard.ClearAsync(); } }); Observable .Merge(ToggleQrCode.ThrownExceptions) .Merge(SaveQRCode.ThrownExceptions) .Merge(CopyAddress.ThrownExceptions) .Merge(CopyLabel.ThrownExceptions) .Merge(ChangeLabel.ThrownExceptions) .Merge(DisplayAddressOnHw.ThrownExceptions) .Merge(LockAddress.ThrownExceptions) .Subscribe(ex => { Logger.LogError(ex); NotificationHelpers.Error(ex.ToUserFriendlyString()); }); }