596 lines
21 KiB
JavaScript
Executable File
596 lines
21 KiB
JavaScript
Executable File
document.addEventListener('DOMContentLoaded', () => {
|
|
const body = document.body;
|
|
const isLoggedIn = body.dataset.auth === '1';
|
|
const childGender = body.dataset.childGender || '';
|
|
const locationPreference = body.dataset.locationPreference || 'prompt';
|
|
const header = document.querySelector('.site-header');
|
|
const headerSentinel = document.getElementById('headerSentinel');
|
|
|
|
// Logo-Logik
|
|
const pickLogo = (gender) => {
|
|
if (gender === 'female') return 'logo_female.png';
|
|
if (gender === 'male') return 'logo_male.png';
|
|
return Math.random() < 0.5 ? 'logo_female.png' : 'logo_male.png';
|
|
};
|
|
const chosenLogo = pickLogo(childGender);
|
|
document.querySelectorAll('[data-logo-img]').forEach(img => {
|
|
img.src = `/assets/bilder/${chosenLogo}`;
|
|
});
|
|
|
|
// Header shrink via IntersectionObserver (no flicker around threshold)
|
|
if (header && headerSentinel && 'IntersectionObserver' in window) {
|
|
const observer = new IntersectionObserver(([entry]) => {
|
|
header.classList.toggle('is-scrolled', !entry.isIntersecting);
|
|
}, {
|
|
rootMargin: '-1px 0px 0px 0px',
|
|
threshold: 0,
|
|
});
|
|
observer.observe(headerSentinel);
|
|
} else if (header) {
|
|
// Fallback with simple threshold
|
|
const limit = 120;
|
|
const onScroll = () => header.classList.toggle('is-scrolled', window.scrollY > limit);
|
|
onScroll();
|
|
window.addEventListener('scroll', onScroll, { passive: true });
|
|
}
|
|
|
|
// Mobile Menü
|
|
const mobileMenu = document.getElementById('mobileMenu');
|
|
document.querySelectorAll('.menu-toggle').forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
mobileMenu?.classList.toggle('open');
|
|
});
|
|
});
|
|
|
|
// Scroll zu Events
|
|
const scrollBtn = document.getElementById('scrollToEvents');
|
|
if (scrollBtn) {
|
|
scrollBtn.addEventListener('click', () => {
|
|
document.getElementById('events')?.scrollIntoView({ behavior: 'smooth' });
|
|
});
|
|
}
|
|
|
|
// Events from backend (injected on page); fallback to empty
|
|
const events = Array.isArray(window.__events) ? window.__events : [];
|
|
const threads = Array.isArray(window.__threads) ? window.__threads : [];
|
|
const EVENTS_RADIUS_KM = 20;
|
|
const LOCATION_STORAGE_KEY = 'pkt_user_location';
|
|
const LOCATION_SESSION_STORAGE_KEY = 'pkt_user_location_session';
|
|
const LOCATION_SESSION_PREFERENCE_KEY = 'pkt_user_location_session_preference';
|
|
|
|
const el = {
|
|
sliderTrack: document.getElementById('eventSlider'),
|
|
sliderViewport: document.querySelector('.slider__viewport'),
|
|
sliderPrev: document.querySelector('[data-slider-prev]'),
|
|
sliderNext: document.querySelector('[data-slider-next]'),
|
|
threadSliderTrack: document.getElementById('threadSlider'),
|
|
threadSliderViewport: document.getElementById('threadSlider')?.closest('.slider__viewport') || null,
|
|
threadSliderPrev: document.querySelector('[data-thread-slider-prev]'),
|
|
threadSliderNext: document.querySelector('[data-thread-slider-next]'),
|
|
modal: document.getElementById('eventModal'),
|
|
modalBody: document.getElementById('eventModalBody'),
|
|
modalTitle: document.getElementById('eventModalTitle'),
|
|
quickForm: document.getElementById('quickSearchForm'),
|
|
quickLoc: document.getElementById('qsLoc'),
|
|
quickQuery: document.getElementById('qsQuery'),
|
|
quickLat: document.getElementById('qsLat'),
|
|
quickLng: document.getElementById('qsLng'),
|
|
quickGeo: document.getElementById('quickGeo'),
|
|
eventsSection: document.getElementById('events'),
|
|
locationPreferenceModal: document.getElementById('locationPreferenceModal'),
|
|
};
|
|
let effectiveLocationPreference = locationPreference;
|
|
|
|
const fmtDate = (iso) => {
|
|
const d = new Date(iso);
|
|
return d.toLocaleDateString('de-DE', { weekday: 'short', day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' });
|
|
};
|
|
|
|
const now = () => new Date();
|
|
|
|
const setCookie = (name, value, days = 30) => {
|
|
const expires = new Date(Date.now() + (days * 86400000)).toUTCString();
|
|
document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/; SameSite=Lax`;
|
|
};
|
|
|
|
const parseCookie = (name) => {
|
|
const prefix = `${name}=`;
|
|
return document.cookie
|
|
.split(';')
|
|
.map(item => item.trim())
|
|
.find(item => item.startsWith(prefix))
|
|
?.slice(prefix.length) || '';
|
|
};
|
|
|
|
const persistLocation = (location, mode = 'persistent') => {
|
|
if (!location || !Number.isFinite(location.lat) || !Number.isFinite(location.lng)) return;
|
|
const payload = {
|
|
lat: Number(location.lat.toFixed(6)),
|
|
lng: Number(location.lng.toFixed(6)),
|
|
label: location.label || 'Mein Standort',
|
|
savedAt: new Date().toISOString(),
|
|
};
|
|
if (mode === 'session') {
|
|
try {
|
|
window.sessionStorage.setItem(LOCATION_SESSION_STORAGE_KEY, JSON.stringify(payload));
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
} else {
|
|
try {
|
|
window.localStorage.setItem(LOCATION_STORAGE_KEY, JSON.stringify(payload));
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
setCookie('pkt_user_location', JSON.stringify(payload), 30);
|
|
}
|
|
if (el.quickLat) el.quickLat.value = payload.lat.toFixed(6);
|
|
if (el.quickLng) el.quickLng.value = payload.lng.toFixed(6);
|
|
if (el.quickLoc && (!el.quickLoc.value || el.quickLoc.value === 'Mein Standort')) {
|
|
el.quickLoc.value = payload.label;
|
|
}
|
|
};
|
|
|
|
const clearStoredLocation = () => {
|
|
try {
|
|
window.localStorage.removeItem(LOCATION_STORAGE_KEY);
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
try {
|
|
window.sessionStorage.removeItem(LOCATION_SESSION_STORAGE_KEY);
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
document.cookie = 'pkt_user_location=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; SameSite=Lax';
|
|
if (el.quickLat) el.quickLat.value = '';
|
|
if (el.quickLng) el.quickLng.value = '';
|
|
if (el.quickLoc) el.quickLoc.value = '';
|
|
};
|
|
|
|
const getStoredLocation = () => {
|
|
const candidates = [];
|
|
try {
|
|
const session = window.sessionStorage.getItem(LOCATION_SESSION_STORAGE_KEY);
|
|
if (session) candidates.push(session);
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
try {
|
|
const local = window.localStorage.getItem(LOCATION_STORAGE_KEY);
|
|
if (local) candidates.push(local);
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
const cookieValue = parseCookie('pkt_user_location');
|
|
if (cookieValue) candidates.push(decodeURIComponent(cookieValue));
|
|
|
|
for (const entry of candidates) {
|
|
try {
|
|
const parsed = JSON.parse(entry);
|
|
if (parsed && Number.isFinite(parsed.lat) && Number.isFinite(parsed.lng)) {
|
|
return {
|
|
lat: Number(parsed.lat),
|
|
lng: Number(parsed.lng),
|
|
label: parsed.label || 'Mein Standort',
|
|
};
|
|
}
|
|
} catch (err) {
|
|
// ignore invalid payloads
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const haversineKm = (lat1, lng1, lat2, lng2) => {
|
|
const toRad = (value) => value * Math.PI / 180;
|
|
const earthRadiusKm = 6371;
|
|
const dLat = toRad(lat2 - lat1);
|
|
const dLng = toRad(lng2 - lng1);
|
|
const a = Math.sin(dLat / 2) ** 2
|
|
+ Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLng / 2) ** 2;
|
|
return earthRadiusKm * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
};
|
|
|
|
const smallTag = (label) => `<span class="badge">${label}</span>`;
|
|
|
|
const getRankedEvents = (sourceEvents, location) => {
|
|
const normalized = sourceEvents.map(item => {
|
|
const startsAtDate = new Date(item.startsAt);
|
|
const isFuture = startsAtDate >= now();
|
|
const hasGeo = Number.isFinite(item.lat) && Number.isFinite(item.lng);
|
|
const distanceKm = (location && hasGeo)
|
|
? haversineKm(location.lat, location.lng, item.lat, item.lng)
|
|
: null;
|
|
|
|
return {
|
|
...item,
|
|
startsAtDate,
|
|
isFuture,
|
|
distanceKm,
|
|
};
|
|
});
|
|
|
|
if (!location) {
|
|
return normalized
|
|
.filter(item => item.isFuture)
|
|
.sort((a, b) => a.startsAtDate - b.startsAtDate)
|
|
.slice(0, 10);
|
|
}
|
|
|
|
const nearby = normalized.filter(item => item.distanceKm !== null && item.distanceKm <= EVENTS_RADIUS_KM);
|
|
const byDistanceThenDate = (a, b) => {
|
|
if (a.distanceKm !== b.distanceKm) return a.distanceKm - b.distanceKm;
|
|
return a.startsAtDate - b.startsAtDate;
|
|
};
|
|
|
|
const upcomingNearby = nearby
|
|
.filter(item => item.isFuture)
|
|
.sort(byDistanceThenDate);
|
|
|
|
if (upcomingNearby.length) {
|
|
return upcomingNearby.slice(0, 10);
|
|
}
|
|
|
|
const missedNearby = nearby
|
|
.filter(item => !item.isFuture)
|
|
.sort((a, b) => {
|
|
if (a.distanceKm !== b.distanceKm) return a.distanceKm - b.distanceKm;
|
|
return b.startsAtDate - a.startsAtDate;
|
|
})
|
|
.map(item => ({ ...item, missed: true }));
|
|
|
|
if (missedNearby.length) {
|
|
return missedNearby.slice(0, 10);
|
|
}
|
|
|
|
return normalized
|
|
.filter(item => item.isFuture)
|
|
.sort((a, b) => a.startsAtDate - b.startsAtDate)
|
|
.slice(0, 10);
|
|
};
|
|
|
|
const renderCard = (item) => {
|
|
const guest = !isLoggedIn;
|
|
const kids = item.allowKids ? 'Mit Kindern' : 'Ohne Kinder';
|
|
const distanceTag = Number.isFinite(item.distanceKm) ? smallTag(`${item.distanceKm.toFixed(1)} km`) : '';
|
|
const missedTag = item.missed ? smallTag('Das hast du verpasst') : '';
|
|
return `
|
|
<article class="card event-card-small">
|
|
<div class="muted small">${fmtDate(item.startsAt)}</div>
|
|
<h3>${item.title}</h3>
|
|
<p class="muted">${item.teaser}</p>
|
|
<div class="muted small">📍 ${item.city || item.region || ''}</div>
|
|
<div class="event__tags">${smallTag(kids)} ${item.visibility === 'public' ? smallTag('Öffentlich') : smallTag('Mitglieder')} ${distanceTag} ${missedTag}</div>
|
|
<div class="flex gap-8" style="margin-top:8px;">
|
|
<button class="btn ghost" data-event-detail="${item.id}">Details</button>
|
|
${guest || item.missed ? '' : '<button class="btn">Teilnehmen</button>'}
|
|
</div>
|
|
</article>`;
|
|
};
|
|
|
|
const renderSlider = (location = null) => {
|
|
if (!el.sliderTrack) return;
|
|
const rankedEvents = getRankedEvents(events, location);
|
|
if (!rankedEvents.length) {
|
|
el.sliderTrack.innerHTML = '<p class="muted">Keine Events vorhanden.</p>';
|
|
return;
|
|
}
|
|
el.sliderTrack.innerHTML = rankedEvents.map(renderCard).join('');
|
|
el.sliderTrack.querySelectorAll('[data-event-detail]').forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
const id = parseInt(btn.getAttribute('data-event-detail'), 10);
|
|
const ev = rankedEvents.find(e => e.id === id);
|
|
if (!ev || !el.modal || !el.modalBody || !el.modalTitle) return;
|
|
el.modalTitle.textContent = ev.title;
|
|
el.modalBody.innerHTML = `
|
|
<div class="muted small">${fmtDate(ev.startsAt)} · ${ev.region || ev.city || ''}</div>
|
|
<p class="muted">${ev.teaser}</p>
|
|
<p>${ev.description}</p>
|
|
${ev.locationLabel ? `<p><strong>Ort:</strong> ${ev.locationLabel}</p>` : ''}
|
|
${Number.isFinite(ev.distanceKm) ? `<p><strong>Entfernung:</strong> ${ev.distanceKm.toFixed(1)} km</p>` : ''}
|
|
${ev.missed ? '<p><strong>Hinweis:</strong> Das hast du verpasst.</p>' : ''}
|
|
<p><strong>Kinder:</strong> ${ev.allowKids ? 'Mit Kindern' : 'Ohne Kinder'}</p>
|
|
<p><strong>Sichtbarkeit:</strong> ${ev.visibility === 'public' ? 'Öffentlich' : 'Nur Mitglieder'}</p>
|
|
`;
|
|
el.modal.classList.add('open');
|
|
});
|
|
});
|
|
};
|
|
|
|
const renderThreadCard = (item) => {
|
|
const preview = item.body.length > 170 ? `${item.body.slice(0, 170)}…` : item.body;
|
|
return `
|
|
<article class="card thread-card-small">
|
|
<div class="muted small">${fmtDate(item.createdAt)}</div>
|
|
<h3>${item.title}</h3>
|
|
<p class="muted clamp-4">${preview}</p>
|
|
<div class="event__meta">
|
|
<span>${item.displayName}</span>
|
|
<span>Antworten: ${item.answers}</span>
|
|
</div>
|
|
<div class="flex gap-8" style="margin-top:8px;">
|
|
<a class="btn ghost" href="/community_thread?id=${item.id}">Beitrag öffnen</a>
|
|
</div>
|
|
</article>`;
|
|
};
|
|
|
|
const renderThreadSlider = () => {
|
|
if (!el.threadSliderTrack) return;
|
|
if (!threads.length) {
|
|
el.threadSliderTrack.innerHTML = '<p class="muted">Noch keine Community-Beiträge vorhanden.</p>';
|
|
return;
|
|
}
|
|
el.threadSliderTrack.innerHTML = threads.map(renderThreadCard).join('');
|
|
};
|
|
|
|
const scrollSlider = (viewport, dir) => {
|
|
if (!viewport) return;
|
|
const amount = dir === 'next' ? 320 : -320;
|
|
viewport.scrollBy({ left: amount, behavior: 'smooth' });
|
|
};
|
|
|
|
el.sliderPrev?.addEventListener('click', () => scrollSlider(el.sliderViewport, 'prev'));
|
|
el.sliderNext?.addEventListener('click', () => scrollSlider(el.sliderViewport, 'next'));
|
|
el.threadSliderPrev?.addEventListener('click', () => scrollSlider(el.threadSliderViewport, 'prev'));
|
|
el.threadSliderNext?.addEventListener('click', () => scrollSlider(el.threadSliderViewport, 'next'));
|
|
|
|
const applyStoredLocationToForm = () => {
|
|
const stored = getStoredLocation();
|
|
if (!stored) return null;
|
|
if (el.quickLat) el.quickLat.value = stored.lat.toFixed(6);
|
|
if (el.quickLng) el.quickLng.value = stored.lng.toFixed(6);
|
|
if (el.quickLoc && !el.quickLoc.value) el.quickLoc.value = stored.label || 'Mein Standort';
|
|
return stored;
|
|
};
|
|
|
|
const requestLocation = (options = {}) => new Promise((resolve) => {
|
|
if (!navigator.geolocation) {
|
|
resolve(null);
|
|
return;
|
|
}
|
|
navigator.geolocation.getCurrentPosition(
|
|
(pos) => {
|
|
const location = {
|
|
lat: pos.coords.latitude,
|
|
lng: pos.coords.longitude,
|
|
label: 'Mein Standort',
|
|
};
|
|
persistLocation(location, options.persistMode || 'persistent');
|
|
resolve(location);
|
|
},
|
|
() => resolve(null),
|
|
{
|
|
enableHighAccuracy: true,
|
|
timeout: options.timeout || 10000,
|
|
maximumAge: options.maximumAge || 300000,
|
|
}
|
|
);
|
|
});
|
|
|
|
const closeLocationPreferenceModal = () => {
|
|
el.locationPreferenceModal?.classList.remove('open');
|
|
};
|
|
|
|
document.querySelectorAll('[data-location-pref-close]').forEach(btn => {
|
|
btn.addEventListener('click', closeLocationPreferenceModal);
|
|
});
|
|
el.locationPreferenceModal?.addEventListener('click', (event) => {
|
|
if (event.target === el.locationPreferenceModal) {
|
|
closeLocationPreferenceModal();
|
|
}
|
|
});
|
|
|
|
const saveLocationPreference = async (preference) => {
|
|
effectiveLocationPreference = preference;
|
|
if (!isLoggedIn) {
|
|
try {
|
|
window.localStorage.setItem('pkt_location_preference_guest', preference);
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
const body = new URLSearchParams({ preference });
|
|
const response = await fetch('/api/location-preference', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
},
|
|
body: body.toString(),
|
|
});
|
|
return response.ok;
|
|
} catch (err) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
const getSessionPreference = () => {
|
|
try {
|
|
return window.sessionStorage.getItem(LOCATION_SESSION_PREFERENCE_KEY);
|
|
} catch (err) {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
const setSessionPreference = (value) => {
|
|
try {
|
|
if (!value) {
|
|
window.sessionStorage.removeItem(LOCATION_SESSION_PREFERENCE_KEY);
|
|
} else {
|
|
window.sessionStorage.setItem(LOCATION_SESSION_PREFERENCE_KEY, value);
|
|
}
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
};
|
|
|
|
const resolvePromptChoice = () => new Promise((resolve) => {
|
|
if (!el.locationPreferenceModal) {
|
|
resolve('disabled');
|
|
return;
|
|
}
|
|
|
|
const buttons = el.locationPreferenceModal.querySelectorAll('[data-location-pref-choice]');
|
|
const cleanup = () => {
|
|
buttons.forEach(button => button.removeEventListener('click', handleClick));
|
|
document.removeEventListener('keydown', handleKeydown);
|
|
};
|
|
const finish = (value) => {
|
|
cleanup();
|
|
closeLocationPreferenceModal();
|
|
resolve(value);
|
|
};
|
|
const handleClick = (event) => {
|
|
const value = event.currentTarget.getAttribute('data-location-pref-choice') || 'disabled';
|
|
finish(value);
|
|
};
|
|
const handleKeydown = (event) => {
|
|
if (event.key === 'Escape') {
|
|
finish('disabled');
|
|
}
|
|
};
|
|
|
|
buttons.forEach(button => button.addEventListener('click', handleClick));
|
|
document.addEventListener('keydown', handleKeydown);
|
|
el.locationPreferenceModal.classList.add('open');
|
|
});
|
|
|
|
const ensureEventsLocation = async () => {
|
|
const sessionPreference = getSessionPreference();
|
|
if (effectiveLocationPreference === 'disabled') {
|
|
clearStoredLocation();
|
|
renderSlider(null);
|
|
return null;
|
|
}
|
|
|
|
const stored = applyStoredLocationToForm();
|
|
if (stored && effectiveLocationPreference !== 'enabled' && sessionPreference !== 'session') {
|
|
renderSlider(stored);
|
|
return stored;
|
|
}
|
|
|
|
if (effectiveLocationPreference === 'prompt') {
|
|
const choice = sessionPreference || await resolvePromptChoice();
|
|
if (choice === 'session') {
|
|
setSessionPreference('session');
|
|
const location = await requestLocation({ persistMode: 'session' });
|
|
renderSlider(location || stored);
|
|
return location;
|
|
}
|
|
if (choice === 'disabled') {
|
|
await saveLocationPreference('disabled');
|
|
clearStoredLocation();
|
|
renderSlider(null);
|
|
return null;
|
|
}
|
|
if (choice === 'enabled') {
|
|
await saveLocationPreference('enabled');
|
|
effectiveLocationPreference = 'enabled';
|
|
}
|
|
}
|
|
|
|
const location = await requestLocation({
|
|
persistMode: effectiveLocationPreference === 'enabled' ? 'persistent' : 'session',
|
|
});
|
|
renderSlider(location || stored);
|
|
return location;
|
|
};
|
|
|
|
// Quick search with geocoding
|
|
const geocode = async (query) => {
|
|
const url = 'https://nominatim.openstreetmap.org/search?format=jsonv2&limit=1&q=' + encodeURIComponent(query);
|
|
const res = await fetch(url, { headers: { 'Accept-Language': 'de', 'User-Agent': 'papa-kind-treff/1.0' } });
|
|
const data = await res.json();
|
|
if (Array.isArray(data) && data[0]) {
|
|
return { lat: parseFloat(data[0].lat), lng: parseFloat(data[0].lon) };
|
|
}
|
|
return null;
|
|
};
|
|
|
|
el.quickGeo?.addEventListener('click', () => {
|
|
if (!navigator.geolocation) {
|
|
alert('Geolocation wird nicht unterstützt.');
|
|
return;
|
|
}
|
|
navigator.geolocation.getCurrentPosition(
|
|
(pos) => {
|
|
persistLocation({
|
|
lat: pos.coords.latitude,
|
|
lng: pos.coords.longitude,
|
|
label: 'Mein Standort',
|
|
}, effectiveLocationPreference === 'enabled' ? 'persistent' : 'session');
|
|
renderSlider(getStoredLocation());
|
|
},
|
|
() => alert('Standort konnte nicht ermittelt werden.')
|
|
);
|
|
});
|
|
|
|
if (el.quickForm) {
|
|
el.quickForm.addEventListener('submit', async (e) => {
|
|
if (!el.quickLoc || !el.quickLat || !el.quickLng) return;
|
|
const hasCoords = el.quickLat.value && el.quickLng.value;
|
|
const locVal = (el.quickLoc.value || '').trim();
|
|
if (hasCoords || locVal === '') return;
|
|
e.preventDefault();
|
|
try {
|
|
const coords = await geocode(locVal);
|
|
if (coords) {
|
|
el.quickLat.value = coords.lat.toFixed(6);
|
|
el.quickLng.value = coords.lng.toFixed(6);
|
|
}
|
|
} catch (err) {
|
|
// ignore
|
|
} finally {
|
|
el.quickForm.submit();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Close modal
|
|
document.querySelectorAll('[data-event-modal-close]').forEach(btn => {
|
|
btn.addEventListener('click', () => el.modal?.classList.remove('open'));
|
|
});
|
|
el.modal?.addEventListener('click', (e) => { if (e.target === el.modal) el.modal.classList.remove('open'); });
|
|
|
|
document.querySelectorAll('[data-nav-events]').forEach(link => {
|
|
link.addEventListener('click', async () => {
|
|
if (window.location.pathname === '/' && window.location.hash === '#events') {
|
|
await ensureEventsLocation();
|
|
}
|
|
});
|
|
});
|
|
|
|
try {
|
|
if (!isLoggedIn) {
|
|
const guestPreference = window.localStorage.getItem('pkt_location_preference_guest');
|
|
if (guestPreference && ['disabled', 'prompt', 'enabled'].includes(guestPreference)) {
|
|
effectiveLocationPreference = guestPreference;
|
|
}
|
|
}
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
|
|
const initialLocation = effectiveLocationPreference === 'disabled' ? null : applyStoredLocationToForm();
|
|
if (effectiveLocationPreference === 'disabled') {
|
|
clearStoredLocation();
|
|
}
|
|
renderSlider(initialLocation);
|
|
renderThreadSlider();
|
|
|
|
if (effectiveLocationPreference === 'enabled' && window.location.pathname === '/') {
|
|
ensureEventsLocation();
|
|
} else if (window.location.hash === '#events' || window.location.hash === '#quicksearch') {
|
|
ensureEventsLocation();
|
|
}
|
|
|
|
window.addEventListener('hashchange', () => {
|
|
if (window.location.hash === '#events' || window.location.hash === '#quicksearch') {
|
|
ensureEventsLocation();
|
|
}
|
|
});
|
|
});
|