/* =================================================================== kalender-abo.js — den eigenen Kalender abonnierbar machen. Eine eigene Datei und nicht ein Anhängsel in kalender.js: Der Kalender selbst ist die größte Datei der Anwendung, und diese Sache hier hat mit dem Zeichnen von Monaten nichts zu tun. Fällt sie aus, steht der Kalender trotzdem. Der Link wird NICHT beim Öffnen der Seite angelegt. Ein Geheimnis, das entsteht, ohne dass jemand es wollte, liegt danach herum -- und niemand weiß, dass es existiert. Angelegt wird es beim Klick. =================================================================== */ (() => { 'use strict'; const $ = (id) => document.getElementById(id); if (!$('abo-block')) return; // Seite ohne diesen Block const melde = (t) => { $('abo-fehler').textContent = t || ''; }; async function hole(weg, einst) { const a = await fetch(weg, { credentials: 'same-origin', ...einst }); if (a.status === 401) { location.assign('/workspace/'); throw new Error('weg'); } return a; } function zeige(daten) { const hat = !!daten?.link; $('abo-hat').hidden = !hat; $('abo-hilfe').hidden = !hat; $('abo-erzeugen').hidden = hat; $('abo-neu').hidden = !hat; $('abo-aus').hidden = !hat; if (hat) $('abo-link').value = daten.link; /* WANN ZULETZT ABGEHOLT -- die einzige Auskunft, die wirklich sagt, ob die Sache funktioniert. "Link erzeugt" beweist nur, dass ein Link da ist; erst der Abruf beweist, dass ein Kalender ihn auch benutzt. Ohne diese Zeile sucht man bei "kommt nicht an" an der falschen Stelle. */ const stand = $('abo-stand'); if (!hat) { stand.textContent = ''; return; } if (!daten.zuletzt) { stand.textContent = 'Noch nie abgerufen – sobald dein Kalender ihn holt, steht es hier.'; stand.dataset.warten = 'ja'; return; } delete stand.dataset.warten; const d = new Date(daten.zuletzt); const her = Math.round((Date.now() - d.getTime()) / 60000); const wann = her < 2 ? 'gerade eben' : her < 60 ? `vor ${her} Minuten` : her < 60 * 48 ? `vor ${Math.round(her / 60)} Stunden` : `am ${d.toLocaleDateString('de-DE')}`; stand.textContent = `Dein Kalender hat die Termine zuletzt ${wann} abgeholt.`; } async function laden() { try { const a = await hole('/workspace/api/ics'); if (!a.ok) return; zeige(await a.json()); } catch { /* umgeleitet */ } } async function erzeugen(erneuern) { if (erneuern && !await frageNach({ titel: 'Neuen Link erzeugen?', was: 'Der alte hört im selben Moment auf zu funktionieren.', bleibt: 'Deine Termine selbst bleiben. Ein Kalender, der den alten Link ' + 'abonniert hat, bekommt aber keine mehr – bis du ihm den neuen gibst.', endgueltig: true, ja: 'Neuen Link erzeugen', })) return; melde(''); try { const a = await hole('/workspace/api/ics', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}', }); if (!a.ok) { melde('Ging gerade nicht. Bitte später noch einmal.'); return; } const d = await a.json(); zeige({ link: d.link, zuletzt: null }); /* Nach dem Erzeugen die Anleitung aufklappen -- wer gerade einen Link bekommen hat, will als Nächstes wissen, wohin damit. */ $('abo-hilfe').hidden = false; } catch { /* umgeleitet */ } } async function abschalten() { if (!await frageNach({ titel: 'Kalender-Link abschalten?', was: 'Deine Termine verschwinden aus jedem Kalender, der sie abonniert hat.', bleibt: 'Die Termine selbst bleiben hier im Workspace vollständig stehen. ' + 'Du kannst jederzeit einen neuen Link erzeugen.', ja: 'Abschalten', })) return; melde(''); try { const a = await hole('/workspace/api/ics', { method: 'DELETE' }); if (!a.ok) { melde('Ging gerade nicht.'); return; } zeige(null); } catch { /* umgeleitet */ } } async function kopieren() { const feld = $('abo-link'); const knopf = $('abo-kopieren'); try { await navigator.clipboard.writeText(feld.value); } catch { /* Ohne Zwischenablage-Recht (unsicherer Kontext, alter Browser) wenigstens markieren -- dann reicht Strg+C. Wortlos scheitern wäre das Schlechteste: Man klickt dreimal und weiß nicht, ob etwas passiert ist. */ feld.focus(); feld.select(); knopf.textContent = 'Jetzt Strg+C'; setTimeout(() => { knopf.textContent = 'Kopieren'; }, 3000); return; } knopf.textContent = 'Kopiert'; setTimeout(() => { knopf.textContent = 'Kopieren'; }, 2000); } $('abo-erzeugen').addEventListener('click', () => erzeugen(false)); $('abo-neu').addEventListener('click', () => erzeugen(true)); $('abo-aus').addEventListener('click', abschalten); $('abo-kopieren').addEventListener('click', kopieren); /* Erst laden, wenn jemand aufklappt -- die Seite hat beim Öffnen Wichtigeres zu tun, und die meisten klappen nie auf. */ $('abo-block').addEventListener('toggle', () => { if ($('abo-block').open) laden(); }, { once: true }); })();