UX: Installationsanleitung mobile-first, alle Plattformen — SW by-v443, APP_VER 422
Alle 5 Fälle abgedeckt: Android+Prompt (Button), Android ohne Prompt (Chrome-Schritte), iOS Safari (Teilen-Menü), iOS non-Safari (Hinweis + Link kopieren), Desktop (Tabs Android/iOS). Steps mit Icon statt Zahl. Link-kopieren-Button für manuelle Fälle.
This commit is contained in:
parent
e62d94546b
commit
9cb4a16cc2
3 changed files with 102 additions and 25 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
Router, State-Management, Navigation, Initialisierung.
|
Router, State-Management, Navigation, Initialisierung.
|
||||||
============================================================ */
|
============================================================ */
|
||||||
|
|
||||||
const APP_VER = '421'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
const APP_VER = '422'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||||
|
|
||||||
const App = (() => {
|
const App = (() => {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -231,56 +231,112 @@ window.Page_welcome = (() => {
|
||||||
const isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;
|
const isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;
|
||||||
const isSafari = /^((?!chrome|android).)*safari/i.test(ua);
|
const isSafari = /^((?!chrome|android).)*safari/i.test(ua);
|
||||||
const isAndroid = /android/i.test(ua);
|
const isAndroid = /android/i.test(ua);
|
||||||
|
const isMobile = isIOS || isAndroid;
|
||||||
const hasPrompt = !!App.getInstallPrompt();
|
const hasPrompt = !!App.getInstallPrompt();
|
||||||
|
|
||||||
if ((isAndroid || hasPrompt) && hasPrompt) {
|
// Android: Browser hat Install-Prompt bereit (Chrome, Edge, Samsung Internet neu)
|
||||||
|
if (hasPrompt) {
|
||||||
return `
|
return `
|
||||||
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin:0 0 var(--space-3);line-height:1.5">
|
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin:0 0 var(--space-3);line-height:1.5">
|
||||||
Kein App Store nötig — direkt installieren.
|
Kein App Store nötig — direkt auf den Home-Bildschirm.
|
||||||
</p>
|
</p>
|
||||||
<button class="btn btn-primary" id="install-android-btn" style="width:100%">
|
<button class="btn btn-primary" id="install-android-btn" style="width:100%;margin-bottom:var(--space-2)">
|
||||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#download-simple"></use></svg>
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#download-simple"></use></svg>
|
||||||
Ban Yaro installieren
|
Ban Yaro installieren
|
||||||
</button>`;
|
</button>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// iOS Safari: Teilen-Menü
|
||||||
if (isIOS && isSafari) {
|
if (isIOS && isSafari) {
|
||||||
return `
|
return `
|
||||||
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin:0 0 var(--space-4);line-height:1.5">
|
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin:0 0 var(--space-4);line-height:1.5">
|
||||||
Auf iPhone/iPad installieren:
|
So kommt Ban Yaro auf deinen Home-Bildschirm:
|
||||||
</p>
|
</p>
|
||||||
${_steps([
|
${_steps([
|
||||||
['1', 'Teilen-Symbol <svg class="ph-icon" style="width:14px;height:14px;vertical-align:-2px"><use href="/icons/phosphor.svg#share"></use></svg> in Safari tippen'],
|
['share', 'Tippe unten in Safari auf das <strong>Teilen-Symbol</strong> <svg class="ph-icon" style="width:14px;height:14px;vertical-align:-2px"><use href="/icons/phosphor.svg#share"></use></svg>'],
|
||||||
['2', '<strong>„Zum Home-Bildschirm"</strong> wählen'],
|
['rows-plus-top', 'Wähle <strong>„Zum Home-Bildschirm"</strong> aus der Liste'],
|
||||||
['3', 'Rechts oben <strong>„Hinzufügen"</strong> tippen'],
|
['check', 'Tippe oben rechts auf <strong>„Hinzufügen"</strong>'],
|
||||||
])}
|
])}
|
||||||
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:var(--space-3) 0 0">
|
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:var(--space-4) 0 0">
|
||||||
Nur in Safari verfügbar, nicht in anderen Browsern.
|
Funktioniert nur in Safari — nicht in Chrome oder Firefox auf iOS.
|
||||||
</p>`;
|
</p>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// iOS, aber nicht Safari (Chrome, Firefox, etc.)
|
||||||
|
if (isIOS && !isSafari) {
|
||||||
|
return `
|
||||||
|
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin:0 0 var(--space-4);line-height:1.5">
|
||||||
|
Auf dem iPhone geht die Installation nur über <strong>Safari</strong>.
|
||||||
|
</p>
|
||||||
|
${_steps([
|
||||||
|
['safari-logo', 'Öffne <strong>Safari</strong> auf deinem iPhone'],
|
||||||
|
['arrow-square-in','Gib <strong>banyaro.app</strong> in die Adressleiste ein'],
|
||||||
|
['share', 'Tippe auf das Teilen-Symbol und wähle <strong>„Zum Home-Bildschirm"</strong>'],
|
||||||
|
])}
|
||||||
|
<button class="btn btn-ghost btn-sm" id="install-copy-btn"
|
||||||
|
style="margin-top:var(--space-3);width:100%">
|
||||||
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#copy"></use></svg>
|
||||||
|
Link kopieren
|
||||||
|
</button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Android ohne Prompt (Firefox, älterer Samsung Browser, etc.)
|
||||||
|
if (isAndroid) {
|
||||||
|
return `
|
||||||
|
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin:0 0 var(--space-4);line-height:1.5">
|
||||||
|
Am einfachsten geht es mit <strong>Chrome</strong>:
|
||||||
|
</p>
|
||||||
|
${_steps([
|
||||||
|
['arrow-square-in', 'Öffne <strong>banyaro.app</strong> in Chrome'],
|
||||||
|
['dots-three-circle','Tippe auf das <strong>Menü ⋮</strong> oben rechts'],
|
||||||
|
['download-simple', 'Wähle <strong>„App installieren"</strong> oder<br>„Zum Startbildschirm hinzufügen"'],
|
||||||
|
])}
|
||||||
|
<button class="btn btn-ghost btn-sm" id="install-copy-btn"
|
||||||
|
style="margin-top:var(--space-3);width:100%">
|
||||||
|
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#copy"></use></svg>
|
||||||
|
Link kopieren
|
||||||
|
</button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Desktop — beide Plattformen zeigen
|
||||||
return `
|
return `
|
||||||
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin:0 0 var(--space-4);line-height:1.5">
|
<div style="display:flex;gap:var(--space-2);margin-bottom:var(--space-4)">
|
||||||
In Chrome oder Edge installieren:
|
<button class="btn btn-sm" id="inst-tab-android"
|
||||||
</p>
|
style="flex:1;background:var(--c-primary);color:#fff;border:none">
|
||||||
${_steps([
|
Android
|
||||||
['1', 'Seite in <strong>Chrome</strong> oder <strong>Edge</strong> öffnen'],
|
</button>
|
||||||
['2', 'Installations-Symbol in der Adressleiste klicken'],
|
<button class="btn btn-sm btn-ghost" id="inst-tab-ios" style="flex:1">
|
||||||
['3', 'Bestätigen — fertig!'],
|
iPhone / iPad
|
||||||
])}`;
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="inst-panel-android">
|
||||||
|
${_steps([
|
||||||
|
['arrow-square-in', 'Öffne <strong>banyaro.app</strong> in Chrome oder Edge'],
|
||||||
|
['monitor', 'Klicke auf das <strong>Installations-Symbol</strong> in der Adressleiste'],
|
||||||
|
['check', 'Bestätigen — fertig!'],
|
||||||
|
])}
|
||||||
|
</div>
|
||||||
|
<div id="inst-panel-ios" style="display:none">
|
||||||
|
${_steps([
|
||||||
|
['arrow-square-in', 'Öffne <strong>banyaro.app</strong> in Safari auf dem iPhone'],
|
||||||
|
['share', 'Tippe auf das <strong>Teilen-Symbol</strong> <svg class="ph-icon" style="width:14px;height:14px;vertical-align:-2px"><use href="/icons/phosphor.svg#share"></use></svg>'],
|
||||||
|
['rows-plus-top', 'Wähle <strong>„Zum Home-Bildschirm"</strong> → <strong>„Hinzufügen"</strong>'],
|
||||||
|
])}
|
||||||
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _steps(list) {
|
function _steps(list) {
|
||||||
return `
|
return `
|
||||||
<ol style="margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:var(--space-3)">
|
<ol style="margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:var(--space-3)">
|
||||||
${list.map(([num, text]) => `
|
${list.map(([icon, text]) => `
|
||||||
<li style="display:flex;gap:var(--space-3);align-items:flex-start">
|
<li style="display:flex;gap:var(--space-3);align-items:flex-start">
|
||||||
<div style="width:24px;height:24px;border-radius:50%;flex-shrink:0;
|
<div style="width:32px;height:32px;border-radius:var(--radius-md);flex-shrink:0;
|
||||||
background:var(--c-primary);color:#fff;font-size:var(--text-xs);
|
background:var(--c-surface-2);display:flex;align-items:center;justify-content:center">
|
||||||
font-weight:var(--weight-bold);display:flex;align-items:center;justify-content:center">
|
<svg class="ph-icon" style="width:16px;height:16px;color:var(--c-primary)" aria-hidden="true">
|
||||||
${num}
|
<use href="/icons/phosphor.svg#${icon}"></use>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<span style="font-size:var(--text-sm);color:var(--c-text);line-height:1.5;padding-top:2px">${text}</span>
|
<span style="font-size:var(--text-sm);color:var(--c-text);line-height:1.5;padding-top:6px">${text}</span>
|
||||||
</li>
|
</li>
|
||||||
`).join('')}
|
`).join('')}
|
||||||
</ol>`;
|
</ol>`;
|
||||||
|
|
@ -301,6 +357,27 @@ window.Page_welcome = (() => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_container.querySelector('#install-copy-btn')?.addEventListener('click', async () => {
|
||||||
|
await navigator.clipboard.writeText('https://banyaro.app');
|
||||||
|
UI.toast.success('Link kopiert!');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Desktop-Tabs Android / iOS
|
||||||
|
_container.querySelector('#inst-tab-android')?.addEventListener('click', () => {
|
||||||
|
_container.querySelector('#inst-panel-android').style.display = '';
|
||||||
|
_container.querySelector('#inst-panel-ios').style.display = 'none';
|
||||||
|
_container.querySelector('#inst-tab-android').style.cssText += ';background:var(--c-primary);color:#fff;border:none';
|
||||||
|
_container.querySelector('#inst-tab-ios').className = 'btn btn-sm btn-ghost';
|
||||||
|
_container.querySelector('#inst-tab-ios').style.cssText = 'flex:1';
|
||||||
|
});
|
||||||
|
_container.querySelector('#inst-tab-ios')?.addEventListener('click', () => {
|
||||||
|
_container.querySelector('#inst-panel-android').style.display = 'none';
|
||||||
|
_container.querySelector('#inst-panel-ios').style.display = '';
|
||||||
|
_container.querySelector('#inst-tab-ios').style.cssText += ';background:var(--c-primary);color:#fff;border:none';
|
||||||
|
_container.querySelector('#inst-tab-android').className = 'btn btn-sm btn-ghost';
|
||||||
|
_container.querySelector('#inst-tab-android').style.cssText = 'flex:1';
|
||||||
|
});
|
||||||
|
|
||||||
_container.querySelector('#welcome-register-btn')?.addEventListener('click', () => App.navigate('settings'));
|
_container.querySelector('#welcome-register-btn')?.addEventListener('click', () => App.navigate('settings'));
|
||||||
_container.querySelector('#welcome-login-btn')?.addEventListener('click', () => App.navigate('settings'));
|
_container.querySelector('#welcome-login-btn')?.addEventListener('click', () => App.navigate('settings'));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
Offline-Cache + Push Notifications + Tile-Cache
|
Offline-Cache + Push Notifications + Tile-Cache
|
||||||
============================================================ */
|
============================================================ */
|
||||||
|
|
||||||
const CACHE_VERSION = 'by-v442';
|
const CACHE_VERSION = 'by-v443';
|
||||||
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
||||||
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
|
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue