101 lines
3.0 KiB
JavaScript
101 lines
3.0 KiB
JavaScript
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');
|
|
}
|