diff --git a/admin.html b/admin.html index ca0dd56..cdcd48c 100644 --- a/admin.html +++ b/admin.html @@ -341,6 +341,8 @@
In Zoho Show: Datei → Freigeben/Veröffentlichen → Einbetten, Link hier einfügen.
+ + +Sprechernotizen (nur im Steuerpult sichtbar)
+Wie bei PowerPoint lässt sich pro Agenda-Punkt ein Notiz-Text hinterlegen (Admin-Panel → Agenda-Punkt bearbeiten → Feld „Notizen"). Ist ein Punkt mit Notizen live geschaltet, erscheint direkt unter der Kopfzeile im Steuerpult ein gelber Hinweiskasten mit dem Text — unabhängig davon, welcher Reiter (Agenda/Mitglieder/Besucher) gerade offen ist. Im Display-/Beamer-Fenster erscheinen diese Notizen zu keinem Zeitpunkt, das sieht nur die Person am Steuerpult.
+
@@ -1397,6 +1429,11 @@
/agenda.json
+ agendaCatalog: [], // { id, label, type: 'image'|'embed', imagePath?, embedUrl?, notes? } — geladen aus chapters//agenda.json
+ // notes: optionaler Freitext, nur im Steuerpult sichtbar (nie im Display/Beamer-View)
agendaOrder: [], // Reihenfolge von IDs (Katalog-Punkte + eingebaute Vorstellungsrunden), aktiv für dieses Meeting (wie meetingOrder)
agendaKnownIds: [], // IDs, die schon einmal automatisch in agendaOrder eingefügt wurden (verhindert, dass bewusst ausgeblendete Punkte zurückkehren)
currentAgendaItemId: null,
@@ -2945,10 +2983,32 @@ function renderControl() {
renderInvitedBySelect();
renderAdminPanel();
renderStammvertreterSection();
+ renderAgendaNotesPanel();
updateNextButton();
syncDot = document.getElementById('sync-dot');
}
+// Zeigt die Sprecher-Notizen des aktuell live geschalteten Agenda-Punkts im Steuerpult an —
+// unabhängig vom gerade gewählten linken Reiter (Agenda/Mitglieder/Besucher), damit die
+// Moderatorin die Notizen auch sieht, während sie z.B. die Mitglieder-Queue pflegt. Bewusst aus
+// renderControl() heraus aufgerufen (nicht nur aus showAgendaItem/closeAgendaItem), damit der
+// Zustand bei jeder State-Synchronisierung korrekt bleibt. renderDisplay() kennt dieses Element
+// nicht — Notizen erscheinen dadurch garantiert nie auf dem Display/Beamer.
+function renderAgendaNotesPanel() {
+ const panel = document.getElementById('agenda-notes-panel');
+ if (!panel) return;
+ const it = state.mode === 'agenda-item' ? getAgendaItem(state.currentAgendaItemId) : null;
+ const notes = it && it.notes ? it.notes.trim() : '';
+ if (!notes) {
+ panel.style.display = 'none';
+ panel.innerHTML = '';
+ return;
+ }
+ panel.className = 'agenda-notes-panel';
+ panel.style.display = 'block';
+ panel.innerHTML = `Notiz — ${escHtml(it.label || it.id)}${escHtml(notes)}`;
+}
+
function renderInvitedBySelect() {
const sel = document.getElementById('v-invited-by');
if (!sel) return;
@@ -3666,6 +3726,25 @@ function goNext() {
renderDisplay();
}
+// Klick-Ersatz für die Display-Seite (siehe #display-advance-btn): delegiert 1:1 an dieselbe
+// Weiter-Logik/Disabled-Prüfung wie der "Weiter"-Button im Steuerpult, keine zweite Zustandsquelle.
+// Ob "Weiter" gerade sinnvoll etwas tut. Bewusst auf `state` statt auf dem DOM-Element
+// #btn-next geprüft: #btn-next existiert zwar in beiden Fenstern (Steuerpult + Display sind
+// dasselbe Dokument), aber sein disabled-Attribut wird nur von updateNextButton() gepflegt,
+// und das läuft laut renderCurrentView() ausschließlich im Steuerpult-Kontext — im
+// Display-Fenster bliebe #btn-next.disabled sonst dauerhaft auf dem statischen HTML-Anfangswert
+// stehen. Einziger echter "nichts zu tun"-Fall (siehe updateNextButton() ~Zeile 3599): Meeting
+// noch nicht gestartet und keine Mitglieder in der Warteschlange.
+function canAdvance() {
+ const hasStarted = state.currentIndex >= 0 || state.mode === 'visitors' || state.mode !== 'members';
+ if (hasStarted) return true;
+ return state.meetingOrder.length > 0;
+}
+
+function displayAdvanceClick() {
+ if (canAdvance()) goNext();
+}
+
function resetMeeting() {
if (!confirm('Vorstellungsrunde neu starten? Der Fortschritt wird zurückgesetzt.')) return;
stopTimer();
@@ -4082,13 +4161,20 @@ function uid() {
// KEYBOARD SHORTCUTS
// ============================================================
document.addEventListener('keydown', (e) => {
- if (getView() !== 'control') return;
+ // Bewusst NICHT mehr auf getView()==='control' beschränkt: ein Präsentations-Klicker kann
+ // ArrowRight/Space senden, während der OS-Fokus auf dem Display-(Beamer)-Fenster liegt statt
+ // auf dem Steuerpult. #btn-next existiert als reales DOM-Element unabhängig davon, welche
+ // View gerade sichtbar ist. Funktioniert weiterhin nur, solange der Fokus auf unserer eigenen
+ // Seite liegt — sobald in eine eingebettete Zoho-Show-Folie geklickt wurde, verschluckt deren
+ // eigenes (fremdes) Dokument die Tastendrücke; das lässt sich aus Sicherheitsgründen
+ // (Cross-Origin-iframe) von hier aus nicht abfangen.
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
if (e.key === 'ArrowRight' || e.key === ' ') {
e.preventDefault();
- const btn = document.getElementById('btn-next');
- if (btn && !btn.disabled) goNext();
+ // canAdvance() statt #btn-next.disabled: dessen disabled-Attribut wird nur im
+ // Steuerpult-Kontext von updateNextButton() gepflegt (siehe canAdvance()-Kommentar).
+ if (canAdvance()) goNext();
}
});
diff --git a/version.json b/version.json
index bf71032..0c4b1a8 100644
--- a/version.json
+++ b/version.json
@@ -1,4 +1,4 @@
{
- "version": "2.0",
- "notes": "Agenda-Folien für Online-Meetings (Hybrid-Chapter): Bild- oder Live-Einbettungs-Folien frei in die Reihenfolge einsortieren, inkl. Mitglieder-/Besucher-Vorstellungsrunde und neuer Marketing-/Ergebnisrunde (ohne Timer). \"Weiter\" folgt jetzt der Agenda."
+ "version": "2.1",
+ "notes": "Agenda-Folien: Präsentations-Klicker funktioniert jetzt auch dann weiter, wenn der Fokus auf dem Display-(Beamer)-Fenster liegt statt im Steuerpult (Pfeiltaste rechts/Leertaste), zusätzlich ein dezenter Klick-Button unten rechts im Display. Außerdem: Sprechernotizen pro Agenda-Punkt, die nur im Steuerpult sichtbar sind, nie auf dem Display/Beamer."
}