CommandPalette WIP
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FileTime.App.CommandPalette.Abstractions\FileTime.App.CommandPalette.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\FileTime.App.Core.Abstraction\FileTime.App.Core.Abstraction.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Reactive" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace FileTime.App.CommandPalette.Models;
|
||||
|
||||
public class CommandPaletteEntry : ICommandPaletteEntry
|
||||
{
|
||||
public string Identifier { get; }
|
||||
public string Title { get; }
|
||||
|
||||
public CommandPaletteEntry(string identifier, string title)
|
||||
{
|
||||
Identifier = identifier;
|
||||
Title = title;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using FileTime.App.CommandPalette.Models;
|
||||
using FileTime.App.CommandPalette.ViewModels;
|
||||
using FileTime.App.Core.Services;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
|
||||
namespace FileTime.App.CommandPalette.Services;
|
||||
|
||||
public partial class CommandPaletteService : ICommandPaletteService
|
||||
{
|
||||
private readonly IModalService _modalService;
|
||||
private readonly IIdentifiableUserCommandService _identifiableUserCommandService;
|
||||
private readonly BehaviorSubject<bool> _showWindow = new(false);
|
||||
IObservable<bool> ICommandPaletteService.ShowWindow => _showWindow.AsObservable();
|
||||
[Notify] ICommandPaletteViewModel? _currentModal;
|
||||
|
||||
public CommandPaletteService(
|
||||
IModalService modalService,
|
||||
IIdentifiableUserCommandService identifiableUserCommandService)
|
||||
{
|
||||
_modalService = modalService;
|
||||
_identifiableUserCommandService = identifiableUserCommandService;
|
||||
}
|
||||
public void OpenCommandPalette()
|
||||
{
|
||||
_showWindow.OnNext(true);
|
||||
CurrentModal = _modalService.OpenModal<ICommandPaletteViewModel>();
|
||||
}
|
||||
|
||||
public IReadOnlyList<ICommandPaletteEntry> GetCommands() =>
|
||||
_identifiableUserCommandService
|
||||
.GetCommandIdentifiers()
|
||||
.Select(c => new CommandPaletteEntry(c, c))
|
||||
.ToList()
|
||||
.AsReadOnly();
|
||||
}
|
||||
16
src/AppCommon/FileTime.App.CommandPalette/Startup.cs
Normal file
16
src/AppCommon/FileTime.App.CommandPalette/Startup.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using FileTime.App.CommandPalette.Services;
|
||||
using FileTime.App.CommandPalette.ViewModels;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace FileTime.App.CommandPalette;
|
||||
|
||||
public static class Startup
|
||||
{
|
||||
public static IServiceCollection AddCommandPalette(this IServiceCollection services)
|
||||
{
|
||||
services.TryAddTransient<ICommandPaletteViewModel, CommandPaletteViewModel>();
|
||||
services.TryAddSingleton<ICommandPaletteService, CommandPaletteService>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using MvvmGen;
|
||||
|
||||
namespace FileTime.App.CommandPalette.ViewModels;
|
||||
|
||||
[ViewModel]
|
||||
public partial class CommandPaletteEntryViewModel : ICommandPaletteEntryViewModel
|
||||
{
|
||||
[Property] private string _identifier;
|
||||
[Property] private string _title;
|
||||
|
||||
public CommandPaletteEntryViewModel(string identifier, string title)
|
||||
{
|
||||
_identifier = identifier;
|
||||
_title = title;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using Avalonia.Input;
|
||||
using FileTime.App.CommandPalette.Services;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using MvvmGen;
|
||||
|
||||
namespace FileTime.App.CommandPalette.ViewModels;
|
||||
|
||||
[ViewModel]
|
||||
[Inject(typeof(ICommandPaletteService), "_commandPaletteService")]
|
||||
public partial class CommandPaletteViewModel : ICommandPaletteViewModel
|
||||
{
|
||||
private string _searchText;
|
||||
|
||||
[Property] private IObservable<bool> _showWindow;
|
||||
[Property] private List<ICommandPaletteEntryViewModel> _filteredMatches;
|
||||
[Property] private ICommandPaletteEntryViewModel? _selectedItem;
|
||||
string IModalViewModel.Name => "CommandPalette";
|
||||
|
||||
public string SearchText
|
||||
{
|
||||
get => _searchText;
|
||||
set
|
||||
{
|
||||
if (_searchText == value) return;
|
||||
|
||||
_searchText = value;
|
||||
OnPropertyChanged();
|
||||
|
||||
UpdateFilteredMatches();
|
||||
}
|
||||
}
|
||||
|
||||
public void Close() => throw new NotImplementedException();
|
||||
|
||||
public void HandleKeyDown(KeyEventArgs keyEventArgs) => throw new NotImplementedException();
|
||||
|
||||
partial void OnInitialize()
|
||||
{
|
||||
ShowWindow = _commandPaletteService.ShowWindow;
|
||||
UpdateFilteredMatches();
|
||||
}
|
||||
|
||||
private void UpdateFilteredMatches()
|
||||
{
|
||||
FilteredMatches = _commandPaletteService
|
||||
.GetCommands()
|
||||
.Select(c =>
|
||||
(ICommandPaletteEntryViewModel) new CommandPaletteEntryViewModel(c.Identifier, c.Title))
|
||||
.Take(30) // TODO remove magic number
|
||||
.OrderBy(c => c.Title)
|
||||
.ToList();
|
||||
|
||||
if (SelectedItem != null && FilteredMatches.Contains(SelectedItem)) return;
|
||||
|
||||
SelectedItem = FilteredMatches.Count > 0
|
||||
? FilteredMatches[0]
|
||||
: null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user