47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
import { Label, requestRender, type TextField, ui } from '../../ui';
|
||
|
||
/**
|
||
* What a form that can be refused shows about its last attempt – the sign-in screen and the
|
||
* password dialog: the warning line under the fields, and whether an answer is still awaited.
|
||
*/
|
||
export class FormStatus {
|
||
readonly message = new Label('', { style: 'warning' });
|
||
private waiting = false;
|
||
|
||
/** `onChange` redoes what the form shows of it: its button while waiting, its layout after a message. */
|
||
constructor(private readonly onChange: (busy: boolean) => void) {}
|
||
|
||
get busy(): boolean {
|
||
return this.waiting;
|
||
}
|
||
|
||
/** What the check scripts read. */
|
||
info(): { message: string; busy: boolean } {
|
||
return { message: this.message.text, busy: this.waiting };
|
||
}
|
||
|
||
say(message: string): void {
|
||
this.message.setText(message);
|
||
this.changed();
|
||
}
|
||
|
||
setBusy(busy: boolean): void {
|
||
this.waiting = busy;
|
||
this.changed();
|
||
}
|
||
|
||
private changed(): void {
|
||
this.onChange(this.waiting);
|
||
requestRender();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Puts the caret back into a field after a refused attempt. A field blurs itself once its Enter
|
||
* has been handled, and that happens after this call returns – so the focus has to be set again
|
||
* behind it, or the next thing typed goes nowhere.
|
||
*/
|
||
export function refocus(field: TextField): void {
|
||
queueMicrotask(() => ui().focus.focus(field));
|
||
}
|