Public Access
Give hosts and terminals their own screen, and the rest of the vault another
Rebuilds the client's shell from an imported design: a titlebar and nav rail it draws itself, real multi-session tabs over the one WebView, a Ctrl+K host search, and a vault screen that merges keys, passwords and pinned host keys into one table. Hosts left the vault column for their own screen beside the terminal, which is what the design asks for and turned out to be the better split anyway. Two screens the design shows have nothing behind them yet — file transfer and teams — and say so plainly rather than rendering invented data; every other gap between the design and this build is recorded in docs/design-import-gaps.md.
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:DodoSSH.Client.App.ViewModels"
|
||||
x:Class="DodoSSH.Client.App.Views.PreferencesScreen"
|
||||
x:DataType="vm:MainWindowViewModel">
|
||||
|
||||
<!--
|
||||
Preferences.
|
||||
|
||||
The design's rail has six sections and its TERMINAL panel has six settings. None of the six settings can
|
||||
be saved: there is no preferences table in the local cache, no preference item type in the vault, and no
|
||||
channel from the host to the renderer that carries a terminal option — the data plane's frames are
|
||||
output, session-opened, session-closed and session-activated, and nothing else. A font-size stepper
|
||||
that reset on every launch would be worse than not having one.
|
||||
|
||||
So this screen ships what is real, which is not nothing: this machine's device key is a genuine
|
||||
preference with a genuine effect, and it is the one thing on the design's SECURITY panel that exists.
|
||||
The two commands behind it were already in the shell; they were merely homeless, wedged into the old
|
||||
account bar because there was nowhere else to put them.
|
||||
|
||||
Everything else is listed as absent rather than omitted, because a preferences screen that is silent
|
||||
about the settings it has not got reads as a product with six preferences.
|
||||
-->
|
||||
|
||||
<ScrollViewer>
|
||||
<StackPanel MaxWidth="620" Margin="28,26" HorizontalAlignment="Left">
|
||||
|
||||
<TextBlock Classes="mono" Text="THIS MACHINE" FontSize="13" FontWeight="SemiBold"
|
||||
LetterSpacing="1" Foreground="{StaticResource Text}" />
|
||||
|
||||
<Grid ColumnDefinitions="*,Auto" Margin="0,12,0,0">
|
||||
<StackPanel Grid.Column="0" Spacing="2" Margin="0,0,16,0">
|
||||
<TextBlock Text="Unlock with Windows Hello" Foreground="{StaticResource Text}" FontSize="12"
|
||||
FontWeight="Medium" />
|
||||
<TextBlock Classes="hint" FontSize="10"
|
||||
Text="Registers this machine so a later launch can open the vault with a Windows confirmation instead of your passphrase. Your passphrase keeps working." />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1" Classes="accent" Content="REGISTER"
|
||||
Command="{Binding RegisterDeviceCommand}"
|
||||
IsEnabled="{Binding !IsBusy}"
|
||||
IsVisible="{Binding CanRegisterDevice}" />
|
||||
<!--
|
||||
The withdrawal, in the place the offer was. Its own flag rather than the negation of that one: a
|
||||
machine with no TPM and a machine that is already registered are both "cannot register", and only
|
||||
the second has anything to take back.
|
||||
-->
|
||||
<Button Grid.Column="1" Classes="danger" Content="STOP UNLOCKING HERE"
|
||||
Command="{Binding ForgetDeviceCommand}"
|
||||
IsEnabled="{Binding !IsBusy}"
|
||||
IsVisible="{Binding CanForgetDevice}"
|
||||
ToolTip.Tip="Withdraws this machine's device key, here and from your account, so it goes back to asking for your passphrase. Do this to a machine you have lost." />
|
||||
</Grid>
|
||||
|
||||
<!-- Neither flag is set on a machine that cannot keep a key at all, and that is worth saying. -->
|
||||
<TextBlock Classes="hint" FontSize="10" Margin="0,8,0,0"
|
||||
Text="This machine has nowhere to keep a device key, so the vault will keep asking for your passphrase. That needs a TPM and a Windows keystore willing to release the key."
|
||||
IsVisible="{Binding HasNoDeviceKeyOption}" />
|
||||
|
||||
<Border Height="1" Background="{StaticResource BorderSubtle}" Margin="0,20" />
|
||||
|
||||
<TextBlock Classes="mono" Text="VAULT" FontSize="13" FontWeight="SemiBold"
|
||||
LetterSpacing="1" Foreground="{StaticResource Text}" />
|
||||
|
||||
<Grid ColumnDefinitions="*,Auto" Margin="0,12,0,0">
|
||||
<StackPanel Grid.Column="0" Spacing="2" Margin="0,0,16,0">
|
||||
<TextBlock Text="Lock the vault" Foreground="{StaticResource Text}" FontSize="12"
|
||||
FontWeight="Medium" />
|
||||
<TextBlock Classes="hint" FontSize="10"
|
||||
Text="Closes the vault and forgets every key it held. Shells you have open keep running and reappear when you unlock — locked describes the vault, not this machine's access to your hosts." />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1" Classes="ghost" Content="LOCK NOW" Command="{Binding LockCommand}" />
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*,Auto" Margin="0,14,0,0">
|
||||
<StackPanel Grid.Column="0" Spacing="2" Margin="0,0,16,0">
|
||||
<TextBlock Text="Synchronise" Foreground="{StaticResource Text}" FontSize="12"
|
||||
FontWeight="Medium" />
|
||||
<TextBlock Classes="hint" FontSize="10"
|
||||
Text="Runs a pass now. One runs on its own when the vault opens, straight after any change, and every minute while it stays open, so nothing depends on this being pressed." />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="6">
|
||||
<Button Classes="ghost" Content="SIGN IN" Command="{Binding SignInCommand}"
|
||||
IsVisible="{Binding !IsOnline}"
|
||||
ToolTip.Tip="Opens your browser. Syncing needs a connection; everything else works without one." />
|
||||
<Button Classes="ghost" Content="SYNC NOW" Command="{Binding Vault.SyncCommand}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Border Height="1" Background="{StaticResource BorderSubtle}" Margin="0,20" />
|
||||
|
||||
<TextBlock Classes="mono" Text="NOT BUILT YET" FontSize="13" FontWeight="SemiBold"
|
||||
LetterSpacing="1" Foreground="{StaticResource TextDim}" />
|
||||
<TextBlock Classes="hint" FontSize="11" Margin="0,8,0,0"
|
||||
Text="These are on the design and have nothing behind them. They are listed rather than left out, so that what this screen does not do is as legible as what it does. The full list, and what each would take, is in docs/design-import-gaps.md." />
|
||||
|
||||
<ItemsControl Margin="0,12,0,0">
|
||||
<ItemsControl.Styles>
|
||||
<Style Selector="TextBlock.gap">
|
||||
<Setter Property="Foreground" Value="{StaticResource TextFaint}" />
|
||||
<Setter Property="FontSize" Value="11" />
|
||||
<Setter Property="TextWrapping" Value="Wrap" />
|
||||
<Setter Property="Margin" Value="0,0,0,7" />
|
||||
</Style>
|
||||
</ItemsControl.Styles>
|
||||
<TextBlock Classes="gap"
|
||||
Text="Terminal font, size, cursor and scrollback — the renderer hard-codes them, and nothing carries a change to it." />
|
||||
<TextBlock Classes="gap"
|
||||
Text="Any preference at all, saved — there is no preferences store in the local cache and no preference item type in the vault." />
|
||||
<TextBlock Classes="gap"
|
||||
Text="Auto-lock after idle — nothing tracks idleness, and the lock policy would have to decide what to do about a shell mid-job." />
|
||||
<TextBlock Classes="gap"
|
||||
Text="Per-use approval before a key signs — keys are handed to the SSH stack whole at connect time, so there is no per-signature moment to interrupt." />
|
||||
<TextBlock Classes="gap"
|
||||
Text="SSO and team policy — the server has no team endpoints, so there is no policy for this screen to show." />
|
||||
<TextBlock Classes="gap"
|
||||
Text="Keyboard shortcuts — the window binds one chord, and the terminal keeps the rest for the remote." />
|
||||
</ItemsControl>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
</UserControl>
|
||||
Reference in New Issue
Block a user