Skip to content

Commit

Permalink
Merge pull request #7510 from wieslawsoltes/vdg/ExpandCoinjoinsTreeDa…
Browse files Browse the repository at this point in the history
…taGrid

[VDG] [Fluent] Allow Coinjoins to be expanded in the TreeDataGrid
  • Loading branch information
soosr committed Apr 4, 2022
2 parents 5d1ab4e + 559bae6 commit d189d8a
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 5 deletions.
@@ -0,0 +1,47 @@
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using NBitcoin;
using ReactiveUI;
using WalletWasabi.Blockchain.Transactions;
using WalletWasabi.Fluent.Extensions;
using WalletWasabi.Fluent.ViewModels.Navigation;

namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.History.HistoryItems;

public class CoinJoinHistoryItemViewModel : HistoryItemViewModelBase
{
public CoinJoinHistoryItemViewModel(
int orderIndex,
TransactionSummary transactionSummary,
WalletViewModel walletViewModel,
Money balance,
IObservable<Unit> updateTrigger)
: base(orderIndex, transactionSummary)
{
Label = transactionSummary.Label.Take(1).FirstOrDefault();
FilteredLabel = transactionSummary.Label.Skip(1).ToList();
IsConfirmed = transactionSummary.IsConfirmed();
Date = transactionSummary.DateTime.ToLocalTime();
Balance = balance;
IsCoinJoin = true;

var amount = transactionSummary.Amount;
if (amount < Money.Zero)
{
OutgoingAmount = amount * -1;
}
else
{
IncomingAmount = amount;
}

ShowDetailsCommand = ReactiveCommand.Create(() =>
RoutableViewModel.Navigate(NavigationTarget.DialogScreen).To(
new TransactionDetailsViewModel(transactionSummary, walletViewModel.Wallet, updateTrigger)));

DateString = $"{Date.ToLocalTime():MM/dd/yy HH:mm}";
}

public bool IsCoinJoinTransaction => true;
}
@@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Immutable;
using System.Linq;
using System.Reactive;
using NBitcoin;
using ReactiveUI;
using WalletWasabi.Blockchain.Transactions;
Expand All @@ -11,9 +13,19 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Home.History.HistoryItems;

public class CoinJoinsHistoryItemViewModel : HistoryItemViewModelBase
{
public CoinJoinsHistoryItemViewModel(int orderIndex, TransactionSummary firstItem)
private readonly WalletViewModel _walletViewModel;
private readonly IObservable<Unit> _updateTrigger;

public CoinJoinsHistoryItemViewModel(
int orderIndex,
TransactionSummary firstItem,
WalletViewModel walletViewModel,
IObservable<Unit> updateTrigger)
: base(orderIndex, firstItem)
{
_walletViewModel = walletViewModel;
_updateTrigger = updateTrigger;

CoinJoinTransactions = new List<TransactionSummary>();
Label = "Coinjoins";
FilteredLabel = new List<string>();
Expand All @@ -26,6 +38,31 @@ public CoinJoinsHistoryItemViewModel(int orderIndex, TransactionSummary firstIte

public List<TransactionSummary> CoinJoinTransactions { get; private set; }

protected override ObservableCollection<HistoryItemViewModelBase> LoadChildren()
{
var result = new ObservableCollection<HistoryItemViewModelBase>();

var balance = Balance ?? Money.Zero;

for (var i = 0; i < CoinJoinTransactions.Count; i++)
{
var item = CoinJoinTransactions[i];

var transaction = new CoinJoinHistoryItemViewModel(
i,
item,
_walletViewModel,
balance,
_updateTrigger);

balance -= item.Amount;

result.Add(transaction);
}

return result;
}

public void Add(TransactionSummary item)
{
if (!item.IsOwnCoinjoin)
Expand Down
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reactive.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
Expand All @@ -16,6 +17,8 @@ public abstract partial class HistoryItemViewModelBase : ViewModelBase
[AutoNotify] private DateTimeOffset _date;
[AutoNotify] private string _dateString = "";
[AutoNotify] private bool _isConfirmed;
[AutoNotify] private bool _isExpanded;
private ObservableCollection<HistoryItemViewModelBase>? _children;

protected HistoryItemViewModelBase(int orderIndex, TransactionSummary transactionSummary)
{
Expand All @@ -39,6 +42,8 @@ protected HistoryItemViewModelBase(int orderIndex, TransactionSummary transactio

public bool IsCoinJoin { get; protected set; }

public IReadOnlyList<HistoryItemViewModelBase> Children => _children ??= LoadChildren();

public Money? Balance { get; protected set; }

public Money? OutgoingAmount { get; protected set; }
Expand All @@ -47,6 +52,11 @@ protected HistoryItemViewModelBase(int orderIndex, TransactionSummary transactio

public ICommand? ShowDetailsCommand { get; protected set; }

protected virtual ObservableCollection<HistoryItemViewModelBase> LoadChildren()
{
throw new NotSupportedException();
}

public static Comparison<HistoryItemViewModelBase?> SortAscending<T>(Func<HistoryItemViewModelBase, T> selector)
{
return (x, y) =>
Expand Down
Expand Up @@ -66,11 +66,12 @@ public HistoryViewModel(WalletViewModel walletViewModel, IObservable<Unit> updat
// Outgoing OutgoingColumnView Outgoing (BTC) Auto 130 150 true
// Balance BalanceColumnView Balance (BTC) Auto 130 150 true

Source = new FlatTreeDataGridSource<HistoryItemViewModelBase>(_transactions)
Source = new HierarchicalTreeDataGridSource<HistoryItemViewModelBase>(_transactions)
{
Columns =
{
// Indicators
new HierarchicalExpanderColumn<HistoryItemViewModelBase>(
new TemplateColumn<HistoryItemViewModelBase>(
null,
new FuncDataTemplate<HistoryItemViewModelBase>((node, ns) => new IndicatorsColumnView(), true),
Expand All @@ -83,6 +84,18 @@ public HistoryViewModel(WalletViewModel walletViewModel, IObservable<Unit> updat
MinWidth = new GridLength(80, GridUnitType.Pixel)
},
width: new GridLength(0, GridUnitType.Auto)),
x => x.Children,
x =>
{
if (x is CoinJoinsHistoryItemViewModel coinJoinsHistoryItemViewModel
&& coinJoinsHistoryItemViewModel.CoinJoinTransactions.Count > 1)
{
return true;
}
return false;
},
x => x.IsExpanded),

// Date
new PrivacyTextColumn<HistoryItemViewModelBase>(
Expand Down Expand Up @@ -172,7 +185,7 @@ public HistoryViewModel(WalletViewModel walletViewModel, IObservable<Unit> updat

public ObservableCollection<HistoryItemViewModelBase> Transactions => _transactions;

public FlatTreeDataGridSource<HistoryItemViewModelBase> Source { get; }
public HierarchicalTreeDataGridSource<HistoryItemViewModelBase> Source { get; }

public void SelectTransaction(uint256 txid)
{
Expand Down Expand Up @@ -250,7 +263,7 @@ private IEnumerable<HistoryItemViewModelBase> GenerateHistoryList(List<Transacti
{
if (coinJoinGroup is null)
{
coinJoinGroup = new CoinJoinsHistoryItemViewModel(i, item);
coinJoinGroup = new CoinJoinsHistoryItemViewModel(i, item, _walletViewModel, _updateTrigger);
}
else
{
Expand Down
Expand Up @@ -62,7 +62,9 @@
<TreeDataGridCellsPresenter Name="PART_CellsPresenter"
ElementFactory="{TemplateBinding ElementFactory}"
Items="{TemplateBinding Columns}"
Rows="{TemplateBinding Rows}"/>
Rows="{TemplateBinding Rows}"
Classes.coinJoinTransaction="{Binding IsCoinJoinTransaction}"
x:CompileBindings="False"/>
</Panel>
</DockPanel>
</ControlTemplate>
Expand Down Expand Up @@ -100,6 +102,15 @@
<Style Selector="TreeDataGridRow:selected /template/ TreeDataGridCellsPresenter#PART_CellsPresenter">
<Setter Property="Background" Value="Transparent" />
</Style>
<Style Selector="TreeDataGridRow /template/ TreeDataGridCellsPresenter#PART_CellsPresenter.coinJoinTransaction">
<Setter Property="Background" Value="{DynamicResource SystemListLowColor}"/>
</Style>
<Style Selector="TreeDataGridRow:selected /template/ TreeDataGridCellsPresenter#PART_CellsPresenter.coinJoinTransaction">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style Selector="TreeDataGridRow:pointerover /template/ TreeDataGridCellsPresenter#PART_CellsPresenter.coinJoinTransaction">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style Selector="TextBlock.hidden">
<Setter Property="IsVisible" Value="False" />
</Style>
Expand All @@ -118,6 +129,28 @@
</i:BehaviorCollectionTemplate>
</Setter>
</Style>

<Style Selector="TreeDataGridExpanderCell">
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}"
Padding="0">
<DockPanel>
<Border DockPanel.Dock="Left"
Margin="4 0"
Width="12" Height="12">
<ToggleButton Classes="ExpandCollapseChevron"
Focusable="False"
IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}"
IsVisible="{TemplateBinding ShowExpander}"/>
</Border>
<Decorator Name="PART_Content"/>
</DockPanel>
</Border>
</ControlTemplate>
</Setter>
</Style>

<Style Selector="behaviors|TreeDataGridItemDetailsAdorner">
<Setter Property="Margin" Value="-31,0,0,0" />
<Setter Property="HorizontalAlignment" Value="Left" />
Expand Down

0 comments on commit d189d8a

Please sign in to comment.