Add alternate way to close flyout
ADD
WalletWasabi.Fluent/Helpers/ApplicationHelper.cs
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
+
+namespace WalletWasabi.Fluent.Helpers;
+
+public static class ApplicationHelper
+{
+ public static Window? MainWindow => (Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.MainWindow;
+}

MODIFY
WalletWasabi.Fluent/ViewModels/MainViewModel.cs
WalletWasabi.Fluent/ViewModels/MainViewModel.cs
@@ -2,6 +2,7 @@ using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using Avalonia.Controls;
+using Avalonia.Input;
using NBitcoin;
using ReactiveUI;
using WalletWasabi.Fluent.AppServices.Tor;
@@ -106,11 +107,16 @@ public partial class MainViewModel : ViewModelBase
});
var source = new CompositeSearchItemsSource(new ActionsSource(), new SettingsSource(_settingsPage));
- SearchBar = new SearchBarViewModel(source.Changes);
+ SearchBar = new SearchBarViewModel(source.Changes, () => Focus());
NetworkBadgeName = Services.Config.Network == Network.Main ? "" : Services.Config.Network.Name;
}
+ private void Focus()
+ {
+ ;
+ }
+
public IObservable<bool> IsMainContentEnabled { get; }
public string NetworkBadgeName { get; }

DELETE
WalletWasabi.Fluent/ViewModels/SearchBar/CloseSearchBarMessage.cs
-namespace WalletWasabi.Fluent.ViewModels.SearchBar;
-
-public class CloseSearchBarMessage
-{
-}

MODIFY
WalletWasabi.Fluent/ViewModels/SearchBar/SearchBarDesignViewModel.cs
WalletWasabi.Fluent/ViewModels/SearchBar/SearchBarDesignViewModel.cs
@@ -44,7 +44,7 @@ public class SearchBarDesignViewModel : ReactiveObject
{
Icon = "settings_bitcoin_regular"
}
- }.Select(item => (ISearchItem)new AutocloseActionableItem(item, () => { }));
+ };
_items = actionable.ToList();
}

MODIFY
WalletWasabi.Fluent/ViewModels/SearchBar/SearchBarViewModel.cs
WalletWasabi.Fluent/ViewModels/SearchBar/SearchBarViewModel.cs
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
-using Avalonia.Controls.ApplicationLifetimes;
using DynamicData;
using DynamicData.Aggregation;
using ReactiveUI;
@@ -16,7 +15,7 @@ public partial class SearchBarViewModel : ReactiveObject
[AutoNotify] private bool _isSearchListVisible;
[AutoNotify] private string _searchText = "";
- public SearchBarViewModel(IObservable<IChangeSet<ISearchItem, ComposedKey>> itemsObservable)
+ public SearchBarViewModel(IObservable<IChangeSet<ISearchItem, ComposedKey>> itemsObservable, Action onClose)
{
var filterPredicate = this
.WhenAnyValue(x => x.SearchText)
@@ -29,10 +28,6 @@ public partial class SearchBarViewModel : ReactiveObject
.Filter(filterPredicate);
filteredItems
- .Transform(
- item => item is ActionableItem i
- ? new AutocloseActionableItem(i, () => MessageBus.Current.SendMessage(new CloseSearchBarMessage()))
- : item)
.Group(s => s.Category)
.Transform(group => new SearchItemGroup(group.Key, group.Cache))
.Bind(out _groups)

MODIFY
WalletWasabi.Fluent/ViewModels/SearchBar/SearchItems/ActionableItem.cs
WalletWasabi.Fluent/ViewModels/SearchBar/SearchItems/ActionableItem.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using System.Windows.Input;
+using ReactiveUI;
using WalletWasabi.Fluent.ViewModels.SearchBar.Patterns;
namespace WalletWasabi.Fluent.ViewModels.SearchBar.SearchItems;
@@ -14,10 +16,11 @@ public class ActionableItem : IActionableItem
OnExecution = onExecution;
Category = category;
Keywords = keywords ?? Enumerable.Empty<string>();
+ Command = ReactiveCommand.CreateFromTask(onExecution);
}
+ public ICommand Command { get; set; }
public Func<Task> OnExecution { get; }
-
public string Name { get; }
public string Description { get; }
public ComposedKey Key => new(Name);

DELETE
WalletWasabi.Fluent/ViewModels/SearchBar/SearchItems/AutocloseActionableItem.cs
-using System.Collections.Generic;
-using System.Reactive;
-using System.Threading.Tasks;
-using ReactiveUI;
-using WalletWasabi.Fluent.ViewModels.SearchBar.Patterns;
-
-namespace WalletWasabi.Fluent.ViewModels.SearchBar.SearchItems;
-
-public class AutocloseActionableItem : IActionableItem
-{
- private readonly IActionableItem _item;
-
- public AutocloseActionableItem(IActionableItem item, Action collapseParent)
- {
- _item = item;
- Command = ReactiveCommand.CreateFromTask(async () =>
- {
- collapseParent();
- await item.OnExecution();
- });
- }
-
- public ReactiveCommand<Unit, Unit> Command { get; set; }
- public Func<Task> OnExecution => _item.OnExecution;
-
- public string Name => _item.Name;
-
- public string Description => _item.Description;
-
- public ComposedKey Key => _item.Key;
-
- public string? Icon
- {
- get => _item.Icon;
- set => _item.Icon = value;
- }
-
- public string Category => _item.Category;
-
- public IEnumerable<string> Keywords => _item.Keywords;
- public bool IsDefault => _item.IsDefault;
-}
\ No newline at end of file

MODIFY
WalletWasabi.Fluent/Views/SearchBar/SearchBar.axaml.cs
WalletWasabi.Fluent/Views/SearchBar/SearchBar.axaml.cs
-using System.Reactive.Disposables;
-using System.Reactive.Linq;
-using Avalonia;
using Avalonia.Controls;
-using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
-using ReactiveUI;
-using WalletWasabi.Fluent.ViewModels.SearchBar;
namespace WalletWasabi.Fluent.Views.SearchBar;
public class SearchBar : UserControl
{
- private readonly CompositeDisposable _disposables = new();
-
public SearchBar()
{
InitializeComponent();
}
- protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
- {
- MessageBus.Current
- .Listen<CloseSearchBarMessage>()
- .Do(_ => FocusMainWindow())
- .Subscribe()
- .DisposeWith(_disposables);
- }
-
- protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
- {
- _disposables.Dispose();
- }
-
- private static void FocusMainWindow()
- {
- if (Application.Current is { ApplicationLifetime: IClassicDesktopStyleApplicationLifetime applicationLifetime })
- {
- applicationLifetime.MainWindow.Focus();
- }
- }
-
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);

MODIFY
WalletWasabi.Fluent/Views/SearchBar/SearchBarDropdown.axaml
WalletWasabi.Fluent/Views/SearchBar/SearchBarDropdown.axaml
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="450"
x:Class="WalletWasabi.Fluent.Views.SearchBar.SearchBarDropdown"
x:CompileBindings="True"
xmlns:conv="clr-namespace:WalletWasabi.Fluent.Converters"
xmlns:sb="clr-namespace:WalletWasabi.Fluent.ViewModels.SearchBar"
xmlns:settings="clr-namespace:WalletWasabi.Fluent.ViewModels.SearchBar.Settings"
- xmlns:searchItems="clr-namespace:WalletWasabi.Fluent.ViewModels.SearchBar.SearchItems">
+ xmlns:searchItems="clr-namespace:WalletWasabi.Fluent.ViewModels.SearchBar.SearchItems"
+ xmlns:helpers="clr-namespace:WalletWasabi.Fluent.Helpers">
<Design.DataContext>
<sb:SearchBarDesignViewModel />
</Design.DataContext>
</DockPanel>
</DataTemplate>
- <DataTemplate DataType="searchItems:AutocloseActionableItem">
+ <DataTemplate DataType="searchItems:ActionableItem">
- <Button Command="{Binding Command}" Classes="searchItem" Background="Transparent"
+ <Button Command="{Binding Command}" ClickMode="Press" Classes="searchItem" Background="Transparent"
Foreground="{DynamicResource AcrylicTrimForeground}" HorizontalAlignment="Stretch" Padding="0" Cursor="Hand">
<DockPanel Background="Transparent" Margin="10">
TextTrimming="CharacterEllipsis" />
</DockPanel>
+ <i:Interaction.Behaviors>
+ <EventTriggerBehavior EventName="Click">
+ <CallMethodAction MethodName="Focus" TargetObject="{x:Static helpers:ApplicationHelper.MainWindow}" />
+ </EventTriggerBehavior>
+ </i:Interaction.Behaviors>
+
</Button>
</DataTemplate>

Add alternate way to close flyout