diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6dce3d64..dbc87aff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,7 +82,7 @@ jobs: publish: runs-on: ubuntu-latest needs: build - if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true') + if: github.event_name == 'release' || github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true') timeout-minutes: 15 permissions: id-token: write diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 34f7b387..a971ef43 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -322,7 +322,7 @@ jobs: prompt-file: /tmp/prompts/prompt-1.txt - name: Save pass 1 response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_pass1.conclusion == 'success' run: | cp "${{ steps.ai_pass1.outputs.response-file }}" /tmp/pass-1.txt sleep 65 @@ -338,7 +338,7 @@ jobs: prompt-file: /tmp/prompts/prompt-2.txt - name: Save pass 2 response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_pass2.conclusion == 'success' run: | cp "${{ steps.ai_pass2.outputs.response-file }}" /tmp/pass-2.txt sleep 65 @@ -354,7 +354,7 @@ jobs: prompt-file: /tmp/prompts/prompt-3.txt - name: Save pass 3 response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_pass3.conclusion == 'success' run: | cp "${{ steps.ai_pass3.outputs.response-file }}" /tmp/pass-3.txt sleep 65 @@ -370,7 +370,7 @@ jobs: prompt-file: /tmp/prompts/prompt-4.txt - name: Save pass 4 response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_pass4.conclusion == 'success' run: | cp "${{ steps.ai_pass4.outputs.response-file }}" /tmp/pass-4.txt sleep 65 @@ -386,7 +386,7 @@ jobs: prompt-file: /tmp/prompts/prompt-5.txt - name: Save pass 5 response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_pass5.conclusion == 'success' run: | cp "${{ steps.ai_pass5.outputs.response-file }}" /tmp/pass-5.txt sleep 65 @@ -402,7 +402,7 @@ jobs: prompt-file: /tmp/prompts/prompt-6.txt - name: Save pass 6 response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_pass6.conclusion == 'success' run: | cp "${{ steps.ai_pass6.outputs.response-file }}" /tmp/pass-6.txt sleep 65 @@ -446,7 +446,7 @@ jobs: prompt-file: /tmp/prompt-merge-a.txt - name: Save merge-A response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_merge_a.conclusion == 'success' run: | cp "${{ steps.ai_merge_a.outputs.response-file }}" /tmp/merge-a.txt sleep 65 @@ -479,7 +479,7 @@ jobs: prompt-file: /tmp/prompt-compress-a.txt - name: Save compress-A response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_compress_a.conclusion == 'success' run: | cp "${{ steps.ai_compress_a.outputs.response-file }}" /tmp/compress-a.txt sleep 65 @@ -523,7 +523,7 @@ jobs: prompt-file: /tmp/prompt-merge-b.txt - name: Save merge-B response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_merge_b.conclusion == 'success' run: | cp "${{ steps.ai_merge_b.outputs.response-file }}" /tmp/merge-b.txt sleep 65 @@ -556,7 +556,7 @@ jobs: prompt-file: /tmp/prompt-compress-b.txt - name: Save compress-B response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_compress_b.conclusion == 'success' run: | cp "${{ steps.ai_compress_b.outputs.response-file }}" /tmp/compress-b.txt sleep 65 @@ -641,7 +641,7 @@ jobs: prompt-file: /tmp/prompt-final.txt - name: Save final merge response - if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' + if: steps.tag_check.outputs.exists == 'false' && github.event.inputs.skip_ai_notes != 'true' && steps.ai_merge.conclusion == 'success' run: cp "${{ steps.ai_merge.outputs.response-file }}" /tmp/final-merge.txt - name: Write release notes to file if: steps.tag_check.outputs.exists == 'false' diff --git a/build/Package.props b/build/Package.props index d521d115..a1c7caa8 100644 --- a/build/Package.props +++ b/build/Package.props @@ -4,7 +4,7 @@ enable enable default - 5.1.3-alpha2 + 5.1.3-alpha2-fix Dmitry Zhutkov (Onebeld), Andrey Savich (pieckenst) Dmitry Zhutkov (Onebeld) theme, design, xaml, library, ui, gui, control, csharp, styled-components, interface, dotnet, nuget, style, avalonia, controls, user-interface, styles, avaloniaui, pleasant, graphical-user-interface diff --git a/samples/PleasantUI.Example/MainView.axaml.cs b/samples/PleasantUI.Example/MainView.axaml.cs index 8e9e0ef1..551e4766 100644 --- a/samples/PleasantUI.Example/MainView.axaml.cs +++ b/samples/PleasantUI.Example/MainView.axaml.cs @@ -83,6 +83,10 @@ private void OnNavigationSelectionChanged(object? sender, SelectionChangedEventA // stays visible, without going through SelectionChanged again. MainNavigationView.SelectionChanged -= OnNavigationSelectionChanged; MainNavigationView.SelectedItem = HomeNavItem; + // HomeNavItem must not appear highlighted while a leaf page is active. + HomeNavItem.IsSelected = false; + // Re-highlight the leaf item — SelectSingleItemCore cleared it when we redirected to HomeNavItem. + selected.IsSelected = true; MainNavigationView.SelectionChanged += OnNavigationSelectionChanged; } diff --git a/src/PleasantUI/Controls/NavigationView/NavigationView.cs b/src/PleasantUI/Controls/NavigationView/NavigationView.cs index f533188d..1a606f06 100644 --- a/src/PleasantUI/Controls/NavigationView/NavigationView.cs +++ b/src/PleasantUI/Controls/NavigationView/NavigationView.cs @@ -1,4 +1,5 @@ -using System.Runtime.InteropServices; +using System.Diagnostics; +using System.Runtime.InteropServices; using System.Windows.Input; using Avalonia; using Avalonia.Animation; @@ -52,6 +53,10 @@ public class NavigationView : TreeView private ILogical? _logicalSelectedContent; + // Stores the IsExpanded state of group items before the pane collapses to compact mode, + // keyed by the NavigationViewItem instance so each item's state is tracked independently. + private readonly Dictionary _expandedStates = new(); + /// /// Defines the property. /// @@ -380,6 +385,7 @@ static NavigationView() { SelectionModeProperty.OverrideDefaultValue(SelectionMode.Single); SelectedItemProperty.Changed.AddClassHandler((x, _) => x.OnSelectedItemChanged()); + IsOpenProperty.Changed.AddClassHandler((x, e) => x.OnIsOpenChanged(e)); } /// @@ -397,18 +403,20 @@ public NavigationView() /// protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { + Debug.WriteLine("[NavigationView] OnApplyTemplate"); base.OnApplyTemplate(e); _stackPanelButtons = e.NameScope.Find("PART_StackPanelButtons"); _headerItem = e.NameScope.Find