public StatusBarViewModel()
        {
            UpdateStatus            = UpdateStatus.Latest;
            UpdateAvailable         = false;
            CriticalUpdateAvailable = false;
            Backend     = BackendStatus.NotConnected;
            UseTor      = false;
            Tor         = TorStatus.NotRunning;
            Peers       = 0;
            FiltersLeft = 0;
            BlocksLeft  = 0;
            BtcPrice    = "$0";
            StatusText  = "";

            StatusTextAnimationLock = new AsyncLock();

            this.WhenAnyValue(x => x.Status).Subscribe(status =>

            {
                StatusText = StatusBarStatusStringConverter.Convert(status);
            });

            this.WhenAnyValue(x => x.StatusText).Subscribe(async status =>
            {
                using (await StatusTextAnimationLock.LockAsync()) // Without this lock the status get stuck once in a while.
                {
                    if (status.EndsWith("."))                     // Then do animation.
                    {
                        string nextAnimation = null;
                        if (status.EndsWith("..."))
                        {
                            nextAnimation = status.TrimEnd("..", StringComparison.Ordinal);
                        }
                        else if (status.EndsWith("."))
                        {
                            nextAnimation = $"{status}.";
                        }

                        if (nextAnimation != null)
                        {
                            await Task.Delay(1000);
                            if (StatusText == status)                             // If still the same.
                            {
                                StatusText = nextAnimation;
                            }
                        }
                    }
                }
            });

            Status = StatusBarStatus.Loading;
        }
Example #2
0
        public StatusBarViewModel(NodesCollection nodes, WasabiSynchronizer synchronizer, UpdateChecker updateChecker)
        {
            UpdateStatus            = UpdateStatus.Latest;
            Nodes                   = nodes;
            Synchronizer            = synchronizer;
            BlocksLeft              = 0;
            FiltersLeft             = synchronizer.GetFiltersLeft();
            UseTor                  = Global.Config.UseTor.Value; // Don't make it dynamic, because if you change this config settings only next time will it activate.
            StatusTextAnimationLock = new AsyncLock();

            Observable.FromEventPattern <NodeEventArgs>(nodes, nameof(nodes.Added))
            .Subscribe(x =>
            {
                SetPeers(Nodes.Count);
            }).DisposeWith(Disposables);

            Observable.FromEventPattern <NodeEventArgs>(nodes, nameof(nodes.Removed))
            .Subscribe(x =>
            {
                SetPeers(Nodes.Count);
            }).DisposeWith(Disposables);

            SetPeers(Nodes.Count);

            Observable.FromEventPattern <int>(typeof(WalletService), nameof(WalletService.ConcurrentBlockDownloadNumberChanged))
            .Subscribe(x =>
            {
                BlocksLeft = x.EventArgs;
            }).DisposeWith(Disposables);

            Observable.FromEventPattern(synchronizer, nameof(synchronizer.NewFilter)).Subscribe(x =>
            {
                FiltersLeft = Synchronizer.GetFiltersLeft();
            }).DisposeWith(Disposables);

            synchronizer.WhenAnyValue(x => x.TorStatus).Subscribe(status =>
            {
                SetTor(status);
                SetPeers(Nodes.Count);
            }).DisposeWith(Disposables);

            synchronizer.WhenAnyValue(x => x.BackendStatus).Subscribe(_ =>
            {
                Backend = Synchronizer.BackendStatus;
            }).DisposeWith(Disposables);

            synchronizer.WhenAnyValue(x => x.BestBlockchainHeight).Subscribe(_ =>
            {
                FiltersLeft = Synchronizer.GetFiltersLeft();
            }).DisposeWith(Disposables);

            synchronizer.WhenAnyValue(x => x.UsdExchangeRate).Subscribe(usd =>
            {
                BtcPrice = $"${(long)usd}";
            }).DisposeWith(Disposables);

            Observable.FromEventPattern <bool>(synchronizer, nameof(synchronizer.ResponseArrivedIsGenSocksServFail))
            .Subscribe(e =>
            {
                OnResponseArrivedIsGenSocksServFail(e.EventArgs);
            }).DisposeWith(Disposables);

            this.WhenAnyValue(x => x.BlocksLeft).Subscribe(blocks =>
            {
                RefreshStatus();
            });

            this.WhenAnyValue(x => x.FiltersLeft).Subscribe(filters =>
            {
                RefreshStatus();
            });

            this.WhenAnyValue(x => x.Tor).Subscribe(tor =>
            {
                RefreshStatus();
            });

            this.WhenAnyValue(x => x.Backend).Subscribe(backend =>
            {
                RefreshStatus();
            });

            this.WhenAnyValue(x => x.Peers).Subscribe(peers =>
            {
                RefreshStatus();
            });

            this.WhenAnyValue(x => x.UpdateStatus).Subscribe(_ =>
            {
                RefreshStatus();
            });

            this.WhenAnyValue(x => x.Status).Subscribe(status =>
            {
                StatusText = StatusBarStatusStringConverter.Convert(status);
            });

            this.WhenAnyValue(x => x.StatusText).Subscribe(async status =>
            {
                using (await StatusTextAnimationLock.LockAsync()) // Without this lock the status get stuck once in a while.
                {
                    if (status.EndsWith("."))                     // Then do animation.
                    {
                        string nextAnimation = null;
                        if (status.EndsWith("..."))
                        {
                            nextAnimation = status.TrimEnd("..", StringComparison.Ordinal);
                        }
                        else if (status.EndsWith("."))
                        {
                            nextAnimation = $"{status}.";
                        }

                        if (nextAnimation != null)
                        {
                            await Task.Delay(1000);
                            if (StatusText == status)                             // If still the same.
                            {
                                StatusText = nextAnimation;
                            }
                        }
                    }
                }
            });

            UpdateCommand = ReactiveCommand.Create(() =>
            {
                try
                {
                    IoHelpers.OpenBrowser("https://wasabiwallet.io/#download");
                }
                catch (Exception ex)
                {
                    Logging.Logger.LogWarning <StatusBarViewModel>(ex);
                    IoC.Get <IShell>().AddOrSelectDocument(() => new AboutViewModel());
                }
            }, this.WhenAnyValue(x => x.UpdateStatus).Select(x => x != UpdateStatus.Latest));

            updateChecker.Start(TimeSpan.FromMinutes(7),
                                () =>
            {
                UpdateStatus = UpdateStatus.Critical;
                return(Task.CompletedTask);
            },
                                () =>
            {
                if (UpdateStatus != UpdateStatus.Critical)
                {
                    UpdateStatus = UpdateStatus.Optional;
                }
                return(Task.CompletedTask);
            });
        }