Fix auth landing flow and up.sh service fallback
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user