simplify privacy warning messages.
MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/PocketViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/PocketViewModel.cs
@@ -9,6 +9,8 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
[AutoNotify] private bool _isSelected;
[AutoNotify] private decimal _totalBtc;
[AutoNotify] private SmartLabel _labels;
+ [AutoNotify] private bool _isWarningOpen;
+ [AutoNotify] private string? _warningMessage;
public PocketViewModel((SmartLabel labels, ICoinsView coins) pocket)
{

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/PrivacyControlViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/PrivacyControlViewModel.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Disposables;
+using System.Reactive.Linq;
using System.Threading.Tasks;
using DynamicData;
using DynamicData.Aggregation;
@@ -25,11 +26,11 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
private readonly Wallet _wallet;
private readonly SourceList<PocketViewModel> _pocketSource;
private readonly ReadOnlyObservableCollection<PocketViewModel> _pockets;
+ private PocketViewModel? _privatePocket;
+ private readonly IObservableList<PocketViewModel> _selectedList;
[AutoNotify] private decimal _stillNeeded;
[AutoNotify] private bool _enoughSelected;
- [AutoNotify] private bool _privateFundsSelected;
- [AutoNotify] private bool _showCjNotice;
public PrivacyControlViewModel(Wallet wallet, TransactionInfo transactionInfo, TransactionBroadcaster broadcaster)
{
@@ -45,18 +46,18 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
.AutoRefresh()
.Filter(x => x.IsSelected);
- var selectedList = selected.AsObservableList();
+ _selectedList = selected.AsObservableList();
selected.Sum(x => x.TotalBtc)
.Subscribe(x =>
{
- PrivateFundsSelected = selectedList.Items.Any(pocket =>
- pocket.Labels.FirstOrDefault() == CoinPocketHelper.PrivateFundsText);
+ if (_privatePocket is { })
+ {
+ _privatePocket.IsWarningOpen = _privatePocket.IsSelected && _selectedList.Count > 1;
+ }
StillNeeded = transactionInfo.Amount.ToDecimal(MoneyUnit.BTC) - x;
- EnoughSelected = StillNeeded <= 0 || PrivateFundsSelected;
-
- ShowCjNotice = !PrivateFundsSelected && EnoughSelected;
+ EnoughSelected = StillNeeded <= 0;
});
_pocketSource
@@ -75,7 +76,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
EnableBack = true;
NextCommand = ReactiveCommand.CreateFromTask(
- async () => await OnNext(wallet, transactionInfo, broadcaster, selectedList),
+ async () => await OnNext(wallet, transactionInfo, broadcaster, _selectedList),
this.WhenAnyValue(x => x.EnoughSelected));
EnableAutoBusyOn(NextCommand);
@@ -87,6 +88,11 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
{
var coins = selectedList.Items.SelectMany(x => x.Coins).ToArray();
+ if (_privatePocket != null)
+ {
+ _privatePocket.IsSelected = false;
+ }
+
try
{
try
@@ -127,9 +133,28 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
var pockets = _wallet.Coins.GetPockets(_wallet.ServiceConfiguration.GetMixUntilAnonymitySetValue());
foreach (var pocket in pockets)
+ {
+ if (pocket.SmartLabel.Labels.Any(x => x == CoinPocketHelper.PrivateFundsText))
+ {
+ _privatePocket = new PocketViewModel(pocket)
+ {
+ WarningMessage =
+ "Warning, using both private and non-private funds in the same transaction can destroy your privacy."
+ };
+
+ _pocketSource.Add(_privatePocket);
+ }
+ else
{
_pocketSource.Add(new PocketViewModel(pocket));
}
+ }
+ }
+
+ foreach (var pocket in _pockets)
+ {
+ pocket.IsSelected = false;
+ }
if (_pocketSource.Count == 1)
{
@@ -138,4 +163,3 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
}
}
}
-}

MODIFY
WalletWasabi.Fluent/Views/Wallets/Send/PrivacyControlView.axaml
WalletWasabi.Fluent/Views/Wallets/Send/PrivacyControlView.axaml
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<DockPanel>
<Panel MinHeight="60" DockPanel.Dock="Bottom">
- <c:InfoMessage Foreground="{DynamicResource WarningMessageForeground}" HorizontalAlignment="Center"
- VerticalAlignment="Top" IsVisible="{Binding !EnoughSelected}">
+ <c:InfoMessage Foreground="{DynamicResource WarningMessageForeground}"
+ HorizontalAlignment="Center"
+ IsVisible="{Binding !EnoughSelected}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Insufficient funds selected. Select at least another " />
<TextBlock Text="{Binding StillNeeded}" />
<TextBlock Text=" BTC" />
</StackPanel>
</c:InfoMessage>
- <c:InfoMessage IsVisible="{Binding ShowCjNotice}"
+ <c:InfoMessage IsVisible="{Binding EnoughSelected}"
Content="Not in a hurry? Consider making more of your funds private by CoinJoining before making this transaction."
- HorizontalAlignment="Center" VerticalAlignment="Top" />
- <c:InfoMessage VerticalAlignment="Top"
- Foreground="{DynamicResource WarningMessageForeground}"
- IsVisible="{Binding PrivateFundsSelected}"
- Content="Warning! Using both private and non-private funds in the same transaction can destroy your privacy." />
+ HorizontalAlignment="Center" />
</Panel>
<DataGrid AutoGenerateColumns="False"
Margin="0 20"
<DataGridTemplateColumn CanUserSort="False" Width="*" Header="Labels">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate x:DataType="vm:PocketViewModel">
- <c:TagsBox Items="{Binding Labels}" IsReadOnly="True" />
+ <Panel x:Name="ContainerPanel" HorizontalAlignment="Left">
+ <c:TagsBox Items="{Binding Labels}" IsReadOnly="True" HorizontalAlignment="Left" />
+ <Popup IsOpen="{Binding IsWarningOpen, Mode=TwoWay, FallbackValue=False}" PlacementTarget="ContainerPanel" PlacementMode="Right">
+ <c:InfoMessage Classes="overlay" Padding="15" MaxWidth="400" Foreground="{DynamicResource SystemErrorTextColor}">
+ <TextBlock Text="{Binding WarningMessage}" TextWrapping="Wrap" />
+ </c:InfoMessage>
+ </Popup>
+ </Panel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

simplify privacy warning messages.