feat(ui): keyboard shortcuts (/ Ctrl+N Space Esc)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,8 @@ public sealed partial class ListsIslandViewModel : ViewModelBase
|
||||
private readonly IDbContextFactory<ClaudeDoDbContext> _dbFactory;
|
||||
|
||||
public event EventHandler? SelectionChanged;
|
||||
public event EventHandler? FocusSearchRequested;
|
||||
public void RequestFocusSearch() => FocusSearchRequested?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
public ObservableCollection<ListNavItemViewModel> Items { get; } = new();
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ public sealed partial class TasksIslandViewModel : ViewModelBase
|
||||
private ListNavItemViewModel? _currentList;
|
||||
|
||||
public event EventHandler? SelectionChanged;
|
||||
public event EventHandler? FocusAddTaskRequested;
|
||||
public void RequestFocusAddTask() => FocusAddTaskRequested?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
public ObservableCollection<TaskRowViewModel> Items { get; } = new();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using ClaudeDo.Ui.ViewModels.Islands;
|
||||
|
||||
namespace ClaudeDo.Ui.ViewModels;
|
||||
@@ -15,6 +16,18 @@ public sealed partial class IslandsShellViewModel : ViewModelBase
|
||||
public bool ShowDetails => WindowWidth >= 1100;
|
||||
public bool ShowLists => WindowWidth >= 780;
|
||||
|
||||
[RelayCommand]
|
||||
private void FocusSearch() => Lists.RequestFocusSearch();
|
||||
|
||||
[RelayCommand]
|
||||
private void FocusAddTask() => Tasks.RequestFocusAddTask();
|
||||
|
||||
public async Task ToggleSelectedDoneAsync()
|
||||
{
|
||||
if (Tasks.SelectedTask is { } row)
|
||||
await Tasks.ToggleDoneCommand.ExecuteAsync(row);
|
||||
}
|
||||
|
||||
partial void OnWindowWidthChanged(double value)
|
||||
{
|
||||
OnPropertyChanged(nameof(ShowDetails));
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<TextBlock FontFamily="{DynamicResource SansFamily}" FontSize="18"
|
||||
FontWeight="SemiBold" Foreground="{DynamicResource TextBrush}"
|
||||
Text="Lists"/>
|
||||
<TextBox Classes="search" Margin="0,8,0,0" PlaceholderText="Search…"
|
||||
<TextBox x:Name="SearchBox" Classes="search" Margin="0,8,0,0" PlaceholderText="Search…"
|
||||
Text="{Binding SearchText, Mode=TwoWay}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
@@ -6,7 +6,15 @@ namespace ClaudeDo.Ui.Views.Islands;
|
||||
|
||||
public partial class ListsIslandView : UserControl
|
||||
{
|
||||
public ListsIslandView() { InitializeComponent(); }
|
||||
public ListsIslandView()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContextChanged += (_, _) =>
|
||||
{
|
||||
if (DataContext is ListsIslandViewModel vm)
|
||||
vm.FocusSearchRequested += (_, _) => SearchBox.Focus();
|
||||
};
|
||||
}
|
||||
|
||||
private void OnItemTapped(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<!-- Add-task row -->
|
||||
<Border DockPanel.Dock="Top" Margin="18,8,18,4">
|
||||
<TextBox Watermark="Add a task…" Text="{Binding NewTaskTitle, Mode=TwoWay}">
|
||||
<TextBox x:Name="AddTaskBox" Watermark="Add a task…" Text="{Binding NewTaskTitle, Mode=TwoWay}">
|
||||
<TextBox.KeyBindings>
|
||||
<KeyBinding Gesture="Enter" Command="{Binding AddCommand}"/>
|
||||
</TextBox.KeyBindings>
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
using Avalonia.Controls;
|
||||
using ClaudeDo.Ui.ViewModels.Islands;
|
||||
|
||||
namespace ClaudeDo.Ui.Views.Islands;
|
||||
|
||||
public partial class TasksIslandView : UserControl
|
||||
{
|
||||
public TasksIslandView() { InitializeComponent(); }
|
||||
public TasksIslandView()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContextChanged += (_, _) =>
|
||||
{
|
||||
if (DataContext is TasksIslandViewModel vm)
|
||||
vm.FocusAddTaskRequested += (_, _) => AddTaskBox.Focus();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
SystemDecorations="None"
|
||||
ExtendClientAreaToDecorationsHint="True"
|
||||
ExtendClientAreaTitleBarHeightHint="-1">
|
||||
<Window.KeyBindings>
|
||||
<KeyBinding Gesture="OemQuestion" Command="{Binding FocusSearchCommand}"/>
|
||||
<KeyBinding Gesture="Shift+OemQuestion" Command="{Binding FocusSearchCommand}"/>
|
||||
<KeyBinding Gesture="Ctrl+N" Command="{Binding FocusAddTaskCommand}"/>
|
||||
</Window.KeyBindings>
|
||||
<Grid RowDefinitions="36,*">
|
||||
<!-- Custom title bar -->
|
||||
<Border Grid.Row="0" Background="{DynamicResource DeepBrush}" PointerPressed="OnTitleBarPressed">
|
||||
|
||||
@@ -6,7 +6,22 @@ namespace ClaudeDo.Ui.Views;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow() { InitializeComponent(); }
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
KeyDown += OnWindowKeyDown;
|
||||
}
|
||||
|
||||
private void OnWindowKeyDown(object? sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Space
|
||||
&& FocusManager?.GetFocusedElement() is not TextBox
|
||||
&& DataContext is IslandsShellViewModel vm)
|
||||
{
|
||||
e.Handled = true;
|
||||
_ = vm.ToggleSelectedDoneAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTitleBarPressed(object? sender, PointerPressedEventArgs e)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user