From 94d5718cfe12efac3a4682d3f8ca7316086b424a Mon Sep 17 00:00:00 2001 From: Stuart Meeks Date: Sat, 30 May 2026 04:58:42 +0000 Subject: [PATCH 1/3] Add CLI delete with must-be-empty semantics A CLI can now be deleted from its view via a "Delete CLI" action. The rule is must-be-empty: if the CLI still has visible (non-trashed) snips the delete is refused with an explanatory notice. Once empty it deletes after confirmation, cleaning up the CLI's icon asset and removing any leftover trashed snips (which would otherwise be orphaned). Adds IShellInteractions.NotifyAsync (single-button notice) for the "can't delete" message, implemented as a ContentDialog in the App head. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 4 + .../Services/WindowsShellInteractions.cs | 13 +++ src/Snipdeck.App/Views/ShellPage.xaml | 5 + src/Snipdeck.App/Views/ShellPage.xaml.cs | 8 ++ .../Abstractions/IShellInteractions.cs | 5 + .../ViewModels/ShellViewModel.cs | 46 +++++++++ .../Support/FakeIconAssetStorage.cs | 3 + .../Support/FakeShellInteractions.cs | 14 +++ .../ViewModels/ShellViewModelCommandsTests.cs | 93 +++++++++++++++++++ 9 files changed, 191 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c225e20..57345c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Configurable backup retention.** Choose how many timestamped store backups to keep (default 20) from Settings → "Backups to keep". The count is honoured on the next write-triggered backup, with no restart required. +- **Delete a CLI.** A "Delete CLI" action on the CLI view removes an empty CLI + after confirmation. Deletion uses must-be-empty semantics: a CLI with visible + (non-trashed) snips can't be deleted until those snips are removed. The CLI's + icon asset and any leftover trashed snips are cleaned up with it. ## [0.1.0-alpha.1] - 2026-05-30 diff --git a/src/Snipdeck.App/Services/WindowsShellInteractions.cs b/src/Snipdeck.App/Services/WindowsShellInteractions.cs index da9d4ce..f9c7ece 100644 --- a/src/Snipdeck.App/Services/WindowsShellInteractions.cs +++ b/src/Snipdeck.App/Services/WindowsShellInteractions.cs @@ -47,6 +47,19 @@ public async Task ConfirmAsync(string title, string message, string confir return result == ContentDialogResult.Primary; } + public async Task NotifyAsync(string title, string message, string buttonText = "OK") + { + var dialog = new ContentDialog + { + Title = title, + Content = message, + CloseButtonText = buttonText, + DefaultButton = ContentDialogButton.Close, + XamlRoot = GetXamlRoot(), + }; + _ = await dialog.ShowAsync(); + } + public async Task EditSnipAsync(Snip snip, IReadOnlyList availableClis) { ArgumentNullException.ThrowIfNull(snip); diff --git a/src/Snipdeck.App/Views/ShellPage.xaml b/src/Snipdeck.App/Views/ShellPage.xaml index b797d94..196ece1 100644 --- a/src/Snipdeck.App/Views/ShellPage.xaml +++ b/src/Snipdeck.App/Views/ShellPage.xaml @@ -96,6 +96,7 @@ +