diff --git a/src/DodoSSH.Client.App/App.axaml b/src/DodoSSH.Client.App/App.axaml index f906eb0..c36b9fc 100644 --- a/src/DodoSSH.Client.App/App.axaml +++ b/src/DodoSSH.Client.App/App.axaml @@ -1261,6 +1261,57 @@ + + + + + + + + + diff --git a/src/DodoSSH.Client.App/Views/ImportScreen.axaml b/src/DodoSSH.Client.App/Views/ImportScreen.axaml index daff5e7..6c0c2d1 100644 --- a/src/DodoSSH.Client.App/Views/ImportScreen.axaml +++ b/src/DodoSSH.Client.App/Views/ImportScreen.axaml @@ -12,9 +12,10 @@ forty entries for machines that stopped existing years ago. So scanning writes nothing and the list says what each entry means; importing is a separate press on a set somebody has looked at. - Reachable from the preferences screen and not from the nav rail. It is a task rather than a - destination — done once, or once a year — and a seventh rail entry would cost every screen a slot for - something almost nobody is looking at. + v5c-3: restyled into Import.dc.html's own table over SettingsView's content column — SettingsNav stays + lit on Preferences while this is up, and the titlebar says "Back to preferences"; see + MainWindowViewModel.IsImportOpen. No longer reachable from the nav rail, exactly as before: it is a task + done once or once a year, reached from the Preferences page's own "OPEN IMPORTER" row. ── ◆ THE ONE TICK THAT READS PRIVATE KEYS ───────────────────────────────────────────────────────────── Below the list, off, and drawn only where the scan actually found an IdentityFile. It is the only control @@ -26,144 +27,212 @@ What comes back afterwards is the report under the list: one line per key file, saying which were stored, which are protected by a passphrase this cannot know, and which were not there at all. That is reported rather than previewed for the same reason — previewing would mean reading them. + + ── ◆ WHAT THIS MEANS ────────────────────────────────────────────────────────────────────────────────── + One chip per row rather than the old separate AUTHENTICATION/STATE columns, mapped off the two facts a + row actually carries: ImportRowViewModel.AlreadyPresent and HasWarnings. A skipped Host pattern (a + wildcard block) never becomes a row at all — see SshConfigImport.SkippedPatterns — so there is no third, + "skipped" state to draw here; a warned row is the amber case instead, and it wins over "already here" + because the warning is the more actionable of the two facts. See ImportRowViewModel.Meaning. --> - + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/DodoSSH.Client.App/Views/SettingsGroupsPage.axaml.cs b/src/DodoSSH.Client.App/Views/SettingsGroupsPage.axaml.cs new file mode 100644 index 0000000..28edd4c --- /dev/null +++ b/src/DodoSSH.Client.App/Views/SettingsGroupsPage.axaml.cs @@ -0,0 +1,9 @@ +using Avalonia.Controls; + +namespace DodoSSH.Client.App.Views; + +/// Groups: every group, and the hosts filed under each — see the remark at the top of the markup. +internal sealed partial class SettingsGroupsPage : UserControl +{ + public SettingsGroupsPage() => InitializeComponent(); +} diff --git a/src/DodoSSH.Client.App/Views/SettingsNav.axaml b/src/DodoSSH.Client.App/Views/SettingsNav.axaml new file mode 100644 index 0000000..4613531 --- /dev/null +++ b/src/DodoSSH.Client.App/Views/SettingsNav.axaml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/DodoSSH.Client.App/Views/SettingsNav.axaml.cs b/src/DodoSSH.Client.App/Views/SettingsNav.axaml.cs new file mode 100644 index 0000000..e5112cb --- /dev/null +++ b/src/DodoSSH.Client.App/Views/SettingsNav.axaml.cs @@ -0,0 +1,9 @@ +using Avalonia.Controls; + +namespace DodoSSH.Client.App.Views; + +/// Settings mode's own 340px rail — General/Vaults/Account, Security/Preferences, and Logout. +internal sealed partial class SettingsNav : UserControl +{ + public SettingsNav() => InitializeComponent(); +} diff --git a/src/DodoSSH.Client.App/Views/SettingsPreferencesPage.axaml b/src/DodoSSH.Client.App/Views/SettingsPreferencesPage.axaml new file mode 100644 index 0000000..4812d36 --- /dev/null +++ b/src/DodoSSH.Client.App/Views/SettingsPreferencesPage.axaml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/DodoSSH.Client.App/Views/SettingsSecurityPage.axaml.cs b/src/DodoSSH.Client.App/Views/SettingsSecurityPage.axaml.cs new file mode 100644 index 0000000..c1b9af3 --- /dev/null +++ b/src/DodoSSH.Client.App/Views/SettingsSecurityPage.axaml.cs @@ -0,0 +1,9 @@ +using Avalonia.Controls; + +namespace DodoSSH.Client.App.Views; + +/// Settings mode's Security page: the E2E explainer, Windows Hello, and approved host keys. +internal sealed partial class SettingsSecurityPage : UserControl +{ + public SettingsSecurityPage() => InitializeComponent(); +} diff --git a/src/DodoSSH.Client.App/Views/SettingsTagsPage.axaml b/src/DodoSSH.Client.App/Views/SettingsTagsPage.axaml new file mode 100644 index 0000000..eb94b91 --- /dev/null +++ b/src/DodoSSH.Client.App/Views/SettingsTagsPage.axaml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/DodoSSH.Client.App/Views/SettingsTagsPage.axaml.cs b/src/DodoSSH.Client.App/Views/SettingsTagsPage.axaml.cs new file mode 100644 index 0000000..9605def --- /dev/null +++ b/src/DodoSSH.Client.App/Views/SettingsTagsPage.axaml.cs @@ -0,0 +1,9 @@ +using Avalonia.Controls; + +namespace DodoSSH.Client.App.Views; + +/// Tags: every tag, and how many hosts wear each — see the remark at the top of the markup. +internal sealed partial class SettingsTagsPage : UserControl +{ + public SettingsTagsPage() => InitializeComponent(); +} diff --git a/src/DodoSSH.Client.App/Views/SettingsTitleBar.axaml b/src/DodoSSH.Client.App/Views/SettingsTitleBar.axaml new file mode 100644 index 0000000..b1e151a --- /dev/null +++ b/src/DodoSSH.Client.App/Views/SettingsTitleBar.axaml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/DodoSSH.Client.App/Views/SettingsTitleBar.axaml.cs b/src/DodoSSH.Client.App/Views/SettingsTitleBar.axaml.cs new file mode 100644 index 0000000..d48ec3e --- /dev/null +++ b/src/DodoSSH.Client.App/Views/SettingsTitleBar.axaml.cs @@ -0,0 +1,47 @@ +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Interactivity; + +namespace DodoSSH.Client.App.Views; + +/// Settings mode's own titlebar — see the remark in the markup for why it is not TitleBar itself. +internal sealed partial class SettingsTitleBar : UserControl +{ + public SettingsTitleBar() => InitializeComponent(); + + private Window? Host => TopLevel.GetTopLevel(this) as Window; + + /// Left button only, and only on a press nothing inside the bar has already handled. + private void OnDrag(object? sender, PointerPressedEventArgs e) + { + if (e.Handled || !e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) + { + return; + } + + Host?.BeginMoveDrag(e); + } + + private void OnMinimise(object? sender, RoutedEventArgs e) + { + if (Host is { } window) + { + window.WindowState = WindowState.Minimized; + } + } + + /// Both the button and a double-click on the bar arrive here, as Windows convention expects. + private void OnToggleMaximised(object? sender, RoutedEventArgs e) + { + if (Host is not { } window) + { + return; + } + + window.WindowState = window.WindowState == WindowState.Maximized + ? WindowState.Normal + : WindowState.Maximized; + } + + private void OnClose(object? sender, RoutedEventArgs e) => Host?.Close(); +} diff --git a/src/DodoSSH.Client.App/Views/SettingsVaultsPage.axaml b/src/DodoSSH.Client.App/Views/SettingsVaultsPage.axaml new file mode 100644 index 0000000..a9b87f2 --- /dev/null +++ b/src/DodoSSH.Client.App/Views/SettingsVaultsPage.axaml @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +