Public Access
The Android head skipped a host's forwards because it had nowhere to show what was listening. Its terminal bar now draws a ⇄ for a tab that has forwards, carrying the listening count in green and turning the danger colour when one failed, and it raises a sheet over the same rows the desktop sidebar lists: notation, route, state, failure reason and a tap to switch each off or on. MainWindowViewModel.StartForwards no longer returns early on Android. The sheet is shell state like the connect sheet: it collapses the renderer while up, is lowered by leaving the terminal, and the back gesture closes it first. Forwards ride the shell's keep-alive rather than holding the foreground service themselves, since a forward cannot outlive its shell. They only change the notification, which now counts ports forwarded beside shells connected, fed by a new ForwardsChanged event and ListeningForwardCount. The phone still has no editor for forwards; the More screen card, README and design-import-gaps now say they run here and are edited on the desktop.
227 lines
13 KiB
XML
227 lines
13 KiB
XML
<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.Android.Views.MoreScreen"
|
||
x:DataType="vm:MainWindowViewModel"
|
||
Background="{StaticResource Canvas}">
|
||
|
||
<!--
|
||
Design v2 — SETTINGS: the hub for everything the bottom bar has no room for.
|
||
|
||
Three slots and ten destinations is the arithmetic the design solves by putting seven of them one tap
|
||
deeper. This screen is that tap. It takes the shell as its data context rather than the vault, because
|
||
every row on it is a navigation command and nothing here reads an item.
|
||
|
||
Teams is the tenth and the design never drew it — see the row itself. That one is the design's count
|
||
plus one rather than a rearrangement of it. The keychain below is a rearrangement, and the only one:
|
||
the bottom bar lost a slot to gain this row.
|
||
|
||
The rows are the design's list rows rather than cards: a card is one thing you act on, and a destination
|
||
is not a thing — it is a place. Each carries a sentence saying what is behind it, because a hub whose
|
||
entries are one word each is a menu you have to open to read.
|
||
|
||
── from MORE to SETTINGS ──────────────────────────────────────────────────────────────────────────────
|
||
The hub was called More because that was the honest name for a handful of things that did not fit. With
|
||
the keychain on it as well it is the place everything that is not connecting to a machine lives, which
|
||
has a name of its own and a glyph everyone already knows.
|
||
|
||
The keychain is first, and above the rule, because it is the only row here that holds the user's own
|
||
material rather than a screen about the application. Everything below it is somewhere to look at what
|
||
has happened or how this phone behaves.
|
||
-->
|
||
|
||
<Grid RowDefinitions="Auto,*">
|
||
|
||
<Border Grid.Row="0" Height="56" Padding="16,0">
|
||
<TextBlock Classes="heading" Text="Settings" />
|
||
</Border>
|
||
|
||
<ScrollViewer Grid.Row="1">
|
||
<StackPanel Margin="10,0,10,20" Spacing="2">
|
||
|
||
<!--
|
||
"Keychain", although the design's tab says Vault and the enum member is Vault. The split is a
|
||
standing rule rather than an inconsistency: every sentence a user reads calls the encrypted store a
|
||
keychain, and everything under the surface calls it a vault, because renaming the wire route, the
|
||
tables and the CLR types would put an AAD resource type inside the blast radius of a
|
||
find-and-replace. See docs/design-import-gaps.md. A row reading Vault would be the one place the
|
||
product surface leaked the implementation's word.
|
||
-->
|
||
<Button Classes="row" Command="{Binding ShowScreenCommand}"
|
||
CommandParameter="{x:Static vm:ShellScreen.Keychain}">
|
||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||
<TextBlock Grid.Column="0" Text="⚿" Foreground="{StaticResource AccentText}" FontSize="14"
|
||
Width="22" VerticalAlignment="Center" />
|
||
<StackPanel Grid.Column="1" Spacing="2" VerticalAlignment="Center">
|
||
<TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold" Text="Keychain" />
|
||
<TextBlock Classes="detail" Foreground="{StaticResource TextDim}"
|
||
Text="Keys, passwords, buckets and tags — everything in the vault that is not a host." />
|
||
</StackPanel>
|
||
<TextBlock Grid.Column="2" Text="›" Foreground="{StaticResource TextGhost}" FontSize="15"
|
||
VerticalAlignment="Center" />
|
||
</Grid>
|
||
</Button>
|
||
|
||
<Border Height="1" Background="{StaticResource Border}" Margin="16,8" />
|
||
|
||
<Button Classes="row" Command="{Binding ShowScreenCommand}"
|
||
CommandParameter="{x:Static vm:ShellScreen.Snippets}">
|
||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||
<TextBlock Grid.Column="0" Text="❯" Foreground="{StaticResource AccentText}" FontSize="14"
|
||
Width="22" VerticalAlignment="Center" />
|
||
<StackPanel Grid.Column="1" Spacing="2" VerticalAlignment="Center">
|
||
<TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold" Text="Snippets" />
|
||
<TextBlock Classes="detail" Foreground="{StaticResource TextDim}" Text="Saved commands, typed into an open shell." />
|
||
</StackPanel>
|
||
<TextBlock Grid.Column="2" Text="›" Foreground="{StaticResource TextGhost}" FontSize="15"
|
||
VerticalAlignment="Center" />
|
||
</Grid>
|
||
</Button>
|
||
|
||
<!--
|
||
These two go through ShowFiles rather than ShowScreen: they are one screen over one view model,
|
||
and which kind of remote it offers is the thing being chosen. See ShowFilesCommand for why that
|
||
is set by the button rather than on arrival.
|
||
-->
|
||
<Button Classes="row" Command="{Binding ShowFilesCommand}"
|
||
CommandParameter="{x:Static vm:RemoteKind.Host}">
|
||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||
<TextBlock Grid.Column="0" Text="⇅" Foreground="{StaticResource AccentText}" FontSize="14"
|
||
Width="22" VerticalAlignment="Center" />
|
||
<StackPanel Grid.Column="1" Spacing="2" VerticalAlignment="Center">
|
||
<TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold" Text="SFTP" />
|
||
<TextBlock Classes="detail" Foreground="{StaticResource TextDim}"
|
||
Text="Browse a host's files." />
|
||
</StackPanel>
|
||
<TextBlock Grid.Column="2" Text="›" Foreground="{StaticResource TextGhost}" FontSize="15"
|
||
VerticalAlignment="Center" />
|
||
</Grid>
|
||
</Button>
|
||
|
||
<Button Classes="row" Command="{Binding ShowFilesCommand}"
|
||
CommandParameter="{x:Static vm:RemoteKind.Bucket}">
|
||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||
<TextBlock Grid.Column="0" Text="◳" Foreground="{StaticResource AccentText}" FontSize="14"
|
||
Width="22" VerticalAlignment="Center" />
|
||
<StackPanel Grid.Column="1" Spacing="2" VerticalAlignment="Center">
|
||
<TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold" Text="S3" />
|
||
<TextBlock Classes="detail" Foreground="{StaticResource TextDim}"
|
||
Text="Objects in an S3-compatible bucket from the keychain." />
|
||
</StackPanel>
|
||
<TextBlock Grid.Column="2" Text="›" Foreground="{StaticResource TextGhost}" FontSize="15"
|
||
VerticalAlignment="Center" />
|
||
</Grid>
|
||
</Button>
|
||
|
||
<Button Classes="row" Command="{Binding ShowScreenCommand}"
|
||
CommandParameter="{x:Static vm:ShellScreen.Logs}">
|
||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||
<TextBlock Grid.Column="0" Text="≡" Foreground="{StaticResource AccentText}" FontSize="14"
|
||
Width="22" VerticalAlignment="Center" />
|
||
<StackPanel Grid.Column="1" Spacing="2" VerticalAlignment="Center">
|
||
<TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold" Text="Logs" />
|
||
<TextBlock Classes="detail" Foreground="{StaticResource TextDim}" Text="What has been connected to, and what has changed." />
|
||
</StackPanel>
|
||
<TextBlock Grid.Column="2" Text="›" Foreground="{StaticResource TextGhost}" FontSize="15"
|
||
VerticalAlignment="Center" />
|
||
</Grid>
|
||
</Button>
|
||
|
||
<!--
|
||
Vaults, which the v2 design has no row for — it is a shipped screen the design had no slot for
|
||
rather than a drawn one with nothing behind it. It is on the phone because a vault arrives
|
||
without being asked for, and somebody it arrives for is at least as likely to be holding a phone.
|
||
|
||
◎ rather than a glyph of its own. The desktop rail already draws this destination with it, and
|
||
two heads giving one destination two marks is how a user learns the wrong one.
|
||
-->
|
||
<Button Classes="row" Command="{Binding ShowScreenCommand}"
|
||
CommandParameter="{x:Static vm:ShellScreen.Vaults}">
|
||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||
<TextBlock Grid.Column="0" Text="◎" Foreground="{StaticResource AccentText}" FontSize="14"
|
||
Width="22" VerticalAlignment="Center" />
|
||
<StackPanel Grid.Column="1" Spacing="2" VerticalAlignment="Center">
|
||
<TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold" Text="Vaults" />
|
||
<TextBlock Classes="detail" Foreground="{StaticResource TextDim}"
|
||
Text="Your vaults, who is in each one, and who holds its key." />
|
||
</StackPanel>
|
||
<TextBlock Grid.Column="2" Text="›" Foreground="{StaticResource TextGhost}" FontSize="15"
|
||
VerticalAlignment="Center" />
|
||
</Grid>
|
||
</Button>
|
||
|
||
<Button Classes="row" Command="{Binding ShowScreenCommand}"
|
||
CommandParameter="{x:Static vm:ShellScreen.Preferences}">
|
||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||
<TextBlock Grid.Column="0" Text="⚙" Foreground="{StaticResource AccentText}" FontSize="14"
|
||
Width="22" VerticalAlignment="Center" />
|
||
<StackPanel Grid.Column="1" Spacing="2" VerticalAlignment="Center">
|
||
<TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold" Text="Preferences" />
|
||
<TextBlock Classes="detail" Foreground="{StaticResource TextDim}"
|
||
Text="Unlocking with a fingerprint, and what this phone cannot do." />
|
||
</StackPanel>
|
||
<TextBlock Grid.Column="2" Text="›" Foreground="{StaticResource TextGhost}" FontSize="15"
|
||
VerticalAlignment="Center" />
|
||
</Grid>
|
||
</Button>
|
||
|
||
<!--
|
||
Locking, here as well as in the header.
|
||
|
||
The header carries it on HOSTS and stands down behind SETTINGS, so without this row every screen
|
||
under here would be two taps from locking the keychain. That is the wrong direction for the one
|
||
action whose whole value is being quick, and it is why this is a row on the hub rather than
|
||
something you go back for.
|
||
-->
|
||
<Button Classes="row" Margin="0,10,0,0" Command="{Binding LockCommand}">
|
||
<Grid ColumnDefinitions="Auto,*">
|
||
<TextBlock Grid.Column="0" Text="⚿" Foreground="{StaticResource TextDim}" FontSize="14"
|
||
Width="22" VerticalAlignment="Center" />
|
||
<StackPanel Grid.Column="1" Spacing="2" VerticalAlignment="Center">
|
||
<TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold" Text="Lock the keychain" />
|
||
<TextBlock Classes="detail" Foreground="{StaticResource TextDim}"
|
||
Text="Shells you have open keep running." />
|
||
</StackPanel>
|
||
</Grid>
|
||
</Button>
|
||
|
||
<!--
|
||
◆ Port forwarding, stated rather than drawn.
|
||
|
||
The v2 design gives this hub a sixth entry and a full screen behind it: local, remote and dynamic
|
||
rules with toggles and byte counters. Forwarding is built and runs here as on the desktop — a host's
|
||
forwards start with every terminal opened to it — but it is not a destination, so it has no row. A
|
||
forward belongs to a host and runs with a session, and on this head the session's forwards are a
|
||
sheet off the terminal's bar: the ⇄ button, drawn for a tab that has some, lists them with a switch
|
||
each. See MainWindowViewModel.IsForwardsSheetOpen.
|
||
|
||
What the phone lacks is the editor: its host form has no PORT FORWARDS section yet, so forwards are
|
||
added on the desktop and arrive here with the host. The byte counters are not built anywhere;
|
||
SSH.NET keeps no count to draw.
|
||
|
||
It is a paragraph here rather than a missing row for the reason the desktop keeps TEAMS in its rail:
|
||
a place somebody looks for a feature should say where it went. See docs/design-import-gaps.md.
|
||
-->
|
||
<Border Classes="card" Margin="6,16,6,0">
|
||
<StackPanel Spacing="7">
|
||
<StackPanel Orientation="Horizontal" Spacing="9">
|
||
<TextBlock Text="⇄" Foreground="{StaticResource TextFaint}" FontSize="14"
|
||
VerticalAlignment="Center" />
|
||
<TextBlock Classes="mono" FontSize="13.5" FontWeight="SemiBold"
|
||
Foreground="{StaticResource TextDim}" Text="Port forwarding" />
|
||
<Border Classes="tag outline" VerticalAlignment="Center">
|
||
<TextBlock Text="IN THE TERMINAL" />
|
||
</Border>
|
||
</StackPanel>
|
||
<TextBlock Classes="body"
|
||
Text="Forwards saved on a host start with every terminal opened to it, here as on the desktop. The ⇄ button in the terminal's bar lists them, with a switch each and the reason one could not start. They are added and edited in the desktop app's host editor; this phone runs them but has no editor for them yet." />
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
</StackPanel>
|
||
</ScrollViewer>
|
||
|
||
</Grid>
|
||
|
||
</UserControl>
|