Fix: Offline-Pfote als schwebendes Element (Welten verstecken Header), SW by-v1079
Der Header (#app-header) ist in den Welten per 'display:none !important' ausgeblendet (Welten übernehmen Navigation). Mein Pfötchen saß da drin und war genau dort unsichtbar wo es sichtbar sein sollte. - Button aus dem Header rausgeholt, am Ende vom body als schwebendes Element platziert (position:fixed; top-right; z-index:9000) - Eigener Stil: 40px runder Glas-Hintergrund, blur-Effekt, leichter Schatten — passt zur FAB-Optik unten rechts - Dark-Mode Hintergrund: dunkles Glas - Sichtbar in allen Welten und auf allen Seiten (auch wo Header da ist — sitzt daneben) - 'hidden'-Default raus, Element ist sofort sichtbar (nur Färbung wartet auf refresh())
This commit is contained in:
parent
776641fa65
commit
06b91dc54b
6 changed files with 54 additions and 41 deletions
|
|
@ -410,7 +410,7 @@ async def serve_media(path: str, request: _Request):
|
|||
raise _HE(404, "Nicht gefunden.")
|
||||
return _media_response(filepath)
|
||||
|
||||
APP_VER = "1078" # muss mit APP_VER in app.js übereinstimmen
|
||||
APP_VER = "1079" # muss mit APP_VER in app.js übereinstimmen
|
||||
|
||||
@app.get("/.well-known/assetlinks.json")
|
||||
async def assetlinks():
|
||||
|
|
|
|||
|
|
@ -8867,9 +8867,36 @@ svg.empty-state-icon {
|
|||
}
|
||||
|
||||
/* ============================================================
|
||||
Offline-Bereitschafts-Indikator (Pfote im Header)
|
||||
Offline-Bereitschafts-Indikator — schwebend oben rechts
|
||||
5 Pfade — Score 0 (grau) bis 5 (grün, gefüllt)
|
||||
============================================================ */
|
||||
#offline-indicator {
|
||||
position: fixed;
|
||||
top: calc(env(safe-area-inset-top, 0px) + 8px);
|
||||
right: 12px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255,255,255,0.85);
|
||||
backdrop-filter: blur(6px);
|
||||
-webkit-backdrop-filter: blur(6px);
|
||||
border: 1px solid rgba(0,0,0,0.08);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
z-index: 9000; /* unter Modals (~9999), über allem anderen */
|
||||
transition: transform 0.12s, box-shadow 0.12s;
|
||||
}
|
||||
[data-theme="dark"] #offline-indicator {
|
||||
background: rgba(31,41,55,0.85);
|
||||
border-color: rgba(255,255,255,0.08);
|
||||
}
|
||||
#offline-indicator:active { transform: scale(0.92); }
|
||||
#offline-indicator .offline-paw { width: 24px; height: 24px; }
|
||||
|
||||
.offline-paw .paw-elem {
|
||||
color: var(--c-text-muted);
|
||||
transition: stroke 0.5s ease, fill 0.5s ease;
|
||||
|
|
@ -8878,14 +8905,6 @@ svg.empty-state-icon {
|
|||
color: var(--c-success);
|
||||
fill: var(--c-success);
|
||||
}
|
||||
#offline-indicator {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
#offline-indicator:hover .paw-elem {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.offline-status-row {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -101,9 +101,9 @@
|
|||
</script>
|
||||
|
||||
<!-- CSS: Reihenfolge ist wichtig — ?v= zwingt Browser zur Neuladung -->
|
||||
<link rel="stylesheet" href="/css/design-system.css?v=1078">
|
||||
<link rel="stylesheet" href="/css/layout.css?v=1078">
|
||||
<link rel="stylesheet" href="/css/components.css?v=1078">
|
||||
<link rel="stylesheet" href="/css/design-system.css?v=1079">
|
||||
<link rel="stylesheet" href="/css/layout.css?v=1079">
|
||||
<link rel="stylesheet" href="/css/components.css?v=1079">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
|
@ -325,25 +325,6 @@
|
|||
<span class="header-title" id="header-title">Ban Yaro</span>
|
||||
</div>
|
||||
<div id="header-actions"></div>
|
||||
<button id="offline-indicator" class="header-menu-btn hidden"
|
||||
aria-label="Offline-Bereitschaft" title="Offline-Bereitschaft"
|
||||
style="position:relative;padding:0 6px">
|
||||
<svg class="ph-icon offline-paw" viewBox="0 0 256 256" aria-hidden="true"
|
||||
style="width:22px;height:22px">
|
||||
<!-- 4 Zehen + 1 Ballen, jeweils mit data-step für Reihenfolge -->
|
||||
<path class="paw-elem" data-step="1"
|
||||
d="M128,104A36,36,0,0,0,93.43,130a43.49,43.49,0,0,1-20.67,25.9,32,32,0,0,0,27.73,57.62,72.49,72.49,0,0,1,55,0,32,32,0,0,0,27.73-57.62A43.46,43.46,0,0,1,162.57,130,36,36,0,0,0,128,104Z"
|
||||
fill="none" stroke="currentColor" stroke-width="16" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle class="paw-elem" data-step="2" cx="44" cy="108" r="20"
|
||||
fill="none" stroke="currentColor" stroke-width="16"/>
|
||||
<circle class="paw-elem" data-step="3" cx="92" cy="60" r="20"
|
||||
fill="none" stroke="currentColor" stroke-width="16"/>
|
||||
<circle class="paw-elem" data-step="4" cx="164" cy="60" r="20"
|
||||
fill="none" stroke="currentColor" stroke-width="16"/>
|
||||
<circle class="paw-elem" data-step="5" cx="212" cy="108" r="20"
|
||||
fill="none" stroke="currentColor" stroke-width="16"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="header-user-btn" aria-label="Profil"
|
||||
style="width:36px;height:36px;border-radius:50%;border:2px solid var(--c-border);
|
||||
background:var(--c-surface-2);cursor:pointer;flex-shrink:0;
|
||||
|
|
@ -628,6 +609,20 @@
|
|||
<svg class="ph-icon" style="width:22px;height:22px"><use href="/icons/phosphor.svg#arrow-left"></use></svg>
|
||||
</div>
|
||||
|
||||
<!-- OFFLINE-BEREITSCHAFTS-INDIKATOR — schwebend oben rechts, immer sichtbar -->
|
||||
<button id="offline-indicator"
|
||||
aria-label="Offline-Bereitschaft" title="Offline-Bereitschaft wird geprüft …">
|
||||
<svg class="offline-paw" viewBox="0 0 256 256" aria-hidden="true">
|
||||
<path class="paw-elem" data-step="1"
|
||||
d="M128,104A36,36,0,0,0,93.43,130a43.49,43.49,0,0,1-20.67,25.9,32,32,0,0,0,27.73,57.62,72.49,72.49,0,0,1,55,0,32,32,0,0,0,27.73-57.62A43.46,43.46,0,0,1,162.57,130,36,36,0,0,0,128,104Z"
|
||||
fill="none" stroke="currentColor" stroke-width="16" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle class="paw-elem" data-step="2" cx="44" cy="108" r="20" fill="none" stroke="currentColor" stroke-width="16"/>
|
||||
<circle class="paw-elem" data-step="3" cx="92" cy="60" r="20" fill="none" stroke="currentColor" stroke-width="16"/>
|
||||
<circle class="paw-elem" data-step="4" cx="164" cy="60" r="20" fill="none" stroke="currentColor" stroke-width="16"/>
|
||||
<circle class="paw-elem" data-step="5" cx="212" cy="108" r="20" fill="none" stroke="currentColor" stroke-width="16"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- TOAST CONTAINER (außerhalb der App, immer sichtbar) -->
|
||||
<div class="toast-container" id="toast-container" role="alert" aria-live="polite"></div>
|
||||
|
||||
|
|
@ -635,11 +630,11 @@
|
|||
<div id="modal-container"></div>
|
||||
|
||||
<!-- JS: Reihenfolge ist wichtig — erst Basis, dann Features -->
|
||||
<script src="/js/api.js?v=1078"></script>
|
||||
<script src="/js/ui.js?v=1078"></script>
|
||||
<script src="/js/app.js?v=1078"></script>
|
||||
<script src="/js/worlds.js?v=1078"></script>
|
||||
<script src="/js/offline-indicator.js?v=1078"></script>
|
||||
<script src="/js/api.js?v=1079"></script>
|
||||
<script src="/js/ui.js?v=1079"></script>
|
||||
<script src="/js/app.js?v=1079"></script>
|
||||
<script src="/js/worlds.js?v=1079"></script>
|
||||
<script src="/js/offline-indicator.js?v=1079"></script>
|
||||
|
||||
<!-- Feature-Seiten werden lazy geladen -->
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
Router, State-Management, Navigation, Initialisierung.
|
||||
============================================================ */
|
||||
|
||||
const APP_VER = '1078'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VER = '1079'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
|
||||
const IS_STAGING = location.hostname === 'staging.banyaro.app';
|
||||
// Cache-Bust-Parameter nach Update-Reload sofort entfernen.
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ window.OfflineIndicator = (() => {
|
|||
// ----------------------------------------------------------
|
||||
async function refresh() {
|
||||
if (!_btn) return;
|
||||
if (!('caches' in window)) { _btn.classList.add('hidden'); return; }
|
||||
if (!('caches' in window)) { _btn.style.display = 'none'; return; }
|
||||
|
||||
const results = await Promise.all(CHECKS.map(async c => {
|
||||
try { return { ...c, ok: await c.probe() }; }
|
||||
|
|
@ -93,7 +93,6 @@ window.OfflineIndicator = (() => {
|
|||
});
|
||||
_btn.title = `Offline-Bereitschaft: ${score} von 5`;
|
||||
_btn.setAttribute('aria-label', `Offline-Bereitschaft: ${score} von 5`);
|
||||
_btn.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
============================================================ */
|
||||
|
||||
// ← EINZIGE Stelle für die Version — STATIC_ASSETS und CACHE_VERSION leiten sich ab
|
||||
const VER = '1078';
|
||||
const VER = '1079';
|
||||
const CACHE_VERSION = `by-v${VER}`;
|
||||
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
||||
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue