Public Access
Merge branch 'main' into the Android head
Main grew the screens the host-management plan called for — hosts, pins, snippets, logs, import, teams — plus the ObjectStore and Import projects behind two of them, and moved WindowsDeviceKeyStore into the desktop head's Platform folder. Five of those view models landed in a directory this branch had already moved, so they join the rest in DodoSSH.Client.Shell: git spotted the rename and put them there, and the namespaces followed. Shell picks up ObjectStore and Import as a result, which the Android head then gets transitively and will use neither of at first — scoped storage means there is no ~/.ssh/config to import, and file transfer is out of its first scope. Desktop suites green at 155 and 64.
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:DodoSSH.Client.Shell.ViewModels"
|
||||
x:Class="DodoSSH.Client.App.Views.LogsScreen"
|
||||
x:DataType="vm:LogsViewModel">
|
||||
|
||||
<!--
|
||||
What has been connected to, and what has been changed.
|
||||
|
||||
Two logs behind one screen, chosen by two buttons rather than by a selector's selection — the same idiom
|
||||
the keychain screen's categories use, and for the same reason: a selection binding moves before a command
|
||||
can refuse it.
|
||||
|
||||
Both are ordinary synced keychain items, encrypted like everything else. The server holds them and cannot
|
||||
read a single field; what it does learn is that rows exist and when they were written, which ADR 0001
|
||||
records as the metadata this design cannot hide.
|
||||
|
||||
The connections list shows anything still open at the top, marked "still open" rather than with a dash. A
|
||||
dash would read as a missing recording, and the two are opposite facts — an entry is written once, when a
|
||||
connection closes, so a live session is deliberately not in the vault yet.
|
||||
-->
|
||||
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
|
||||
<Border Grid.Row="0" Padding="14,0" Height="44"
|
||||
BorderBrush="{StaticResource Border}" BorderThickness="0,0,0,1">
|
||||
<Grid ColumnDefinitions="Auto,Auto,Auto,*,Auto" VerticalAlignment="Center">
|
||||
<TextBlock Grid.Column="0" Classes="mono" Text="LOGS" FontSize="11" FontWeight="SemiBold"
|
||||
LetterSpacing="1" Foreground="{StaticResource Text}" VerticalAlignment="Center"
|
||||
Margin="0,0,14,0" />
|
||||
|
||||
<Button Grid.Column="1" Classes="flat cat" Content="CONNECTIONS"
|
||||
Classes.active="{Binding ShowsConnections}"
|
||||
Command="{Binding ShowSectionCommand}"
|
||||
CommandParameter="{x:Static vm:LogSection.Connections}" />
|
||||
<Button Grid.Column="2" Classes="flat cat" Content="KEYCHAIN"
|
||||
Classes.active="{Binding ShowsActivity}"
|
||||
Command="{Binding ShowSectionCommand}"
|
||||
CommandParameter="{x:Static vm:LogSection.Activity}" />
|
||||
|
||||
<TextBlock Grid.Column="3" Classes="mono" Text="{Binding Status}" FontSize="9.5"
|
||||
Foreground="{StaticResource TextFaint}" Margin="14,0,0,0"
|
||||
TextTrimming="CharacterEllipsis" VerticalAlignment="Center" />
|
||||
|
||||
<Button Grid.Column="4" Classes="ghost" Content="REFRESH" Command="{Binding RefreshCommand}"
|
||||
IsEnabled="{Binding !IsBusy}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- ============ Connections ============ -->
|
||||
<Grid Grid.Row="1" RowDefinitions="Auto,*" IsVisible="{Binding ShowsConnections}">
|
||||
|
||||
<Grid Grid.Row="0" ColumnDefinitions="1.2*,1.6*,88,72,90,*" Margin="14,6,14,6"
|
||||
IsVisible="{Binding HasConnections}">
|
||||
<TextBlock Grid.Column="0" Classes="label" Text="HOST" FontSize="8.5" LetterSpacing="1" />
|
||||
<TextBlock Grid.Column="1" Classes="label" Text="ADDRESS" FontSize="8.5" LetterSpacing="1" />
|
||||
<TextBlock Grid.Column="2" Classes="label" Text="LASTED" FontSize="8.5" LetterSpacing="1" />
|
||||
<TextBlock Grid.Column="3" Classes="label" Text="KIND" FontSize="8.5" LetterSpacing="1" />
|
||||
<TextBlock Grid.Column="4" Classes="label" Text="STARTED" FontSize="8.5" LetterSpacing="1" />
|
||||
<TextBlock Grid.Column="5" Classes="label" Text="FROM" FontSize="8.5" LetterSpacing="1" />
|
||||
</Grid>
|
||||
|
||||
<ListBox Grid.Row="1" x:Name="ConnectionList" Focusable="True"
|
||||
ItemsSource="{Binding Connections}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:ConnectionLogRowViewModel">
|
||||
<Grid ColumnDefinitions="1.2*,1.6*,88,72,90,*" Margin="0,6,14,6">
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="6" Margin="14,0,8,0">
|
||||
<Ellipse Classes="dot" Classes.live="{Binding IsLive}" VerticalAlignment="Center" />
|
||||
<TextBlock Classes="mono" Text="{Binding HostLabel}" FontSize="11" FontWeight="Medium"
|
||||
Foreground="{StaticResource Text}" TextTrimming="CharacterEllipsis"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="1" Classes="mono" Text="{Binding Address}" FontSize="9.5"
|
||||
Foreground="{StaticResource TextDim}" Margin="0,0,8,0"
|
||||
TextTrimming="CharacterEllipsis" VerticalAlignment="Center" />
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="6" VerticalAlignment="Center">
|
||||
<TextBlock Classes="mono" Text="{Binding Duration}" FontSize="9.5"
|
||||
Foreground="{StaticResource TextDim}" />
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="3" Classes="mono" Text="{Binding Kind}" FontSize="9"
|
||||
Foreground="{StaticResource TextFaint}" VerticalAlignment="Center" />
|
||||
<TextBlock Grid.Column="4" Classes="mono" Text="{Binding Started}" FontSize="9"
|
||||
Foreground="{StaticResource TextFaint}" VerticalAlignment="Center" />
|
||||
<StackPanel Grid.Column="5" Orientation="Horizontal" Spacing="6" VerticalAlignment="Center">
|
||||
<TextBlock Classes="mono" Text="{Binding DeviceName}" FontSize="9"
|
||||
Foreground="{StaticResource TextFaint}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<!--
|
||||
Only when there is something to say. A connection that opened and closed says nothing
|
||||
here; one that was refused says so, and that is the row worth finding in a long list.
|
||||
-->
|
||||
<Border Classes="chip warn" Padding="4,0" IsVisible="{Binding HasOutcome}">
|
||||
<TextBlock Text="{Binding Outcome}" FontSize="8.5" />
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<TextBlock Grid.Row="1" Classes="hint" Text="{Binding EmptyMessage}" FontSize="11"
|
||||
Margin="24" HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
TextAlignment="Center" MaxWidth="420"
|
||||
IsVisible="{Binding !HasConnections}" />
|
||||
</Grid>
|
||||
|
||||
<!-- ============ Keychain changes ============ -->
|
||||
<Grid Grid.Row="1" RowDefinitions="Auto,*" IsVisible="{Binding ShowsActivity}">
|
||||
|
||||
<Grid Grid.Row="0" ColumnDefinitions="1.2*,90,96,*,90" Margin="14,6,14,6"
|
||||
IsVisible="{Binding HasActivity}">
|
||||
<TextBlock Grid.Column="0" Classes="label" Text="ITEM" FontSize="8.5" LetterSpacing="1" />
|
||||
<TextBlock Grid.Column="1" Classes="label" Text="TYPE" FontSize="8.5" LetterSpacing="1" />
|
||||
<TextBlock Grid.Column="2" Classes="label" Text="WHAT" FontSize="8.5" LetterSpacing="1" />
|
||||
<TextBlock Grid.Column="3" Classes="label" Text="FIELDS" FontSize="8.5" LetterSpacing="1" />
|
||||
<TextBlock Grid.Column="4" Classes="label" Text="WHEN" FontSize="8.5" LetterSpacing="1" />
|
||||
</Grid>
|
||||
|
||||
<ListBox Grid.Row="1" x:Name="ActivityList" Focusable="True" ItemsSource="{Binding Activity}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:ActivityLogRowViewModel">
|
||||
<Grid ColumnDefinitions="1.2*,90,96,*,90" Margin="14,6,14,6">
|
||||
<TextBlock Grid.Column="0" Classes="mono" Text="{Binding ItemLabel}" FontSize="11"
|
||||
FontWeight="Medium" Foreground="{StaticResource Text}" Margin="0,0,8,0"
|
||||
TextTrimming="CharacterEllipsis" VerticalAlignment="Center" />
|
||||
<TextBlock Grid.Column="1" Classes="mono" Text="{Binding ItemKind}" FontSize="9"
|
||||
Foreground="{StaticResource TextFaint}" VerticalAlignment="Center" />
|
||||
<TextBlock Grid.Column="2" Classes="mono" Text="{Binding Operation}" FontSize="9.5"
|
||||
Foreground="{StaticResource TextDim}" VerticalAlignment="Center" />
|
||||
<!--
|
||||
The names of the fields that changed, and never what they changed to. A log that recorded
|
||||
an old password would be a plaintext credential store with a vault drawn around it.
|
||||
-->
|
||||
<TextBlock Grid.Column="3" Classes="mono" Text="{Binding ChangedFields}" FontSize="9.5"
|
||||
Foreground="{StaticResource TextFaint}" Margin="0,0,8,0"
|
||||
TextTrimming="CharacterEllipsis" VerticalAlignment="Center"
|
||||
IsVisible="{Binding HasChangedFields}" />
|
||||
<TextBlock Grid.Column="4" Classes="mono" Text="{Binding At}" FontSize="9"
|
||||
Foreground="{StaticResource TextFaint}" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<TextBlock Grid.Row="1" Classes="hint" Text="{Binding EmptyMessage}" FontSize="11"
|
||||
Margin="24" HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
TextAlignment="Center" MaxWidth="420"
|
||||
IsVisible="{Binding !HasActivity}" />
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
Reference in New Issue
Block a user