Fix auth landing flow and up.sh service fallback

This commit is contained in:
Jage9
2026-02-24 22:21:38 -05:00
parent d7be6d999a
commit b424a0ae34
7 changed files with 11 additions and 54 deletions

View File

@@ -37,10 +37,6 @@
</div>
<button id="showLoginButton" type="button">Back to login</button>
</section>
<div id="nicknameContainer" class="nickname-row">
<label for="preconnectNickname">Nickname</label>
<input id="preconnectNickname" type="text" maxlength="32" autocomplete="nickname" />
</div>
<div class="controls" id="button-container">
<button id="connectButton">Connect</button>
<button id="logoutButton">Log out</button>

View File

@@ -1,5 +1,5 @@
// Maintainer-controlled web client version.
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
window.CHGRID_WEB_VERSION = "2026.02.25 R243";
window.CHGRID_WEB_VERSION = "2026.02.25 R244";
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
window.CHGRID_TIME_ZONE = "America/Detroit";

View File

@@ -56,7 +56,7 @@ import {
import { createItemPropertyEditor } from './items/itemPropertyEditor';
import { createItemPropertyPresentation } from './items/itemPropertyPresentation';
import { ItemBehaviorRegistry } from './items/types/behaviorRegistry';
import { NICKNAME_STORAGE_KEY, SettingsStore } from './settings/settingsStore';
import { SettingsStore } from './settings/settingsStore';
import { runConnectFlow, runDisconnectFlow, type ConnectFlowDeps } from './session/connectionFlow';
import { MediaSession } from './session/mediaSession';
import { type AudioLayerState } from './types/audio';
@@ -102,8 +102,6 @@ type Dom = {
updatesSection: HTMLElement;
updatesToggle: HTMLButtonElement;
updatesPanel: HTMLDivElement;
nicknameContainer: HTMLDivElement;
preconnectNickname: HTMLInputElement;
connectButton: HTMLButtonElement;
logoutButton: HTMLButtonElement;
disconnectButton: HTMLButtonElement;
@@ -135,8 +133,6 @@ const dom: Dom = {
updatesSection: requiredById('updatesSection'),
updatesToggle: requiredById('updatesToggle'),
updatesPanel: requiredById('updatesPanel'),
nicknameContainer: requiredById('nicknameContainer'),
preconnectNickname: requiredById('preconnectNickname'),
connectButton: requiredById('connectButton'),
logoutButton: requiredById('logoutButton'),
disconnectButton: requiredById('disconnectButton'),
@@ -519,6 +515,7 @@ function sanitizeAuthUsername(value: string): string {
function updateConnectAvailability(): void {
dom.logoutButton.disabled = !authSessionToken.trim() && !state.running;
if (state.running) {
dom.connectButton.textContent = 'Connect';
dom.connectButton.disabled = true;
dom.loginView.classList.add('hidden');
dom.registerView.classList.add('hidden');
@@ -532,6 +529,7 @@ function updateConnectAvailability(): void {
const hasRegisterCredentials =
sanitizeAuthUsername(dom.registerUsername.value).length >= 2 && dom.registerPassword.value.trim().length >= 8;
const authReady = hasSessionToken || (authMode === 'login' ? hasLoginCredentials : hasRegisterCredentials);
dom.connectButton.textContent = hasSessionToken ? 'Connect' : authMode === 'login' ? 'Log In & Connect' : 'Register & Connect';
dom.connectButton.disabled = mediaSession.isConnecting() || !authReady;
}
@@ -1419,8 +1417,6 @@ async function handleAuthResult(message: Extract<IncomingMessage, { type: 'auth_
const resolved = sanitizeName(message.nickname);
if (resolved) {
state.player.nickname = resolved;
dom.preconnectNickname.value = resolved;
settings.saveNickname(resolved);
}
}
dom.authPassword.value = '';
@@ -1561,7 +1557,6 @@ const onAppMessage = createOnMessageHandler({
audioUiBlip: () => audio.sfxUiBlip(),
audioUiConfirm: () => audio.sfxUiConfirm(),
audioUiCancel: () => audio.sfxUiCancel(),
NICKNAME_STORAGE_KEY,
getCarriedItemId: () => getCarriedItem()?.id ?? null,
recomputeActiveItemPropertyKeys,
itemPropertyLabel,
@@ -2558,8 +2553,6 @@ function closeSettings(): void {
function setupUiHandlers(): void {
setupDomUiHandlers({
dom,
sanitizeName,
nicknameStorageKey: NICKNAME_STORAGE_KEY,
updateConnectAvailability,
connect,
disconnect,
@@ -2615,11 +2608,6 @@ setupInputHandlers();
setupUiHandlers();
dom.authUsername.value = sanitizeAuthUsername(authUsername);
dom.registerUsername.value = sanitizeAuthUsername(authUsername);
const storedNickname = sanitizeName(settings.loadNickname());
dom.preconnectNickname.value = storedNickname;
if (storedNickname) {
state.player.nickname = storedNickname;
}
setAuthMode('login');
updateConnectAvailability();
updateDeviceSummary();

View File

@@ -25,13 +25,11 @@ type MessageHandlerDeps = {
carriedItemId: string | null;
};
dom: {
nicknameContainer: HTMLElement;
connectButton: HTMLElement;
disconnectButton: HTMLElement;
focusGridButton: HTMLElement;
canvas: HTMLCanvasElement;
instructions: HTMLElement;
preconnectNickname: HTMLInputElement;
};
signalingSend: (message: unknown) => void;
peerManager: {
@@ -63,7 +61,6 @@ type MessageHandlerDeps = {
audioUiBlip: () => void;
audioUiConfirm: () => void;
audioUiCancel: () => void;
NICKNAME_STORAGE_KEY: string;
getCarriedItemId: () => string | null;
recomputeActiveItemPropertyKeys: (itemId: string) => void;
itemPropertyLabel: (key: string) => string;
@@ -113,7 +110,6 @@ export function createOnMessageHandler(deps: MessageHandlerDeps): (message: Inco
const targetY = persistedPosition?.y ?? message.player.y;
deps.state.player.x = Math.max(0, Math.min(deps.getWorldGridSize() - 1, targetX));
deps.state.player.y = Math.max(0, Math.min(deps.getWorldGridSize() - 1, targetY));
deps.dom.nicknameContainer.classList.add('hidden');
deps.dom.connectButton.classList.add('hidden');
deps.dom.disconnectButton.classList.remove('hidden');
deps.dom.focusGridButton.classList.remove('hidden');
@@ -228,8 +224,8 @@ export function createOnMessageHandler(deps: MessageHandlerDeps): (message: Inco
case 'nickname_result': {
deps.state.player.nickname = deps.sanitizeName(message.effectiveNickname) || 'user...';
if (message.accepted) {
deps.dom.preconnectNickname.value = deps.state.player.nickname;
localStorage.setItem(deps.NICKNAME_STORAGE_KEY, deps.state.player.nickname);
deps.updateStatus(`Nickname set to ${deps.state.player.nickname}`);
deps.audioUiConfirm();
} else {
deps.pushChatMessage(message.reason || 'Nickname unavailable.');
deps.audioUiCancel();

View File

@@ -3,8 +3,6 @@ import type { GameState } from '../state/gameState';
const WELCOME_TIMEOUT_MS = 8_000;
type DomRefs = {
preconnectNickname: HTMLInputElement;
nicknameContainer: HTMLDivElement;
connectButton: HTMLButtonElement;
disconnectButton: HTMLButtonElement;
focusGridButton: HTMLButtonElement;
@@ -40,15 +38,14 @@ export type ConnectFlowDeps = {
};
/**
* Runs connect flow: validate nickname, preflight mic/device setup, then signaling connect.
* Runs connect flow: preflight media setup, then signaling connect/auth.
*/
export async function runConnectFlow(deps: ConnectFlowDeps): Promise<void> {
if (deps.mediaIsConnecting() || deps.state.running) {
return;
}
const nickname = deps.sanitizeName(deps.dom.preconnectNickname.value);
const nickname = deps.sanitizeName(deps.state.player.nickname);
deps.state.player.nickname = nickname || deps.state.player.nickname;
deps.dom.preconnectNickname.value = nickname;
if (nickname) {
deps.settingsSaveNickname(nickname);
}
@@ -138,7 +135,6 @@ export function runDisconnectFlow(deps: ConnectFlowDeps): void {
deps.state.effectSelectIndex = 0;
deps.mediaSetConnecting(false);
deps.dom.nicknameContainer.classList.remove('hidden');
deps.dom.connectButton.classList.remove('hidden');
deps.dom.disconnectButton.classList.add('hidden');
deps.dom.focusGridButton.classList.add('hidden');

View File

@@ -3,7 +3,6 @@
*/
type UiDom = {
connectButton: HTMLButtonElement;
preconnectNickname: HTMLInputElement;
disconnectButton: HTMLButtonElement;
focusGridButton: HTMLButtonElement;
settingsButton: HTMLButtonElement;
@@ -19,8 +18,6 @@ type UiDom = {
*/
type UiBindingsDeps = {
dom: UiDom;
sanitizeName: (value: string) => string;
nicknameStorageKey: string;
updateConnectAvailability: () => void;
connect: () => Promise<void>;
disconnect: () => void;
@@ -46,25 +43,6 @@ export function setupUiHandlers(deps: UiBindingsDeps): void {
deps.dom.connectButton.addEventListener('click', () => {
void deps.connect();
});
deps.dom.preconnectNickname.addEventListener('input', () => {
deps.updateConnectAvailability();
});
deps.dom.preconnectNickname.addEventListener('change', () => {
const clean = deps.sanitizeName(deps.dom.preconnectNickname.value);
deps.dom.preconnectNickname.value = clean;
if (clean) {
localStorage.setItem(deps.nicknameStorageKey, clean);
} else {
localStorage.removeItem(deps.nicknameStorageKey);
}
deps.updateConnectAvailability();
});
deps.dom.preconnectNickname.addEventListener('keydown', (event) => {
if (event.key === 'Enter' && !deps.dom.connectButton.disabled) {
event.preventDefault();
void deps.connect();
}
});
deps.dom.disconnectButton.addEventListener('click', () => {
deps.disconnect();