diff --git a/client/index.html b/client/index.html index 3b8dd6f..1d1f17b 100644 --- a/client/index.html +++ b/client/index.html @@ -37,10 +37,6 @@ -
- - -
diff --git a/client/public/version.js b/client/public/version.js index ebbc482..d0fe5a5 100644 --- a/client/public/version.js +++ b/client/public/version.js @@ -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"; diff --git a/client/src/main.ts b/client/src/main.ts index 0f9dfcd..d6143fa 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -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 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(); diff --git a/client/src/network/messageHandlers.ts b/client/src/network/messageHandlers.ts index 7a7ff78..f0815c5 100644 --- a/client/src/network/messageHandlers.ts +++ b/client/src/network/messageHandlers.ts @@ -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(); diff --git a/client/src/session/connectionFlow.ts b/client/src/session/connectionFlow.ts index d33b244..cf6f49e 100644 --- a/client/src/session/connectionFlow.ts +++ b/client/src/session/connectionFlow.ts @@ -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 { 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'); diff --git a/client/src/ui/domBindings.ts b/client/src/ui/domBindings.ts index 0e8af6e..0c88f3b 100644 --- a/client/src/ui/domBindings.ts +++ b/client/src/ui/domBindings.ts @@ -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; 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(); diff --git a/deploy/scripts/up.sh b/deploy/scripts/up.sh index d59671c..eca875b 100644 --- a/deploy/scripts/up.sh +++ b/deploy/scripts/up.sh @@ -5,6 +5,9 @@ REPO_ROOT="${1:-/home/bestmidi/chgrid}" PUBLISH_DIR="${2:-/home/bestmidi/public_html/chgrid}" BASE_PATH="${3:-/chgrid/}" SERVICE_NAME="${4:-chat-grid.service}" +if [[ -z "${SERVICE_NAME// }" || "$SERVICE_NAME" == "-" || "$SERVICE_NAME" == ".service" ]]; then + SERVICE_NAME="chat-grid.service" +fi "$REPO_ROOT/deploy/scripts/deploy_client.sh" "$REPO_ROOT" "$PUBLISH_DIR" "$BASE_PATH" sudo systemctl restart "$SERVICE_NAME"