LoginScreen constructor
LoginScreen(
- AppContext ctx
Builds the screen for ctx.
Implementation
LoginScreen(this.ctx) {
final prefill = ctx.auth.prefill;
_hub = input(
id: 'login-hub',
type: 'text',
value: prefill.hub,
placeholder: 'hub.example.com:8443',
autocomplete: 'url',
autocapitalize: 'none',
onEnter: _submit,
);
_principal = input(
id: 'login-principal',
value: prefill.principal,
placeholder: 'alice',
autocomplete: 'username',
autocapitalize: 'none',
onEnter: _submit,
);
_token = input(
id: 'login-token',
type: 'password',
value: prefill.token,
placeholder: 'bearer token',
autocomplete: 'current-password',
onEnter: _submit,
);
final remember = checkbox(
'Remember token on this device',
id: 'login-remember',
checked: ctx.settings.rememberToken,
);
_remember = remember.box;
_messages = div();
_actions = div(classes: 'row');
_renderActions(connecting: false);
element = el(
'div',
classes: 'center-host',
children: [
el(
'div',
classes: 'card pad-lg narrow stack',
children: [
el(
'div',
classes: 'brand',
children: [
el('span', classes: 'dot'),
el('h1', text: 'OmnyShell'),
],
),
el(
'p',
classes: 'muted',
text: 'Connect to a Hub to discover nodes and manage sessions.',
),
_messages,
field(
'Hub address',
_hub,
hint: 'Uses wss:// when no scheme given.',
),
field('Principal', _principal),
field('Token', _token),
remember.root,
_actions,
el(
'p',
classes: 'hint',
text:
'Self-signed / dev Hubs must have their certificate trusted '
'by this browser or OS first — the browser controls TLS, so '
'there is no in-app bypass.',
),
el(
'p',
classes: 'hint version-footer',
text:
'Web Client v$webClientVersion · '
'OmnyShell v$omnyShellVersion',
),
],
),
],
);
// listen() delivers the current snapshot immediately, so an error set
// before this screen mounted (e.g. a dropped connection) renders at once.
_sub = ctx.auth.state.listen(_onAuth);
// Focus the first field that still needs input for fast keyboard entry.
scheduleMicrotask(() {
if (_hub.value.isEmpty) {
_hub.focus();
} else if (_principal.value.isEmpty) {
_principal.focus();
} else {
_token.focus();
}
});
}