Files
ClaudeDo/src/ClaudeDo.Ui/Views/Islands/NotesEditorView.axaml
T
CubeGameLPandClaude Opus 5 f640580463 fix(notes): Shift+Enter in the capture box, not just in the note rows
The previous fix put AcceptsReturn on the rows in the DataTemplate and
missed the box you actually type new notes into, which still had it off
and only a KeyBinding for Enter — so Shift+Enter there did nothing.

Both now go through the same tunnel handler: Enter files the note,
Shift+Enter is left to the TextBox for the line break. The KeyBinding is
gone; with AcceptsReturn on it could never have fired anyway, because
TextBox consumes Enter in its own OnKeyDown before bindings or bubbling
handlers run.

Verified against the running app: a note typed with Shift+Enter is
stored as "fe\r\ndwa".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 21:46:59 +02:00

114 lines
5.5 KiB
XML

<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:ClaudeDo.Ui.ViewModels.Islands"
xmlns:loc="using:ClaudeDo.Ui.Localization"
x:Class="ClaudeDo.Ui.Views.Islands.NotesEditorView"
x:DataType="vm:NotesEditorViewModel">
<UserControl.Styles>
<!-- A note reads as text, not as a form field: the box only shows itself under the pointer
and while it has focus. -->
<Style Selector="TextBox.note">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="4,3"/>
<Setter Property="MinHeight" Value="0"/>
</Style>
<Style Selector="TextBox.note /template/ Border#PART_BorderElement">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
<Style Selector="Border.note-row">
<Setter Property="CornerRadius" Value="6"/>
<Setter Property="Padding" Value="10,1,6,1"/>
<Setter Property="Margin" Value="4,1"/>
</Style>
<Style Selector="Border.note-row:pointerover">
<Setter Property="Background" Value="{DynamicResource PeatSoftBrush}"/>
</Style>
<!-- Row actions stay out of the way until the row is hovered. -->
<Style Selector="Border.note-row Button.note-del">
<Setter Property="Opacity" Value="0"/>
</Style>
<Style Selector="Border.note-row:pointerover Button.note-del">
<Setter Property="Opacity" Value="1"/>
</Style>
</UserControl.Styles>
<DockPanel LastChildFill="True">
<!-- Today's capture box: Enter files the note and leaves the caret here for the next one. -->
<Border DockPanel.Dock="Top" Classes="add-task" Margin="16,14,16,10">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Classes="add-task-plus" VerticalAlignment="Center">
<PathIcon Width="12" Height="12" Data="{StaticResource Icon.Plus}"
Foreground="{DynamicResource TextFaintBrush}"/>
</Border>
<!-- Enter/Shift+Enter are handled in the code-behind's tunnel handler, same as the note
rows: a KeyBinding would never fire, because AcceptsReturn makes TextBox consume
Enter first. -->
<TextBox Grid.Column="1" x:Name="NewNoteBox" Classes="add-task-input"
PlaceholderText="{loc:Tr notes.newNotePlaceholder}"
Text="{Binding NewBulletText, Mode=TwoWay}"
AcceptsReturn="True" TextWrapping="Wrap"
VerticalAlignment="Center" Margin="12,0,0,0"/>
<Border Grid.Column="2" Classes="kbd kbd-enter" VerticalAlignment="Center"
IsVisible="{Binding #NewNoteBox.IsFocused}">
<TextBlock Text="{loc:Tr tasks.enterKey}"/>
</Border>
</Grid>
</Border>
<Panel>
<ScrollViewer>
<ItemsControl x:Name="RowsHost" ItemsSource="{Binding Rows}" Margin="10,0,10,12">
<ItemsControl.DataTemplates>
<DataTemplate DataType="vm:NoteDayHeaderViewModel">
<TextBlock Classes="eyebrow section-label" Margin="14,12,14,4" Text="{Binding Label}"/>
</DataTemplate>
<DataTemplate DataType="vm:NoteBulletViewModel">
<Border Classes="note-row">
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Ellipse Grid.Column="0" Width="4" Height="4" Margin="0,0,10,0"
VerticalAlignment="Center"
Fill="{DynamicResource TextFaintBrush}"/>
<!-- AcceptsReturn/TextWrapping are set here, not in the style above: TextBox
reads AcceptsReturn in its own OnKeyDown, which runs before any handler a
style or the XAML could attach. Enter is intercepted in the tunnel phase
(see code-behind) so the split still wins over the newline. -->
<TextBox Grid.Column="1" Classes="note" Text="{Binding Text, Mode=TwoWay}"
AcceptsReturn="True" TextWrapping="Wrap"
LostFocus="OnBulletLostFocus"/>
<PathIcon Grid.Column="2" Width="12" Height="12" Margin="6,0"
VerticalAlignment="Center"
IsVisible="{Binding FromAgent}"
ToolTip.Tip="{loc:Tr notes.fromAgentTip}"
Data="{StaticResource Icon.AgentSuggested}"
Foreground="{DynamicResource TextFaintBrush}"/>
<Button Grid.Column="3" Classes="icon-btn note-del"
VerticalAlignment="Center"
ToolTip.Tip="{loc:Tr notes.deleteTip}"
Click="OnDeleteBulletClick">
<PathIcon Classes="danger" Data="{StaticResource Icon.Trash}" Width="12" Height="12"/>
</Button>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.DataTemplates>
</ItemsControl>
</ScrollViewer>
<TextBlock IsVisible="{Binding IsEmpty}"
Text="{loc:Tr notes.emptyHint}"
Foreground="{DynamicResource TextMuteBrush}"
MaxWidth="260" TextAlignment="Center" TextWrapping="Wrap"
HorizontalAlignment="Center" VerticalAlignment="Center"
IsHitTestVisible="False"/>
</Panel>
</DockPanel>
</UserControl>