This commit is contained in:
Vendored
+273
-83
@@ -1,14 +1,16 @@
|
||||
:root {
|
||||
--bootstrap-bg: #f3f7ee;
|
||||
--bootstrap-card-bg: #ffffff;
|
||||
--bootstrap-text: #1c2b20;
|
||||
--bootstrap-muted: #53605a;
|
||||
--bootstrap-accent: #315d3a;
|
||||
--bootstrap-accent-strong: #25462c;
|
||||
--bootstrap-border: #d6dfd3;
|
||||
--bootstrap-error: #8b1e1e;
|
||||
--bootstrap-shadow: 0 1rem 3rem rgb(29 52 36 / 18%);
|
||||
--bootstrap-text: #10291b;
|
||||
--bootstrap-muted: #67726c;
|
||||
--bootstrap-accent: #286438;
|
||||
--bootstrap-accent-strong: #194d2b;
|
||||
--bootstrap-border: #dce6dc;
|
||||
--bootstrap-error: #a32020;
|
||||
--bootstrap-shadow: 0 1.2rem 3.6rem rgb(29 52 36 / 16%);
|
||||
--bootstrap-fade-duration: 180ms;
|
||||
}
|
||||
|
||||
#bootstrap-screen {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
@@ -18,7 +20,7 @@
|
||||
justify-items: center;
|
||||
min-height: 100svh;
|
||||
box-sizing: border-box;
|
||||
padding: max(1rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(1rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));
|
||||
padding: max(5.25rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(1rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior-y: contain;
|
||||
@@ -26,127 +28,315 @@
|
||||
-webkit-overflow-scrolling: touch;
|
||||
color: var(--bootstrap-text);
|
||||
background:
|
||||
radial-gradient(circle at 20% 10%, rgb(135 185 112 / 32%), transparent 34rem),
|
||||
radial-gradient(circle at 85% 90%, rgb(230 198 116 / 25%), transparent 28rem),
|
||||
var(--bootstrap-bg);
|
||||
radial-gradient(circle at 12% 6%, rgb(126 183 101 / 24%), transparent 27rem),
|
||||
radial-gradient(circle at 88% 94%, rgb(235 196 104 / 18%), transparent 25rem),
|
||||
linear-gradient(180deg, #f7faf4 0%, var(--bootstrap-bg) 100%);
|
||||
}
|
||||
|
||||
#bootstrap-screen[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#bootstrap-screen > section {
|
||||
width: min(100%, 34rem);
|
||||
width: min(100%, 42rem);
|
||||
box-sizing: border-box;
|
||||
padding: clamp(1.25rem, 5vw, 2rem);
|
||||
border: 1px solid var(--bootstrap-border);
|
||||
border-radius: 1.5rem;
|
||||
padding: clamp(1.1rem, 4vw, 1.8rem);
|
||||
border: 1px solid rgb(214 224 214 / 80%);
|
||||
border-radius: clamp(1.4rem, 5vw, 2rem);
|
||||
box-shadow: var(--bootstrap-shadow);
|
||||
background: var(--bootstrap-card-bg);
|
||||
background: rgb(255 255 255 / 96%);
|
||||
}
|
||||
|
||||
#bootstrap-screen [aria-hidden="true"] {
|
||||
display: inline-block;
|
||||
margin-bottom: .25rem;
|
||||
font-size: 2rem;
|
||||
.bootstrap-brand {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.bootstrap-logo {
|
||||
width: clamp(4.25rem, 15vw, 5.75rem);
|
||||
height: auto;
|
||||
filter: drop-shadow(0 .35rem .6rem rgb(49 93 58 / 12%));
|
||||
}
|
||||
|
||||
#bootstrap-screen h1 {
|
||||
margin: 0 0 .5rem;
|
||||
font-size: clamp(1.8rem, 8vw, 2.5rem);
|
||||
line-height: 1.05;
|
||||
margin: 0 0 .3rem;
|
||||
color: #0d2b1b;
|
||||
font-size: clamp(2rem, 8vw, 3rem);
|
||||
line-height: 1;
|
||||
letter-spacing: -.035em;
|
||||
}
|
||||
|
||||
#bootstrap-screen p {
|
||||
margin: .65rem 0;
|
||||
#bootstrap-screen .bootstrap-brand p {
|
||||
margin: 0;
|
||||
color: var(--bootstrap-muted);
|
||||
font-size: clamp(.98rem, 3.8vw, 1.18rem);
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.bootstrap-hero {
|
||||
overflow: hidden;
|
||||
margin: .35rem 0 1rem;
|
||||
border-radius: 1.5rem;
|
||||
background: #eef7f1;
|
||||
}
|
||||
|
||||
.bootstrap-hero svg {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: 16rem;
|
||||
}
|
||||
|
||||
.bootstrap-action-slot {
|
||||
display: grid;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.bootstrap-action-slot > * {
|
||||
grid-area: 1 / 1;
|
||||
}
|
||||
|
||||
.bootstrap-action-status,
|
||||
#bootstrap-enter.ui-button,
|
||||
.bootstrap-enter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
min-height: 4rem;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: .8rem 1.25rem;
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
font: inherit;
|
||||
font-size: clamp(1.05rem, 4.4vw, 1.28rem);
|
||||
font-weight: 750;
|
||||
letter-spacing: .005em;
|
||||
}
|
||||
|
||||
.bootstrap-action-status {
|
||||
gap: .75rem;
|
||||
color: #eff8f0;
|
||||
background: linear-gradient(135deg, #387347, var(--bootstrap-accent));
|
||||
box-shadow: 0 .45rem 1.1rem rgb(40 100 56 / 18%);
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
transition: opacity var(--bootstrap-fade-duration) ease, transform var(--bootstrap-fade-duration) ease;
|
||||
}
|
||||
|
||||
.bootstrap-action-status.is-leaving {
|
||||
opacity: 0;
|
||||
transform: translateY(-.2rem);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.bootstrap-loading-dot {
|
||||
flex: 0 0 auto;
|
||||
width: .65rem;
|
||||
height: .65rem;
|
||||
border-radius: 50%;
|
||||
background: #d9f0de;
|
||||
box-shadow: 0 0 0 0 rgb(217 240 222 / 50%);
|
||||
animation: bootstrap-pulse 1.35s ease-out infinite;
|
||||
}
|
||||
|
||||
.bootstrap-status-text {
|
||||
opacity: 1;
|
||||
transition: opacity var(--bootstrap-fade-duration) ease;
|
||||
}
|
||||
|
||||
.bootstrap-status-text.is-fading {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#bootstrap-enter.ui-button,
|
||||
.bootstrap-enter {
|
||||
gap: .75rem;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #2d743d, var(--bootstrap-accent-strong));
|
||||
box-shadow: 0 .55rem 1.25rem rgb(25 77 43 / 24%);
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
transform: translateY(.2rem);
|
||||
transition: opacity var(--bootstrap-fade-duration) ease, transform var(--bootstrap-fade-duration) ease, background-color .15s ease;
|
||||
}
|
||||
|
||||
#bootstrap-enter.is-visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
#bootstrap-enter svg {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
margin-left: auto;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: 2.5;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
|
||||
#bootstrap-enter:hover,
|
||||
#bootstrap-enter:focus-visible {
|
||||
background: #173f24;
|
||||
}
|
||||
|
||||
.bootstrap-features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 0;
|
||||
margin: 1rem 0;
|
||||
padding: .8rem .4rem;
|
||||
border: 1px solid #e2ebe2;
|
||||
border-radius: 1.35rem;
|
||||
background: linear-gradient(135deg, #f4f9f4, #fbfcf8);
|
||||
}
|
||||
|
||||
.bootstrap-features > div {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
gap: .4rem;
|
||||
min-width: 0;
|
||||
padding: .3rem .45rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bootstrap-features > div + div {
|
||||
border-left: 1px solid #dce6dc;
|
||||
}
|
||||
|
||||
.bootstrap-features svg {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
fill: none;
|
||||
stroke: var(--bootstrap-accent);
|
||||
stroke-width: 2.2;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
|
||||
.bootstrap-features > div:nth-child(2) svg {
|
||||
stroke: #7351b4;
|
||||
}
|
||||
|
||||
.bootstrap-features > div:nth-child(3) svg {
|
||||
fill: #e96c2a;
|
||||
stroke: #e96c2a;
|
||||
}
|
||||
|
||||
.bootstrap-features span {
|
||||
color: #24402c;
|
||||
font-size: clamp(.78rem, 3vw, .95rem);
|
||||
font-weight: 650;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
#bootstrap-screen .privacy-summary {
|
||||
display: grid;
|
||||
gap: .75rem;
|
||||
margin: 1rem 0;
|
||||
gap: .65rem;
|
||||
margin: .85rem 0 0;
|
||||
padding: .85rem;
|
||||
border: 1px solid var(--bootstrap-border);
|
||||
border-radius: 1rem;
|
||||
border-radius: 1.15rem;
|
||||
background: #f9fbf6;
|
||||
}
|
||||
|
||||
#bootstrap-screen .privacy-summary > p {
|
||||
margin: 0;
|
||||
color: var(--bootstrap-muted);
|
||||
font-size: .92rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
#bootstrap-screen .privacy-summary > .switch-row.switch-disabled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#bootstrap-screen progress {
|
||||
width: 100%;
|
||||
height: .9rem;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
background: #dce7d8;
|
||||
}
|
||||
|
||||
#bootstrap-screen progress::-webkit-progress-bar {
|
||||
border-radius: 999px;
|
||||
background: #dce7d8;
|
||||
}
|
||||
|
||||
#bootstrap-screen progress::-webkit-progress-value {
|
||||
border-radius: 999px;
|
||||
background: var(--bootstrap-accent);
|
||||
}
|
||||
#bootstrap-screen progress::-moz-progress-bar {
|
||||
border-radius: 999px;
|
||||
background: var(--bootstrap-accent);
|
||||
}
|
||||
|
||||
#bootstrap-steps {
|
||||
display: grid;
|
||||
gap: .35rem;
|
||||
margin: 1rem 0;
|
||||
padding-left: 1.4rem;
|
||||
.storage-cleanup-status {
|
||||
min-height: 1.2rem;
|
||||
margin: .75rem 0 0;
|
||||
color: var(--bootstrap-muted);
|
||||
font-size: .86rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#bootstrap-steps li[data-state="done"] {
|
||||
color: var(--bootstrap-accent-strong);
|
||||
}
|
||||
|
||||
#bootstrap-steps li[data-state="active"] {
|
||||
font-weight: 700;
|
||||
color: var(--bootstrap-text);
|
||||
}
|
||||
|
||||
#bootstrap-error {
|
||||
.bootstrap-error {
|
||||
margin: .65rem 0 0;
|
||||
padding: .75rem .9rem;
|
||||
border-radius: .9rem;
|
||||
color: var(--bootstrap-error);
|
||||
background: #fff0f0;
|
||||
font-weight: 700;
|
||||
}
|
||||
#bootstrap-retry,
|
||||
#bootstrap-enter {
|
||||
|
||||
.bootstrap-retry,
|
||||
#bootstrap-retry.ui-button {
|
||||
width: 100%;
|
||||
min-height: 3rem;
|
||||
margin-top: .75rem;
|
||||
border: 0;
|
||||
box-sizing: border-box;
|
||||
margin-top: .65rem;
|
||||
border: 1px solid #d8abab;
|
||||
border-radius: 999px;
|
||||
color: #ffffff;
|
||||
background: var(--bootstrap-accent);
|
||||
color: #861d1d;
|
||||
background: #fff;
|
||||
font: inherit;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
#bootstrap-retry:hover,
|
||||
#bootstrap-enter:hover,
|
||||
#bootstrap-retry:focus-visible,
|
||||
#bootstrap-enter:focus-visible {
|
||||
background: var(--bootstrap-accent-strong);
|
||||
|
||||
.bootstrap-ready,
|
||||
.bootstrap-state-model {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.bootstrap-ready {
|
||||
font-weight: 700;
|
||||
color: var(--bootstrap-accent-strong);
|
||||
@keyframes bootstrap-pulse {
|
||||
0% { box-shadow: 0 0 0 0 rgb(217 240 222 / 55%); }
|
||||
65%, 100% { box-shadow: 0 0 0 .7rem rgb(217 240 222 / 0%); }
|
||||
}
|
||||
|
||||
.storage-cleanup-status {
|
||||
min-height: 1.25rem;
|
||||
font-size: .95rem;
|
||||
@media (max-width: 34rem) {
|
||||
#bootstrap-screen {
|
||||
padding-right: max(.75rem, env(safe-area-inset-right));
|
||||
padding-left: max(.75rem, env(safe-area-inset-left));
|
||||
}
|
||||
|
||||
#bootstrap-screen > section {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.bootstrap-brand {
|
||||
gap: .75rem;
|
||||
}
|
||||
|
||||
.bootstrap-hero svg {
|
||||
max-height: 12.5rem;
|
||||
}
|
||||
|
||||
.bootstrap-features {
|
||||
padding: .65rem .25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 700px) {
|
||||
.bootstrap-hero svg {
|
||||
max-height: 10rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.bootstrap-loading-dot {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.bootstrap-status-text,
|
||||
.bootstrap-action-status,
|
||||
#bootstrap-enter.ui-button,
|
||||
.bootstrap-enter {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
+74
-12
@@ -22,12 +22,77 @@
|
||||
</nav>
|
||||
</div>
|
||||
<div id="bootstrap-screen" aria-live="polite" aria-busy="true">
|
||||
<section>
|
||||
<span aria-hidden="true">🧭</span>
|
||||
<h1>Wegwichtel</h1>
|
||||
<p>Der Wegwichtel bereitet Routen und Medien vor.</p>
|
||||
<section class="bootstrap-card">
|
||||
<header class="bootstrap-brand">
|
||||
<svg class="bootstrap-logo" viewBox="0 0 96 96" aria-hidden="true" focusable="false">
|
||||
<circle cx="48" cy="48" r="39" fill="#fff7d7" stroke="#f4b400" stroke-width="6"/>
|
||||
<path d="M48 15 57 39 81 48 57 57 48 81 39 57 15 48 39 39Z" fill="#d9ddd8"/>
|
||||
<path d="m48 48 24-23-13 31Z" fill="#e53935"/>
|
||||
<path d="m48 48-24 23 13-31Z" fill="#2d9cdb"/>
|
||||
<circle cx="48" cy="48" r="6" fill="#f8fbf7" stroke="#315d3a" stroke-width="3"/>
|
||||
<circle cx="80" cy="16" r="8" fill="#fff" stroke="#f4b400" stroke-width="5"/>
|
||||
</svg>
|
||||
<div>
|
||||
<h1>Wegwichtel</h1>
|
||||
<p>Der Wegwichtel bereitet Routen und Medien vor.</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="bootstrap-hero" aria-hidden="true">
|
||||
<svg viewBox="0 0 720 300" preserveAspectRatio="xMidYMid slice" focusable="false">
|
||||
<rect width="720" height="300" rx="32" fill="#eef7f1"/>
|
||||
<circle cx="255" cy="68" r="27" fill="#ffd66b"/>
|
||||
<path d="M0 150C92 84 172 113 250 156c81 44 139-14 228-36 82-20 149 2 242 62v118H0Z" fill="#a9d4ca"/>
|
||||
<path d="M0 191c111-67 217-16 306 25 89 40 179-50 283-49 53 0 92 15 131 43v90H0Z" fill="#74aa62"/>
|
||||
<path d="M0 224c93-51 194-19 283 17 85 34 189-35 279-31 60 3 110 18 158 51v39H0Z" fill="#5e914e"/>
|
||||
<g fill="#477d49">
|
||||
<circle cx="75" cy="200" r="34"/><circle cx="118" cy="210" r="26"/><circle cx="610" cy="210" r="31"/><circle cx="654" cy="218" r="25"/>
|
||||
</g>
|
||||
<g fill="#607d8b" opacity=".9">
|
||||
<path d="M305 174h28v36h-28zM339 161h35v49h-35zM381 180h34v30h-34z"/>
|
||||
<path d="m350 160 8-24 8 24Z"/>
|
||||
</g>
|
||||
<path d="M250 300c34-52 88-69 137-74 53-5 113 5 153 22-65 9-127 29-155 52Z" fill="#f6dfb7"/>
|
||||
<g transform="translate(538 117)">
|
||||
<rect x="36" y="24" width="13" height="121" rx="6" fill="#7b5231"/>
|
||||
<path d="M0 17h105l25 21-25 21H0Z" fill="#f5a332"/>
|
||||
<path d="M14 65h91l22 19-22 19H14Z" fill="#4f914b"/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="bootstrap-action-slot">
|
||||
<output id="bootstrap-action-status" class="bootstrap-action-status" aria-live="polite">
|
||||
<span class="bootstrap-loading-dot" aria-hidden="true"></span>
|
||||
<span id="bootstrap-status-text" class="bootstrap-status-text">Wegwichtel wird vorbereitet …</span>
|
||||
</output>
|
||||
<button id="bootstrap-enter" class="bootstrap-enter" type="button" hidden>
|
||||
<span>Los geht’s</span>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="m9 5 7 7-7 7"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p id="bootstrap-error" class="bootstrap-error" hidden></p>
|
||||
<button id="bootstrap-retry" class="bootstrap-retry" type="button" hidden>Erneut versuchen</button>
|
||||
<p id="bootstrap-ready" class="bootstrap-ready" hidden>Alles ist bereit.</p>
|
||||
|
||||
<div class="bootstrap-features" aria-label="Wegwichtel Funktionen">
|
||||
<div>
|
||||
<svg viewBox="0 0 32 32" aria-hidden="true" focusable="false"><path d="m3 7 8-3 10 4 8-3v20l-8 3-10-4-8 3Zm8-3v20m10-16v20"/></svg>
|
||||
<span>Routen<br>entdecken</span>
|
||||
</div>
|
||||
<div>
|
||||
<svg viewBox="0 0 32 32" aria-hidden="true" focusable="false"><path d="M7 18v-4a9 9 0 0 1 18 0v4M7 18H4v7h5v-7Zm18 0h3v7h-5v-7Z"/></svg>
|
||||
<span>Spannende<br>Geschichten</span>
|
||||
</div>
|
||||
<div>
|
||||
<svg viewBox="0 0 32 32" aria-hidden="true" focusable="false"><path d="m16 3 3.9 8 8.8 1.3-6.4 6.2 1.5 8.8-7.8-4.1-7.8 4.1 1.5-8.8-6.4-6.2 8.8-1.3Z"/></svg>
|
||||
<span>Kindgerechte<br>Erlebnisse</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="privacy-summary">
|
||||
<p><strong>Cookies:</strong> Diese Anwendung setzt derzeit keine Cookies und verwendet weder Werbung noch Tracking.</p>
|
||||
<p><strong>Datenschutzfreundlich:</strong> Keine Werbung, kein Tracking und derzeit keine Cookies.</p>
|
||||
<label class="switch-row switch-disabled">
|
||||
<span>
|
||||
<strong>Optionale Cookies</strong>
|
||||
@@ -39,15 +104,16 @@
|
||||
<label class="switch-row">
|
||||
<span>
|
||||
<strong>Streckenfortschritt lokal speichern</strong>
|
||||
<small>Speichert ausgewählte Routen, besuchte und angesehene Stationen sowie abgespielte Audiodateien ausschließlich in diesem Browser.</small>
|
||||
<small>Speichert ausgewählte Routen und besuchte Stationen ausschließlich in diesem Browser.</small>
|
||||
</span>
|
||||
<input class="progress-storage-toggle" type="checkbox" role="switch" aria-checked="false">
|
||||
<span class="switch-track" aria-hidden="true"></span>
|
||||
</label>
|
||||
</div>
|
||||
<p id="storage-cleanup-status" class="storage-cleanup-status" hidden></p>
|
||||
<progress id="bootstrap-progress" max="6" value="0"></progress>
|
||||
<ol id="bootstrap-steps">
|
||||
|
||||
<progress id="bootstrap-progress" class="bootstrap-state-model" max="6" value="0" hidden></progress>
|
||||
<ol id="bootstrap-steps" class="bootstrap-state-model" hidden>
|
||||
<li data-step="jquery">jQuery laden</li>
|
||||
<li data-step="jquery-ui">jQuery UI laden</li>
|
||||
<li data-step="modules">Anwendungsmodule laden</li>
|
||||
@@ -55,10 +121,6 @@
|
||||
<li data-step="routes">Routen laden</li>
|
||||
<li data-step="location">Standort ermitteln</li>
|
||||
</ol>
|
||||
<p id="bootstrap-ready" class="bootstrap-ready" hidden>Alles ist bereit. Tippe oder klicke auf diese Startseite, um die Anwendung zu öffnen.</p>
|
||||
<p id="bootstrap-error" hidden></p>
|
||||
<button id="bootstrap-retry" type="button" hidden>Erneut versuchen</button>
|
||||
<button id="bootstrap-enter" type="button" hidden>Anwendung öffnen</button>
|
||||
</section>
|
||||
</div>
|
||||
<main id="app-shell" hidden>
|
||||
|
||||
Vendored
+61
-1
@@ -3,6 +3,14 @@
|
||||
|
||||
const versions = Object.freeze({ app: '0.12.14', jquery: '4.0.0', jqueryUi: '1.14.2' });
|
||||
const steps = ['jquery', 'jquery-ui', 'modules', 'server', 'routes', 'location'];
|
||||
const stepLabels = Object.freeze({
|
||||
jquery: 'jQuery laden …',
|
||||
'jquery-ui': 'jQuery UI laden …',
|
||||
modules: 'Anwendungsmodule laden …',
|
||||
server: 'Server prüfen …',
|
||||
routes: 'Routen laden …',
|
||||
location: 'Standort ermitteln …'
|
||||
});
|
||||
const screen = document.getElementById('bootstrap-screen');
|
||||
const progress = document.getElementById('bootstrap-progress');
|
||||
const errorBox = document.getElementById('bootstrap-error');
|
||||
@@ -10,16 +18,54 @@
|
||||
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');
|
||||
let ready = false;
|
||||
let statusTransition = 0;
|
||||
|
||||
const versioned = path => `${path}${path.includes('?') ? '&' : '?'}v=${encodeURIComponent(versions.app)}`;
|
||||
|
||||
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');
|
||||
globalThis.setTimeout(() => {
|
||||
if (transition !== statusTransition) return;
|
||||
statusText.textContent = text;
|
||||
statusText.classList.remove('is-fading');
|
||||
}, 180);
|
||||
}
|
||||
|
||||
function nextPendingStep() {
|
||||
return steps.find(step => !document.querySelector(`[data-step="${step}"]`)?.classList.contains('done'));
|
||||
}
|
||||
|
||||
function announceStep(step) {
|
||||
if (stepLabels[step]) setStatusText(stepLabels[step]);
|
||||
}
|
||||
|
||||
function mark(step, state) {
|
||||
const item = document.querySelector(`[data-step="${step}"]`);
|
||||
if (!item) return;
|
||||
item.classList.remove('done', 'failed');
|
||||
item.classList.add(state);
|
||||
item.dataset.state = state;
|
||||
progress.value = document.querySelectorAll('#bootstrap-steps .done').length;
|
||||
|
||||
if (state === 'failed') {
|
||||
setStatusText(`Fehler bei: ${stepLabels[step] || step}`);
|
||||
return;
|
||||
}
|
||||
if (state === 'done') {
|
||||
const next = nextPendingStep();
|
||||
if (next) announceStep(next);
|
||||
}
|
||||
}
|
||||
|
||||
function loadScript(src, test) {
|
||||
@@ -78,7 +124,14 @@
|
||||
screen.setAttribute('aria-busy', 'false');
|
||||
screen.classList.add('ready');
|
||||
readyText.hidden = false;
|
||||
|
||||
setStatusText('Vorbereitung abgeschlossen.');
|
||||
actionStatus?.classList.add('is-leaving');
|
||||
enter.hidden = false;
|
||||
globalThis.requestAnimationFrame(() => enter.classList.add('is-visible'));
|
||||
globalThis.setTimeout(() => {
|
||||
if (actionStatus) actionStatus.hidden = true;
|
||||
}, 220);
|
||||
enter.focus();
|
||||
}
|
||||
|
||||
@@ -88,11 +141,18 @@
|
||||
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 {
|
||||
setStatusText('Lokalen Speicher prüfen …', true);
|
||||
await cleanupOldProgress();
|
||||
announceStep('jquery');
|
||||
|
||||
await loadScript(
|
||||
`vendor/jquery/jquery-${versions.jquery}.min.js`,
|
||||
@@ -116,7 +176,7 @@
|
||||
showReadyState();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
const current = steps.find(step => !document.querySelector(`[data-step="${step}"]`)?.classList.contains('done'));
|
||||
const current = nextPendingStep();
|
||||
if (current) mark(current, 'failed');
|
||||
errorBox.textContent = error.message;
|
||||
errorBox.hidden = false;
|
||||
|
||||
Reference in New Issue
Block a user