UI components use Application's resource dictionnary to fetch app level singletons
MODIFY
WalletWasabi.Gui/Behaviors/PasteAddressOnClickBehavior.cs
WalletWasabi.Gui/Behaviors/PasteAddressOnClickBehavior.cs
@@ -56,6 +56,7 @@ namespace WalletWasabi.Gui.Behaviors
public async Task<(bool isAddress, string address)> IsThereABitcoinAddressOnTheClipboardAsync()
{
+ var network = ((Global)Application.Current.Resources[Global.GlobalResourceKey]).Network;
string text = await Application.Current.Clipboard.GetTextAsync();
if (string.IsNullOrEmpty(text) || text.Length > 100)
{
@@ -65,7 +66,7 @@ namespace WalletWasabi.Gui.Behaviors
text = text.Trim();
try
{
- var bitcoinAddress = BitcoinAddress.Create(text, Global.Instance.Network);
+ var bitcoinAddress = BitcoinAddress.Create(text, network);
return (true, bitcoinAddress.ToString());
}
catch (FormatException)

MODIFY
WalletWasabi.Gui/Controls/MultiTextBox.cs
WalletWasabi.Gui/Controls/MultiTextBox.cs
@@ -198,8 +198,8 @@ namespace WalletWasabi.Gui.Controls
try
{
var eventArgs = eventPattern?.EventArgs as PointerPressedEventArgs;
-
- if (Global.Instance.UiConfig?.Autocopy is true && eventArgs?.MouseButton == MouseButton.Left)
+ var uiConfig = Application.Current.Resources[Global.UIConfigResourceKey] as UiConfig;
+ if (uiConfig?.Autocopy is true && eventArgs?.MouseButton == MouseButton.Left)
{
if (CopyOnClick)
{

MODIFY
WalletWasabi.Gui/Converters/LurkingWifeModeStringConverter.cs
WalletWasabi.Gui/Converters/LurkingWifeModeStringConverter.cs
+using Avalonia;
using Avalonia.Data.Converters;
using System;
using System.Collections.Generic;
@@ -11,7 +12,8 @@ namespace WalletWasabi.Gui.Converters
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
- if (Global.Instance.UiConfig.LurkingWifeMode is true)
+ var uiConfig = (UiConfig)Application.Current.Resources[Global.UIConfigResourceKey];
+ if (uiConfig.LurkingWifeMode is true)
{
int len = 10;
if (int.TryParse(parameter.ToString(), out int newLength))

MODIFY
WalletWasabi.Gui/Converters/PhaseColorConverter.cs
WalletWasabi.Gui/Converters/PhaseColorConverter.cs
+using Avalonia;
using Avalonia.Data.Converters;
using Avalonia.Media;
using System;
@@ -16,8 +17,8 @@ namespace WalletWasabi.Gui.Converters
{
throw new ArgumentException($"Unknown '{parameter}' value");
}
-
- var phaseError = Global.Instance.ChaumianClient.State.IsInErrorState;
+ var global = (Global)Application.Current.Resources[Global.GlobalResourceKey];
+ var phaseError = global.ChaumianClient.State.IsInErrorState;
return ((CcjRoundPhase)p <= (CcjRoundPhase)value)
? (phaseError ? Brushes.IndianRed : Brushes.Green)

MODIFY
WalletWasabi.Gui/Converters/PrivacyLevelValueConverter.cs
WalletWasabi.Gui/Converters/PrivacyLevelValueConverter.cs
@@ -34,18 +34,19 @@ namespace WalletWasabi.Gui.Converters
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
+ var config = (Config)Application.Current.Resources[Global.ConfigResourceKey];
if (value is int integer)
{
string shield;
- if (integer < Global.Instance.Config.PrivacyLevelSome)
+ if (integer < config.PrivacyLevelSome)
{
shield = "Critical";
}
- else if (integer < Global.Instance.Config.PrivacyLevelFine)
+ else if (integer < config.PrivacyLevelFine)
{
shield = "Some";
}
- else if (integer < Global.Instance.Config.PrivacyLevelStrong)
+ else if (integer < config.PrivacyLevelStrong)
{
shield = "Fine";
}

MODIFY
WalletWasabi.Gui/Extensions/AvaloniaExtensions.cs
WalletWasabi.Gui/Extensions/AvaloniaExtensions.cs
@@ -13,5 +13,12 @@ namespace System
{
return shell.Documents.OfType<T>().Single();
}
+ public static void AddOrReplace(this IResourceDictionary resources, object key, object value)
+ {
+ if (resources.TryGetResource(key.ToString(), out _))
+ resources[key] = value;
+ else
+ resources.Add(key, value);
+ }
}
}

MODIFY
WalletWasabi.Gui/Global.cs
WalletWasabi.Gui/Global.cs
@@ -33,6 +33,9 @@ namespace WalletWasabi.Gui
{
public class Global
{
+ public static string GlobalResourceKey = "Wasabi.UI.Global";
+ public static string ConfigResourceKey = "Wasabi.UI.Config";
+ public static string UIConfigResourceKey = "Wasabi.UI.UIConfig";
public static Global Instance { get; } = new Global();
public string DataDir { get; }
public string TorLogsFile { get; }

MODIFY
WalletWasabi.Gui/MainWindow.xaml.cs
WalletWasabi.Gui/MainWindow.xaml.cs
@@ -48,6 +48,15 @@ namespace WalletWasabi.Gui
AvaloniaXamlLoader.Load(this);
}
+ protected override void OnDataContextEndUpdate()
+ {
+ if (Global.Instance == null)
+ return;
+ Application.Current.Resources.AddOrReplace(Global.GlobalResourceKey, Global.Instance);
+ Application.Current.Resources.AddOrReplace(Global.ConfigResourceKey, Global.Instance.Config);
+ Application.Current.Resources.AddOrReplace(Global.UIConfigResourceKey, Global.Instance.UiConfig);
+ }
+
private int _closingState;
private async void MainWindow_ClosingAsync(object sender, CancelEventArgs e)
@@ -161,6 +170,7 @@ namespace WalletWasabi.Gui
var uiConfig = new UiConfig(uiConfigFilePath);
await uiConfig.LoadOrCreateDefaultFileAsync();
Global.Instance.InitializeUiConfig(uiConfig);
+ Application.Current.Resources.AddOrReplace(Global.UIConfigResourceKey, Global.Instance.UiConfig);
Logging.Logger.LogInfo<UiConfig>("UiConfig is successfully initialized.");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))

UI components use Application's resource dictionnary to fetch app level singletons