Implement status class
MODIFY
WalletWasabi.Gui/Controls/StatusBar.xaml
WalletWasabi.Gui/Controls/StatusBar.xaml
<converters:ShowCursorConverter x:Key="ShowCursorConverter" />
<converters:ShouldDisplayValueConverter x:Key="ShouldDisplayValueConverter" />
<converters:PascalToPhraseConverter x:Key="PascalToPhraseConverter" />
- <converters:StatusBarStatusStringConverter x:Key="StatusBarStatusStringConverter" />
<converters:RpcStatusStringConverter x:Key="RpcStatusStringConverter" />
</UserControl.Resources>
<Grid Cursor="{Binding UpdateAvailable, Converter={StaticResource ShowCursorConverter}}"
<Grid Height="10" Width="10" IsVisible="{Binding CriticalUpdateAvailable}">
<DrawingPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Drawing="{DynamicResource StatusBar_YellowFlag}" />
</Grid>
- <TextBlock Text="{Binding Status, Converter={StaticResource StatusBarStatusStringConverter}}" />
+ <TextBlock Text="{Binding Status}" />
</StackPanel>
</DockPanel>
</Grid>

MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
@@ -229,7 +229,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
try
{
IsBusy = true;
- MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusPriority.BuildingTransaction);
+ MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.BuildingTransaction);
var label = new SmartLabel(_labelSuggestion.Label);
_labelSuggestion.Label = label;
@@ -291,7 +291,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
var intent = new PaymentIntent(address, moneyRequest, label);
try
{
- MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusPriority.DequeuingSelectedCoins);
+ MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.DequeuingSelectedCoins);
TxoRef[] toDequeue = selectedCoinViewModels.Where(x => x.CoinJoinInProgress).Select(x => x.Model.GetTxoRef()).ToArray();
if (toDequeue != null && toDequeue.Any())
{
@@ -305,7 +305,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
}
finally
{
- MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusPriority.DequeuingSelectedCoins);
+ MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.DequeuingSelectedCoins);
}
if (!KeyManager.IsWatchOnly)
@@ -352,7 +352,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
return;
}
- MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusPriority.SigningTransaction);
+ MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.SigningTransaction);
SmartTransaction signedTransaction = result.Transaction;
if (IsHardwareWallet && !result.Signed) // If hardware but still has a privkey then it's password, then meh.
@@ -360,7 +360,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
try
{
IsHardwareBusy = true;
- MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusPriority.AcquiringSignatureFromHardwareWallet);
+ MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.AcquiringSignatureFromHardwareWallet);
var client = new HwiClient(Global.Network);
using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
@@ -383,12 +383,12 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
}
finally
{
- MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusPriority.AcquiringSignatureFromHardwareWallet);
+ MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.AcquiringSignatureFromHardwareWallet);
IsHardwareBusy = false;
}
}
- MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusPriority.BroadcastingTransaction);
+ MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.BroadcastingTransaction);
await Task.Run(async () => await Global.TransactionBroadcaster.SendTransactionAsync(signedTransaction));
ResetUi();
@@ -408,7 +408,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
}
finally
{
- MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusPriority.BuildingTransaction, StatusPriority.SigningTransaction, StatusPriority.BroadcastingTransaction);
+ MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.BuildingTransaction, StatusType.SigningTransaction, StatusType.BroadcastingTransaction);
IsBusy = false;
}
},

MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/TransactionBroadcasterViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/TransactionBroadcasterViewModel.cs
@@ -201,7 +201,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
transaction = new SmartTransaction(Transaction.Parse(TransactionString, Global.Network ?? Network.Main), WalletWasabi.Models.Height.Unknown);
}
- MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusPriority.BroadcastingTransaction);
+ MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.BroadcastingTransaction);
await Task.Run(async () => await Global.TransactionBroadcaster.SendTransactionAsync(transaction));
NotificationHelpers.Success("Transaction is successfully sent!");
@@ -213,7 +213,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
}
finally
{
- MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusPriority.BroadcastingTransaction);
+ MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.BroadcastingTransaction);
IsBusy = false;
ButtonText = "Broadcast Transaction";
}

DELETE
WalletWasabi.Gui/Converters/StatusBarStatusStringConverter.cs
-using Avalonia.Data.Converters;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Text;
-using WalletWasabi.Exceptions;
-using WalletWasabi.Gui.Models.StatusBarStatuses;
-
-namespace WalletWasabi.Gui.Converters
-{
- public class StatusBarStatusStringConverter : IValueConverter
- {
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- if (value is StatusPriority status)
- {
- return status switch
- {
- StatusPriority.Ready => "Ready",
- StatusPriority.CriticalUpdate => "THE BACKEND WAS UPGRADED WITH BREAKING CHANGES - PLEASE UPDATE YOUR WASABI WALLET!",
- StatusPriority.OptionalUpdate => "A new version of Wasabi Wallet is available.",
- StatusPriority.Connecting => "Connecting...",
- StatusPriority.Synchronizing => "Synchronizing...",
- StatusPriority.Loading => "Loading...",
- StatusPriority.SettingUpHardwareWallet => "Setting up hardware wallet...",
- StatusPriority.ConnectingToHardwareWallet => "Connecting to hardware wallet...",
- StatusPriority.AcquiringXpubFromHardwareWallet => "Acquiring xpub from hardware wallet...",
- StatusPriority.AcquiringSignatureFromHardwareWallet => "Acquiring signature from hardware wallet...",
- StatusPriority.BuildingTransaction => "Building transaction...",
- StatusPriority.SigningTransaction => "Signing transaction...",
- StatusPriority.BroadcastingTransaction => "Broadcasting transaction...",
- StatusPriority.DequeuingSelectedCoins => "Dequeuing selected coins...",
- _ => status.ToString()
- };
- }
- else
- {
- throw new TypeArgumentException(value, typeof(StatusPriority), nameof(value));
- }
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- throw new NotSupportedException();
- }
- }
-}

ADD
WalletWasabi.Gui/Models/StatusBarStatuses/Status.cs
+using System;
+using System.Collections.Generic;
+using System.Text;
+using WalletWasabi.Helpers;
+
+namespace WalletWasabi.Gui.Models.StatusBarStatuses
+{
+ public class Status
+ {
+ public static Status Started(StatusType type) => new Status(type, 0);
+
+ public static Status Completed(StatusType type) => new Status(type, 100);
+
+ public Status(StatusType type, ushort percentage)
+ {
+ Type = type;
+ Percentage = Guard.InRangeAndNotNull(nameof(percentage), percentage, 0, 100);
+ }
+
+ public StatusType Type { get; }
+ public int Percentage { get; }
+
+ public override string ToString()
+ {
+ var friendlyName = Type switch
+ {
+ StatusType.Ready => "Ready",
+ StatusType.CriticalUpdate => "THE BACKEND WAS UPGRADED WITH BREAKING CHANGES - PLEASE UPDATE YOUR WASABI WALLET!",
+ StatusType.OptionalUpdate => "A new version of Wasabi Wallet is available.",
+ StatusType.Connecting => "Connecting...",
+ StatusType.Synchronizing => "Synchronizing...",
+ StatusType.Loading => "Loading...",
+ StatusType.SettingUpHardwareWallet => "Setting up hardware wallet...",
+ StatusType.ConnectingToHardwareWallet => "Connecting to hardware wallet...",
+ StatusType.AcquiringXpubFromHardwareWallet => "Acquiring xpub from hardware wallet...",
+ StatusType.AcquiringSignatureFromHardwareWallet => "Acquiring signature from hardware wallet...",
+ StatusType.BuildingTransaction => "Building transaction...",
+ StatusType.SigningTransaction => "Signing transaction...",
+ StatusType.BroadcastingTransaction => "Broadcasting transaction...",
+ StatusType.DequeuingSelectedCoins => "Dequeuing selected coins...",
+ _ => Type.ToString()
+ };
+
+ if (Percentage == 0)
+ {
+ return friendlyName;
+ }
+ else
+ {
+ return $"{friendlyName} {Percentage}%";
+ }
+ }
+ }
+}

MODIFY
WalletWasabi.Gui/Models/StatusBarStatuses/StatusSet.cs
WalletWasabi.Gui/Models/StatusBarStatuses/StatusSet.cs
@@ -10,25 +10,25 @@ namespace WalletWasabi.Gui.Models.StatusBarStatuses
{
public class StatusSet : ReactiveObject
{
- private StatusPriority _status;
+ private StatusType _status;
- private HashSet<StatusPriority> ActiveStatuses { get; }
+ private HashSet<StatusType> ActiveStatuses { get; }
private object ActiveStatusesLock { get; }
public StatusSet()
{
- ActiveStatuses = new HashSet<StatusPriority>() { StatusPriority.Ready };
+ ActiveStatuses = new HashSet<StatusType>() { StatusType.Ready };
ActiveStatusesLock = new object();
- CurrentStatus = StatusPriority.Loading;
+ CurrentStatus = StatusType.Loading;
}
- public StatusPriority CurrentStatus
+ public StatusType CurrentStatus
{
get => _status;
set => this.RaiseAndSetIfChanged(ref _status, value);
}
- public bool TryAddStatus(StatusPriority status)
+ public bool TryAddStatus(StatusType status)
{
bool ret;
lock (ActiveStatusesLock)
@@ -49,12 +49,12 @@ namespace WalletWasabi.Gui.Models.StatusBarStatuses
Dispatcher.UIThread.PostLogException(() => CurrentStatus = ActiveStatuses.Min());
}
- public bool TryRemoveStatus(params StatusPriority[] statuses)
+ public bool TryRemoveStatus(params StatusType[] statuses)
{
bool ret = false;
lock (ActiveStatusesLock)
{
- foreach (StatusPriority status in statuses.ToHashSet())
+ foreach (StatusType status in statuses.ToHashSet())
{
ret = ActiveStatuses.Remove(status) || ret;
}

RENAME
WalletWasabi.Gui/Models/StatusBarStatuses/StatusPriority.cs
WalletWasabi.Gui/Models/StatusBarStatuses/StatusType.cs
@@ -7,7 +7,7 @@ namespace WalletWasabi.Gui.Models.StatusBarStatuses
/// <summary>
/// Order: piority the lower.
/// </summary>
- public enum StatusPriority
+ public enum StatusType
{
CriticalUpdate,
OptionalUpdate,

MODIFY
WalletWasabi.Gui/Tabs/WalletManager/LoadWalletViewModel.cs
WalletWasabi.Gui/Tabs/WalletManager/LoadWalletViewModel.cs
@@ -384,7 +384,7 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
try
{
IsHardwareBusy = true;
- MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusPriority.SettingUpHardwareWallet);
+ MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.SettingUpHardwareWallet);
// Setup may take a while for users to write down stuff.
using (var ctsSetup = new CancellationTokenSource(TimeSpan.FromMinutes(21)))
@@ -401,13 +401,13 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
}
}
- MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusPriority.ConnectingToHardwareWallet);
+ MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.ConnectingToHardwareWallet);
await EnumerateHardwareWalletsAsync();
}
finally
{
IsHardwareBusy = false;
- MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusPriority.SettingUpHardwareWallet, StatusPriority.ConnectingToHardwareWallet);
+ MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.SettingUpHardwareWallet, StatusType.ConnectingToHardwareWallet);
}
return await LoadKeyManagerAsync(requirePassword, isHardwareWallet);
@@ -447,13 +447,13 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
try
{
- MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusPriority.AcquiringXpubFromHardwareWallet);
+ MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.AcquiringXpubFromHardwareWallet);
extPubKey = await client.GetXpubAsync(selectedWallet.HardwareWalletInfo.Model, selectedWallet.HardwareWalletInfo.Path, KeyManager.DefaultAccountKeyPath, cts.Token);
}
finally
{
cts?.Dispose();
- MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusPriority.AcquiringXpubFromHardwareWallet);
+ MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.AcquiringXpubFromHardwareWallet);
}
Logger.LogInfo("Hardware wallet was not used previously on this computer. Creating a new wallet file.");
@@ -609,7 +609,7 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
try
{
IsBusy = true;
- MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusPriority.Loading);
+ MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.Loading);
var keyManager = await LoadKeyManagerAsync(IsPasswordRequired, IsHardwareWallet);
if (keyManager is null)
@@ -646,7 +646,7 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
}
finally
{
- MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusPriority.Loading);
+ MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.Loading);
IsBusy = false;
}
}

MODIFY
WalletWasabi.Gui/ViewModels/StatusBarViewModel.cs
WalletWasabi.Gui/ViewModels/StatusBarViewModel.cs
@@ -48,7 +48,7 @@ namespace WalletWasabi.Gui.ViewModels
private int _peers;
private ObservableAsPropertyHelper<int> _filtersLeft;
private string _btcPrice;
- private ObservableAsPropertyHelper<StatusPriority> _status;
+ private ObservableAsPropertyHelper<string> _status;
private bool _downloadingBlock;
public Global Global { get; }
private StatusSet ActiveStatuses { get; }
@@ -81,6 +81,7 @@ namespace WalletWasabi.Gui.ViewModels
BitcoinCoreStatus = rpcMonitor?.RpcStatus ?? RpcStatus.Unresponsive;
_status = ActiveStatuses.WhenAnyValue(x => x.CurrentStatus)
+ .Select(x => x.ToString())
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.Status)
.DisposeWith(Disposables);
@@ -146,11 +147,11 @@ namespace WalletWasabi.Gui.ViewModels
(int filtersLeft, bool downloadingBlock, bool useCore, RpcStatus coreStatus) = tup;
if (filtersLeft == 0 && !downloadingBlock && (!useCore || coreStatus?.Synchronized is true))
{
- TryRemoveStatus(StatusPriority.Synchronizing);
+ TryRemoveStatus(StatusType.Synchronizing);
}
else
{
- TryAddStatus(StatusPriority.Synchronizing);
+ TryAddStatus(StatusType.Synchronizing);
}
});
@@ -164,11 +165,11 @@ namespace WalletWasabi.Gui.ViewModels
var p2pConnected = useCore ? coreStatus?.Success is true : peers >= 1;
if (tor == TorStatus.NotRunning || backend != BackendStatus.Connected || !p2pConnected)
{
- TryAddStatus(StatusPriority.Connecting);
+ TryAddStatus(StatusType.Connecting);
}
else
{
- TryRemoveStatus(StatusPriority.Connecting);
+ TryRemoveStatus(StatusType.Connecting);
}
});
@@ -178,20 +179,20 @@ namespace WalletWasabi.Gui.ViewModels
{
if (x.BackendCompatible)
{
- TryRemoveStatus(StatusPriority.CriticalUpdate);
+ TryRemoveStatus(StatusType.CriticalUpdate);
}
else
{
- TryAddStatus(StatusPriority.CriticalUpdate);
+ TryAddStatus(StatusType.CriticalUpdate);
}
if (x.ClientUpToDate)
{
- TryRemoveStatus(StatusPriority.OptionalUpdate);
+ TryRemoveStatus(StatusType.OptionalUpdate);
}
else
{
- TryAddStatus(StatusPriority.OptionalUpdate);
+ TryAddStatus(StatusType.OptionalUpdate);
}
UpdateAvailable = !x.ClientUpToDate;
@@ -276,7 +277,7 @@ namespace WalletWasabi.Gui.ViewModels
set => this.RaiseAndSetIfChanged(ref _btcPrice, value);
}
- public StatusPriority Status => _status?.Value ?? StatusPriority.Loading;
+ public string Status => _status?.Value ?? "Loading...";
public bool DownloadingBlock
{
@@ -326,7 +327,7 @@ namespace WalletWasabi.Gui.ViewModels
}
}
- public void TryAddStatus(StatusPriority status)
+ public void TryAddStatus(StatusType status)
{
try
{
@@ -338,7 +339,7 @@ namespace WalletWasabi.Gui.ViewModels
}
}
- public void TryRemoveStatus(params StatusPriority[] statuses)
+ public void TryRemoveStatus(params StatusType[] statuses)
{
try
{

Implement status class