forked from phenom/healer-man
Update Healer Man server
This commit is contained in:
1 parent
cc3b2fa4d5
commit
daa417ec17
46 files changed
+1334
-172
No files matched your search
@@ -0,0 +1,80 @@
|
||||
import type { CSSProperties } from "react";
|
||||
import {
|
||||
loginKeyboardRows,
|
||||
type LoginField,
|
||||
type LoginInputSnapshot,
|
||||
type LoginKeyDefinition,
|
||||
} from "../app/loginInputStore";
|
||||
import type { CompanionCommand } from "../platform/dualScreenSync";
|
||||
import { BrandMark, FrontSurface } from "./FrontSurface";
|
||||
|
||||
function passwordPreview(length: number): string {
|
||||
if (!length) return "Password";
|
||||
return `${"•".repeat(Math.min(length, 18))}${length > 18 ? "…" : ""}`;
|
||||
}
|
||||
|
||||
function keyLabel(key: LoginKeyDefinition, activeField: LoginField): string {
|
||||
if (key.kind === "field") return activeField === "username" ? "Password" : "Username";
|
||||
return key.label;
|
||||
}
|
||||
|
||||
export function LoginVirtualKeyboard({ snapshot, notice, send }: {
|
||||
snapshot: LoginInputSnapshot;
|
||||
notice: string;
|
||||
send: (command: CompanionCommand) => void;
|
||||
}) {
|
||||
const rows = loginKeyboardRows(snapshot.keyboardMode);
|
||||
const chooseField = (field: LoginField) => send({ name: "selectLoginField", field });
|
||||
|
||||
return (
|
||||
<FrontSurface bottom className="companion-panel companion-login companion-login-keyboard" ariaLabel="Controller login keyboard">
|
||||
<header><BrandMark compact /><b>CONTROLLER KEYBOARD</b></header>
|
||||
<main>
|
||||
<div className="login-keyboard-fields" role="group" aria-label="Login fields">
|
||||
<button
|
||||
type="button"
|
||||
className={snapshot.activeField === "username" ? "is-active" : ""}
|
||||
aria-pressed={snapshot.activeField === "username"}
|
||||
onClick={() => chooseField("username")}
|
||||
>
|
||||
<small>Username</small><strong>{snapshot.username || "Select to enter"}</strong>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={snapshot.activeField === "password" ? "is-active" : ""}
|
||||
aria-pressed={snapshot.activeField === "password"}
|
||||
onClick={() => chooseField("password")}
|
||||
>
|
||||
<small>Password</small><strong>{passwordPreview(snapshot.passwordLength)}</strong>
|
||||
</button>
|
||||
</div>
|
||||
<div className="login-keyboard-grid" role="group" aria-label={`${snapshot.keyboardMode} virtual keyboard`}>
|
||||
{rows.flat().map((key) => {
|
||||
const isAction = ["login", "create", "offline"].includes(key.kind);
|
||||
const unavailableForUsername = snapshot.activeField === "username"
|
||||
&& key.kind === "character"
|
||||
&& !/^[A-Za-z0-9_]$/.test(key.value ?? "");
|
||||
return (
|
||||
<button
|
||||
key={key.id}
|
||||
type="button"
|
||||
className={`login-keyboard-key login-keyboard-key--${key.kind} ${snapshot.selectedKeyId === key.id ? "is-controller-selected" : ""} ${unavailableForUsername ? "is-unavailable" : ""}`}
|
||||
style={{ gridColumn: `span ${key.span ?? 1}` } as CSSProperties}
|
||||
aria-label={key.ariaLabel}
|
||||
aria-current={snapshot.selectedKeyId === key.id ? "true" : undefined}
|
||||
disabled={isAction && snapshot.busy !== null}
|
||||
onClick={() => send({ name: "pressLoginKey", keyId: key.id })}
|
||||
>
|
||||
{keyLabel(key, snapshot.activeField)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
<span><b>D-Pad</b> Move <b>A</b> Type</span>
|
||||
<strong>{snapshot.busy ? `${snapshot.busy === "create" ? "Creating account" : "Opening gateway"}…` : notice || `${snapshot.activeField === "username" ? "Username" : "Password"} selected`}</strong>
|
||||
</footer>
|
||||
</FrontSurface>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user