Navigation, Karten-FABs, Nearby-Alerts
- Bottom-Nav neu: Karte | Routen | + | Tagebuch | Forum - + reduziert auf: Giftköder, Gassi-Treffen, Verlorener Hund - Notification-Badge auf User-Avatar (Header) - Nearby-Alerts: Nav-Leiste pulsiert rot/orange bei Giftköder/vermisstm Hund in 20km - SW postMessage bei poison/lost_alert → sofortiger Alert-Check - Karten-FABs: nur Marker setzen + Standort (Route aufzeichnen + Offline entfernt) - SW by-v272, APP_VER 262
This commit is contained in:
parent
5141ba9969
commit
65d1cf6c7f
7 changed files with 105 additions and 27 deletions
|
|
@ -3,7 +3,7 @@
|
|||
Router, State-Management, Navigation, Initialisierung.
|
||||
============================================================ */
|
||||
|
||||
const APP_VER = '261'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VER = '262'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
|
||||
const App = (() => {
|
||||
|
||||
|
|
@ -361,17 +361,14 @@ const App = (() => {
|
|||
</button>`;
|
||||
|
||||
UI.modal.open({
|
||||
title: 'Was möchtest du hinzufügen?',
|
||||
title: 'Schnellmeldung',
|
||||
body: `
|
||||
<div class="flex flex-col gap-3">
|
||||
${authBtn('diary', 'btn-secondary', 'book-open', 'Tagebuch-Eintrag')}
|
||||
${authBtn('health', 'btn-secondary', 'syringe', 'Gesundheits-Eintrag')}
|
||||
${authBtn('chat', 'btn-secondary', 'chat-circle-dots','Neue Nachricht')}
|
||||
${authBtn('forum', 'btn-secondary', 'push-pin', 'Forenbeitrag erstellen')}
|
||||
<button class="btn btn-danger w-full" data-quick="poison">
|
||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#warning-octagon"></use></svg> Giftköder melden
|
||||
</button>
|
||||
${authBtn('walk', 'btn-nature', 'paw-print', 'Gassi-Treffen erstellen')}
|
||||
${authBtn('walk', 'btn-secondary', 'paw-print', 'Gassi-Treffen erstellen')}
|
||||
${authBtn('lost', 'btn-secondary', 'magnifying-glass','Verlorener Hund melden')}
|
||||
</div>
|
||||
${!loggedIn ? `<p style="font-size:var(--text-xs);color:var(--c-text-muted);text-align:center;margin-top:var(--space-3)">
|
||||
<svg class="ph-icon" style="width:12px;height:12px" aria-hidden="true"><use href="/icons/phosphor.svg#info"></use></svg>
|
||||
|
|
@ -391,12 +388,9 @@ const App = (() => {
|
|||
// Ohne Delay trifft es das neu geöffnete Modal und schließt es sofort.
|
||||
setTimeout(() => {
|
||||
if (action.startsWith('auth-')) { navigate('settings'); return; }
|
||||
if (action === 'diary') { navigate('diary'); pages['diary'].module?.openNew?.(); }
|
||||
if (action === 'health') { navigate('health'); pages['health'].module?.openNew?.(); }
|
||||
if (action === 'poison') { navigate('poison'); pages['poison'].module?.openNew?.(); }
|
||||
if (action === 'walk') { navigate('walks'); pages['walks'].module?.openNew?.(); }
|
||||
if (action === 'chat') { navigate('chat'); setTimeout(() => pages['chat'].module?._showNewMessagePicker?.(), 400); }
|
||||
if (action === 'forum') { navigate('forum'); setTimeout(() => pages['forum'].module?.openNew?.(), 400); }
|
||||
if (action === 'lost') { navigate('lost'); setTimeout(() => pages['lost'].module?.openNew?.(), 400); }
|
||||
}, 350);
|
||||
}, { once: true });
|
||||
}
|
||||
|
|
@ -434,11 +428,14 @@ const App = (() => {
|
|||
|
||||
_updateNotifBadge();
|
||||
_updateChatBadge();
|
||||
_checkNearbyAlerts();
|
||||
setInterval(() => { _updateNotifBadge(); _updateChatBadge(); }, 30_000);
|
||||
setInterval(_checkNearbyAlerts, 5 * 60_000);
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
_updateNotifBadge();
|
||||
_updateChatBadge();
|
||||
_checkNearbyAlerts();
|
||||
if (state.page === 'chat') {
|
||||
pages['chat']?.module?.refresh?.();
|
||||
}
|
||||
|
|
@ -452,6 +449,22 @@ const App = (() => {
|
|||
}
|
||||
}
|
||||
|
||||
async function _checkNearbyAlerts() {
|
||||
const nav = document.getElementById('bottom-nav');
|
||||
if (!nav) return;
|
||||
try {
|
||||
const pos = await new Promise((resolve, reject) =>
|
||||
navigator.geolocation.getCurrentPosition(resolve, reject, { timeout: 5000, maximumAge: 120_000 })
|
||||
);
|
||||
const { latitude: lat, longitude: lon } = pos.coords;
|
||||
const data = await API.get(`/alerts?lat=${lat}&lon=${lon}`);
|
||||
nav.classList.toggle('alert-poison', !!data.poison);
|
||||
nav.classList.toggle('alert-lost', !data.poison && !!data.lost);
|
||||
} catch {
|
||||
// Kein Standort verfügbar — kein Alert anzeigen
|
||||
}
|
||||
}
|
||||
|
||||
async function _updateNotifBadge() {
|
||||
if (!state.user) return;
|
||||
try {
|
||||
|
|
@ -820,7 +833,8 @@ const App = (() => {
|
|||
renderDogSwitcher: _renderDogSwitcher,
|
||||
getInstallPrompt: () => _installPrompt, requireAuth,
|
||||
showOnboarding: _showOnboardingModal,
|
||||
updateNotifBadge: _updateNotifBadge };
|
||||
updateNotifBadge: _updateNotifBadge,
|
||||
_checkNearbyAlerts };
|
||||
|
||||
})();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue