246 lines
9.1 KiB
JavaScript
246 lines
9.1 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
const versions = Object.freeze({ app: '0.12.14', jquery: '4.0.0', jqueryUi: '1.14.2' });
|
|
const steps = ['storage', 'jquery', 'jquery-ui', 'modules', 'server', 'routes', 'location'];
|
|
const stepLabels = Object.freeze({
|
|
get storage() { return globalThis.Wegwichtel.I18n.t("bootstrap-loader.gespeicherte.inhalte.prufen"); },
|
|
get jquery() { return globalThis.Wegwichtel.I18n.t("bootstrap-loader.wegwichtel.vorbereiten"); },
|
|
get 'jquery-ui'() { return globalThis.Wegwichtel.I18n.t("bootstrap-loader.die.bedienung.vorbereiten"); },
|
|
get modules() { return globalThis.Wegwichtel.I18n.t("bootstrap-loader.die.app.vorbereiten"); },
|
|
get server() { return globalThis.Wegwichtel.I18n.t("bootstrap-loader.verbindung.prufen"); },
|
|
get routes() { return globalThis.Wegwichtel.I18n.t("bootstrap-loader.strecken.laden"); },
|
|
get location() { return globalThis.Wegwichtel.I18n.t("bootstrap.location"); }
|
|
});
|
|
const screen = document.getElementById('bootstrap-screen');
|
|
const progress = document.getElementById('bootstrap-progress');
|
|
const errorBox = document.getElementById('bootstrap-error');
|
|
const retry = document.getElementById('bootstrap-retry');
|
|
const enter = document.getElementById('bootstrap-enter');
|
|
const readyText = document.getElementById('bootstrap-ready');
|
|
const cleanupStatus = document.getElementById('storage-cleanup-status');
|
|
const actionStatus = document.getElementById('bootstrap-action-status');
|
|
const statusText = document.getElementById('bootstrap-status-text');
|
|
const androidBrowserHint = document.getElementById('android-browser-hint');
|
|
let ready = false;
|
|
let statusTransition = 0;
|
|
const completedSteps = new Set();
|
|
|
|
const versioned = path => `${path}${path.includes('?') ? '&' : '?'}v=${encodeURIComponent(versions.app)}`;
|
|
|
|
function updateAndroidBrowserHint() {
|
|
if (!androidBrowserHint) return;
|
|
const userAgent = globalThis.navigator?.userAgent || '';
|
|
const platform = globalThis.navigator?.userAgentData?.platform || '';
|
|
const isAndroid = /Android/i.test(`${userAgent} ${platform}`);
|
|
if (!isAndroid) {
|
|
androidBrowserHint.hidden = true;
|
|
return;
|
|
}
|
|
|
|
const isChrome = /Chrome\//i.test(userAgent)
|
|
&& !/(?:EdgA|OPR|SamsungBrowser)\//i.test(userAgent);
|
|
androidBrowserHint.hidden = false;
|
|
androidBrowserHint.dataset.browser = isChrome ? 'chrome' : 'other';
|
|
androidBrowserHint.textContent = isChrome
|
|
? globalThis.Wegwichtel.I18n.t("bootstrap-loader.auf.diesem.gerat.kannst.du.bilder.und")
|
|
: globalThis.Wegwichtel.I18n.t("bootstrap-loader.tipp.fur.android.mit.chrome.lassen.sich");
|
|
}
|
|
|
|
function schedule(callback, delay = 0) {
|
|
if (typeof globalThis.setTimeout === 'function') {
|
|
return globalThis.setTimeout(callback, delay);
|
|
}
|
|
callback();
|
|
return null;
|
|
}
|
|
|
|
function setStatusText(text, immediate = false) {
|
|
if (!statusText) return;
|
|
statusTransition += 1;
|
|
const transition = statusTransition;
|
|
if (immediate) {
|
|
statusText.textContent = text;
|
|
statusText.classList.remove('is-fading');
|
|
return;
|
|
}
|
|
statusText.classList.add('is-fading');
|
|
schedule(() => {
|
|
if (transition !== statusTransition) return;
|
|
statusText.textContent = text;
|
|
statusText.classList.remove('is-fading');
|
|
}, 180);
|
|
}
|
|
|
|
function nextPendingStep() {
|
|
return steps.find(step => !completedSteps.has(step));
|
|
}
|
|
|
|
function announceStep(step) {
|
|
if (stepLabels[step]) setStatusText(stepLabels[step]);
|
|
}
|
|
|
|
function mark(step, state) {
|
|
if (!steps.includes(step)) return;
|
|
|
|
const item = document.querySelector(`[data-step="${step}"]`);
|
|
item?.classList?.remove('done', 'failed');
|
|
|
|
if (state === 'done') completedSteps.add(step);
|
|
else completedSteps.delete(step);
|
|
|
|
item?.classList?.add(state);
|
|
if (progress) progress.value = completedSteps.size;
|
|
|
|
if (state === 'failed') {
|
|
setStatusText(globalThis.Wegwichtel.I18n.t("bootstrap.step.failed", { value1: stepLabels[step] || step }));
|
|
return;
|
|
}
|
|
if (state === 'done') {
|
|
const next = nextPendingStep();
|
|
if (next) announceStep(next);
|
|
}
|
|
}
|
|
|
|
function loadScript(src, test) {
|
|
return new Promise((resolve, reject) => {
|
|
const script = document.createElement('script');
|
|
script.src = versioned(src);
|
|
script.async = false;
|
|
script.onload = () => {
|
|
if (test && !test()) reject(new Error(globalThis.Wegwichtel.I18n.t("bootstrap-loader.ein.teil.der.app.konnte.nicht.starten")));
|
|
else resolve();
|
|
};
|
|
script.onerror = () => reject(new Error(globalThis.Wegwichtel.I18n.t("bootstrap-loader.ein.teil.der.app.konnte.nicht.geladen")));
|
|
document.head.appendChild(script);
|
|
});
|
|
}
|
|
|
|
function initializeJqueryUi() {
|
|
const $ = globalThis.jQuery;
|
|
$('#bootstrap-retry').button({ icon: 'ui-icon-refresh' });
|
|
$('#bootstrap-enter').button();
|
|
$('.back-button').button();
|
|
$('#clear-route-search').button({ icon: 'ui-icon-close', showLabel: false });
|
|
$('#slide-prev').button();
|
|
$('#slide-next').button();
|
|
}
|
|
|
|
function updateCleanupProgress(removed, total) {
|
|
cleanupStatus.textContent = globalThis.Wegwichtel.I18n.t("bootstrap-loader.alten.fortschritt.loschen", { value1: removed, value2: total });
|
|
cleanupStatus.hidden = false;
|
|
}
|
|
|
|
async function cleanupOldProgress() {
|
|
cleanupStatus.hidden = true;
|
|
await globalThis.Wegwichtel.PrivacyStorage.cleanupExpired(updateCleanupProgress);
|
|
}
|
|
|
|
function isActivation(event) {
|
|
if (event.type === 'keydown') return event.key === 'Enter' || event.key === ' ';
|
|
if (event.type !== 'pointerup') return false;
|
|
if (event.isPrimary === false) return false;
|
|
return event.pointerType !== 'mouse' || event.button === 0;
|
|
}
|
|
|
|
function openApplication(event) {
|
|
if (!ready || globalThis.Wegwichtel.OfflineCache?.busy || !isActivation(event)) return;
|
|
if (event.target !== enter && event.target.closest('button, input, label, a, dialog')) return;
|
|
if (event.target.closest('.offline-help, .storage-usage')) return;
|
|
|
|
event.preventDefault();
|
|
event.stopPropagation?.();
|
|
screen.hidden = true;
|
|
document.getElementById('app-shell').hidden = false;
|
|
globalThis.Wegwichtel.App.navigate('#routes-page', { replace: true });
|
|
}
|
|
|
|
function showReadyState() {
|
|
ready = true;
|
|
screen.setAttribute('aria-busy', 'false');
|
|
screen.classList.add('ready');
|
|
readyText.hidden = false;
|
|
|
|
setStatusText(globalThis.Wegwichtel.I18n.t("bootstrap.ready"));
|
|
actionStatus?.classList.add('is-leaving');
|
|
enter.hidden = false;
|
|
const showEnter = () => enter.classList.add('is-visible');
|
|
if (typeof globalThis.requestAnimationFrame === 'function') {
|
|
globalThis.requestAnimationFrame(showEnter);
|
|
} else {
|
|
schedule(showEnter);
|
|
}
|
|
schedule(() => {
|
|
if (actionStatus) actionStatus.hidden = true;
|
|
}, 220);
|
|
enter.focus();
|
|
}
|
|
|
|
async function boot() {
|
|
ready = false;
|
|
completedSteps.clear();
|
|
if (progress) progress.value = 0;
|
|
screen.setAttribute('aria-busy', 'true');
|
|
screen.classList.remove('ready');
|
|
readyText.hidden = true;
|
|
enter.hidden = true;
|
|
enter.classList.remove('is-visible');
|
|
errorBox.hidden = true;
|
|
retry.hidden = true;
|
|
if (actionStatus) {
|
|
actionStatus.hidden = false;
|
|
actionStatus.classList.remove('is-leaving');
|
|
}
|
|
|
|
try {
|
|
await globalThis.Wegwichtel.OfflineCache?.initialize();
|
|
setStatusText(stepLabels.storage, true);
|
|
await cleanupOldProgress();
|
|
mark('storage', 'done');
|
|
|
|
await loadScript(
|
|
`vendor/jquery/jquery-${versions.jquery}.min.js`,
|
|
() => globalThis.jQuery?.fn?.jquery === versions.jquery
|
|
);
|
|
mark('jquery', 'done');
|
|
|
|
await loadScript(
|
|
`vendor/jquery-ui/jquery-ui-${versions.jqueryUi}.min.js`,
|
|
() => globalThis.jQuery?.ui?.version === versions.jqueryUi
|
|
);
|
|
initializeJqueryUi();
|
|
mark('jquery-ui', 'done');
|
|
|
|
for (const module of ['config', 'api-client', 'distance', 'geolocation', 'orientation', 'slideshow', 'audio-player', 'vibration', 'app']) {
|
|
await loadScript(`js/${module}.js`, () => Boolean(globalThis.Wegwichtel));
|
|
}
|
|
mark('modules', 'done');
|
|
|
|
await globalThis.Wegwichtel.App.initialize({ markStep: mark });
|
|
showReadyState();
|
|
} catch (error) {
|
|
console.error(error);
|
|
const current = nextPendingStep();
|
|
if (current) mark(current, 'failed');
|
|
errorBox.textContent = globalThis.Wegwichtel.UserMessages?.error(error, globalThis.Wegwichtel.I18n.t("bootstrap-loader.wegwichtel.konnte.nicht.starten.prufe.deine.verbindung")) || globalThis.Wegwichtel.I18n.t("bootstrap-loader.wegwichtel.konnte.nicht.starten.bitte.versuche.es");
|
|
errorBox.hidden = false;
|
|
retry.hidden = false;
|
|
}
|
|
}
|
|
|
|
function retryBoot(event) {
|
|
if (!isActivation(event)) return;
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
location.reload();
|
|
}
|
|
|
|
retry.addEventListener('pointerup', retryBoot);
|
|
retry.addEventListener('keydown', retryBoot);
|
|
enter.addEventListener('pointerup', openApplication);
|
|
enter.addEventListener('keydown', openApplication);
|
|
screen.addEventListener('pointerup', openApplication);
|
|
updateAndroidBrowserHint();
|
|
boot();
|
|
}());
|