import { en } from './locales/en.js'; import { normalizeServer, needsConfirmation } from './server.js'; for (const element of document.querySelectorAll('[data-i18n]')) { element.textContent = en[element.dataset.i18n]; } const form = document.querySelector('#server-form'); const input = document.querySelector('#server-url'); const status = document.querySelector('#connection-status'); const open = document.querySelector('.open-workspace'); const resume = document.querySelector('#resume'); const confirmation = document.querySelector('#switch-confirmation'); let activeServer = null; let pendingServer = null; let initialized = false; function action(name, server) { const url = new URL(`/action/${name}`, location.href); if (server) { url.searchParams.set('server', server); } if (window.nativeLauncher) { window.nativeLauncher.postMessage(url.href); } else { location.href = url.href; } } window.updateLauncher = (query) => { const state = new URLSearchParams(query); const phase = state.get('phase'); const server = state.get('server'); if (!initialized) { input.value = server; initialized = true; } if (phase === 'connecting' || phase === 'connected') { activeServer = server; } status.textContent = en[ phase === 'connected' && state.get('platform') === 'android' ? 'connectedMobile' : phase ] ?? ''; status.dataset.state = phase; open.disabled = phase === 'connecting'; open.textContent = en[phase === 'connectionError' ? 'retry' : 'openWorkspace']; resume.hidden = state.get('ready') !== 'true'; form.setAttribute('aria-busy', String(phase === 'connecting')); }; function connect(server) { confirmation.hidden = true; pendingServer = null; action('open', server); } form.addEventListener('submit', (event) => { event.preventDefault(); let server; try { server = normalizeServer(input.value); } catch { status.textContent = en.invalidServer; input.setAttribute('aria-invalid', 'true'); input.focus(); return; } input.removeAttribute('aria-invalid'); if (needsConfirmation(activeServer, server)) { pendingServer = server; confirmation.hidden = false; document.querySelector('#confirm-switch').focus(); return; } connect(server); }); document.querySelector('#confirm-switch').addEventListener('click', () => { if (pendingServer) { connect(pendingServer); } }); document.querySelector('#cancel-switch').addEventListener('click', () => { confirmation.hidden = true; pendingServer = null; input.focus(); }); resume.addEventListener('click', () => action('resume')); document.querySelector('#appearance').addEventListener('change', (event) => { document.documentElement.dataset.appearance = event.target.value; }); if (window.nativeLauncher) { action('ready'); } window.updateAvailable = (available) => { document.querySelector('#update-notice').hidden = !available; }; document .querySelector('#update-notice') .addEventListener('click', () => action('updates'));