From 7cf60a848fb540ee971263270062d8ced0db36a9 Mon Sep 17 00:00:00 2001 From: rene Date: Thu, 30 Apr 2026 16:43:16 +0200 Subject: [PATCH 1/3] =?UTF-8?q?Feature:=20Notizblock=20=E2=80=94=20Neue=20?= =?UTF-8?q?Notiz=20direkt=20erstellen=20mit=20Kategorie-Vorauswahl,=20SW?= =?UTF-8?q?=20by-v560?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/static/js/app.js | 2 +- backend/static/js/pages/notes.js | 108 ++++++++++++++++++++++++++++++- backend/static/sw.js | 2 +- 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/backend/static/js/app.js b/backend/static/js/app.js index 581a260..45724cb 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -3,7 +3,7 @@ Router, State-Management, Navigation, Initialisierung. ============================================================ */ -const APP_VER = '536'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '537'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.1.3'; // ← semantische Version, wird bei make release gesetzt const IS_STAGING = location.hostname === 'staging.banyaro.app'; diff --git a/backend/static/js/pages/notes.js b/backend/static/js/pages/notes.js index d9ce75d..d78797d 100644 --- a/backend/static/js/pages/notes.js +++ b/backend/static/js/pages/notes.js @@ -136,7 +136,13 @@ window.Page_notes = (() => {

Notizblock

- ${_notes.length} Notiz${_notes.length !== 1 ? 'en' : ''} +
+ ${_notes.length} Notiz${_notes.length !== 1 ? 'en' : ''} + +
@@ -361,6 +367,11 @@ window.Page_notes = (() => { _container.querySelector('#notes-privacy-notice')?.remove(); }); + // Neue Notiz + _container.querySelector('#notes-new-btn')?.addEventListener('click', () => { + _openCreateModal(_filterType || ''); + }); + // Filter-Chips _container.querySelectorAll('.notes-chip').forEach(btn => { btn.addEventListener('click', () => { @@ -464,6 +475,101 @@ window.Page_notes = (() => { _render(); } + // ---------------------------------------------------------- + // Create-Modal — neue Notiz mit vorausgewählter Kategorie + // ---------------------------------------------------------- + function _openCreateModal(preselectedType = '') { + const ERSTELL_RUBRIKEN = RUBRIKEN.filter(r => r.type !== ''); // ohne "Alle" + let _selType = preselectedType || ERSTELL_RUBRIKEN[0].type; + + const modalId = 'notes-create-modal'; + document.getElementById(modalId)?.remove(); + + const overlay = document.createElement('div'); + overlay.id = modalId; + overlay.style.cssText = `position:fixed;inset:0;z-index:9999;display:flex;align-items:flex-end;justify-content:center;background:rgba(0,0,0,0.45)`; + + const _buildContent = () => { + const rb = _rubrik(_selType); + return ` +
+
+

Neue Notiz

+ + +
+ +
+ ${ERSTELL_RUBRIKEN.map(r => ` + `).join('')} +
+
+ + +
+ + +
+ +
+ + +
+
`; + }; + + overlay.innerHTML = _buildContent(); + document.body.appendChild(overlay); + + const _rebind = () => { + overlay.querySelectorAll('.nc-cat').forEach(btn => { + btn.addEventListener('click', () => { + _selType = btn.dataset.type; + overlay.innerHTML = _buildContent(); + _rebind(); + overlay.querySelector('#nc-text')?.focus(); + }); + }); + + overlay.querySelector('#nc-cancel')?.addEventListener('click', () => overlay.remove()); + overlay.addEventListener('click', e => { if (e.target === overlay) overlay.remove(); }); + + overlay.querySelector('#nc-save')?.addEventListener('click', async () => { + const text = overlay.querySelector('#nc-text')?.value?.trim(); + if (!text) { UI.toast.warning('Bitte einen Text eingeben.'); return; } + const btn = overlay.querySelector('#nc-save'); + await UI.asyncButton(btn, async () => { + const rb = _rubrik(_selType); + await API.notes.create(_selType, 'standalone', { + text, + parent_label: rb.label, + }); + overlay.remove(); + _filterType = _selType; + await _reload(); + UI.toast.success('Notiz gespeichert.'); + }); + }); + + setTimeout(() => overlay.querySelector('#nc-text')?.focus(), 100); + }; + + _rebind(); + } + // ---------------------------------------------------------- // Edit-Modal (Bottom-Sheet Stil) // ---------------------------------------------------------- diff --git a/backend/static/sw.js b/backend/static/sw.js index ecb2350..aa968c2 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -3,7 +3,7 @@ Offline-Cache + Push Notifications + Tile-Cache ============================================================ */ -const CACHE_VERSION = 'by-v559'; +const CACHE_VERSION = 'by-v560'; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache From c657ac6ab8d14cb94dc524f2ebd1de2e1c8bc37d Mon Sep 17 00:00:00 2001 From: rene Date: Thu, 30 Apr 2026 16:48:37 +0200 Subject: [PATCH 2/3] =?UTF-8?q?Fix:=20Update-Check=20vergleicht=20Server-V?= =?UTF-8?q?ersion=20mit=20lokaler=20=E2=80=94=20l=C3=A4dt=20Seite=20neu=20?= =?UTF-8?q?wenn=20Update=20gefunden,=20SW=20by-v561?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/static/js/app.js | 2 +- backend/static/js/pages/settings.js | 19 ++++++++++++++++--- backend/static/sw.js | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/backend/static/js/app.js b/backend/static/js/app.js index 45724cb..3a6efda 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -3,7 +3,7 @@ Router, State-Management, Navigation, Initialisierung. ============================================================ */ -const APP_VER = '537'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '538'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.1.3'; // ← semantische Version, wird bei make release gesetzt const IS_STAGING = location.hostname === 'staging.banyaro.app'; diff --git a/backend/static/js/pages/settings.js b/backend/static/js/pages/settings.js index 37f67b5..9a6b596 100644 --- a/backend/static/js/pages/settings.js +++ b/backend/static/js/pages/settings.js @@ -604,14 +604,27 @@ window.Page_settings = (() => { } if (btn) btn.textContent = 'Prüfe…'; try { + // Aktuelle Version vom Server holen (no-cache) + const serverResp = await fetch('/js/app.js', { cache: 'no-store' }); + const serverText = await serverResp.text(); + const match = serverText.match(/APP_VERSION\s*=\s*'([^']+)'/); + const serverVersion = match?.[1] || null; + const localVersion = typeof APP_VERSION !== 'undefined' ? APP_VERSION : '0'; + + // SW update anstoßen const reg = await navigator.serviceWorker.getRegistration(); await reg?.update(); - if (reg?.waiting) { - // Neuer SW wartet — sofort aktivieren + + if (serverVersion && serverVersion !== localVersion) { + // Neuere Version verfügbar — Seite neu laden + if (reg?.waiting) reg.waiting.postMessage({ type: 'SKIP_WAITING' }); + UI.toast.info(`Update auf v${serverVersion} verfügbar — Seite wird neu geladen…`); + setTimeout(() => location.reload(), 1500); + } else if (reg?.waiting) { reg.waiting.postMessage({ type: 'SKIP_WAITING' }); UI.toast.success('Update wird installiert…'); } else { - UI.toast.success('Ban Yaro ist aktuell — v' + (typeof APP_VERSION !== 'undefined' ? APP_VERSION : '1.0.0') + '.'); + UI.toast.success(`Ban Yaro ist aktuell — v${localVersion}`); } } catch { UI.toast.error('Update-Prüfung fehlgeschlagen.'); diff --git a/backend/static/sw.js b/backend/static/sw.js index aa968c2..7a41a97 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -3,7 +3,7 @@ Offline-Cache + Push Notifications + Tile-Cache ============================================================ */ -const CACHE_VERSION = 'by-v560'; +const CACHE_VERSION = 'by-v561'; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache From f8861f39399fffe65a09361ac6515cc1707f6189 Mon Sep 17 00:00:00 2001 From: rene Date: Thu, 30 Apr 2026 16:54:03 +0200 Subject: [PATCH 3/3] =?UTF-8?q?Fix:=20SW=20skipWaiting()=20sofort=20beim?= =?UTF-8?q?=20Install=20=E2=80=94=20kein=20Warten=20auf=20Cache,=20Update?= =?UTF-8?q?=20greift=20sofort,=20SW=20by-v562?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/static/js/app.js | 2 +- backend/static/sw.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/static/js/app.js b/backend/static/js/app.js index 3a6efda..2476a00 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -3,7 +3,7 @@ Router, State-Management, Navigation, Initialisierung. ============================================================ */ -const APP_VER = '538'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '539'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.1.3'; // ← semantische Version, wird bei make release gesetzt const IS_STAGING = location.hostname === 'staging.banyaro.app'; diff --git a/backend/static/sw.js b/backend/static/sw.js index 7a41a97..b443693 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -3,7 +3,7 @@ Offline-Cache + Push Notifications + Tile-Cache ============================================================ */ -const CACHE_VERSION = 'by-v561'; +const CACHE_VERSION = 'by-v562'; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache @@ -134,13 +134,13 @@ function _isCacheableGet(pathname) { // INSTALL — App Shell cachen // ---------------------------------------------------------- self.addEventListener('install', event => { + self.skipWaiting(); // Sofort übernehmen — kein Warten auf Cache-Aufbau event.waitUntil( caches.open(CACHE_STATIC) .then(cache => cache.addAll(STATIC_ASSETS)) .then(() => caches.open(CACHE_API).then(c => fetch('/api/training/exercises').then(r => { if (r.ok) c.put('/api/training/exercises', r); }).catch(() => {}) )) - .then(() => self.skipWaiting()) ); });