Feature: Tagebuch Cover-Bild (Favorit-Funktion) für diary_media

- Migration: diary_media.is_cover (INTEGER DEFAULT 0)
- Upload: erstes Item eines Eintrags automatisch is_cover=1
- Neuer Endpoint: PATCH /diary/{id}/media/{mid}/cover
- GET-Endpoints geben is_cover + cover_url zurück
- Frontend: Stern-Button () in Gallery-Detail und Edit-Formular
- Timeline-Karte verwendet cover_url als Vorschaubild
- SW by-v212, APP_VER 186
This commit is contained in:
rene 2026-04-18 19:07:37 +02:00
parent 63ab092f5e
commit fa0fcbf8c9
7 changed files with 196 additions and 21 deletions

View file

@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
const APP_VER = '181'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VER = '186'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const App = (() => {
@ -420,7 +420,8 @@ const App = (() => {
}
_updateNotifBadge();
setInterval(_updateNotifBadge, 60_000);
_updateChatBadge();
setInterval(() => { _updateNotifBadge(); _updateChatBadge(); }, 30_000);
const pendingInvite = sessionStorage.getItem('pending_invite');
if (pendingInvite) {
@ -440,6 +441,18 @@ const App = (() => {
} catch { /* ignorieren */ }
}
async function _updateChatBadge() {
if (!state.user) return;
try {
const convs = await API.chat.conversations();
const total = convs.reduce((s, c) => s + (c.unread_count || 0), 0);
const badge = document.getElementById('chat-badge');
if (!badge) return;
badge.textContent = total;
badge.style.display = total > 0 ? '' : 'none';
} catch { /* ignorieren */ }
}
function _onLoggedOut() {
state.user = null;
state.dogs = [];