Idle-Pause fuer Heli funktionsfaehig + iframe-aware Interaktionserfassung

- Interaktionen aus gleich-origin iFrames (Heli-Start/-Flug/-Landung) zaehlen jetzt
  (periodisches _hookFrame), plus postMessage {type:'ggs-activity'} + __GGS_LIVE__.ping().
  Aktives Steuern gilt nicht mehr faelschlich als idle.
- EVENTS erweitert (keyup/touchmove/pointermove). Heli in IDLE_PAUSE_SIMS aufgenommen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 12:50:30 +02:00
parent 7986bb2eb6
commit 0d765961af
+27 -2
View File
@@ -60,7 +60,7 @@
// Sichtbare Idle-Pause vorerst NUR dort, wo sie getestet ist. Sonst stört sie
// passive Phasen (z. B. die Heli-Flug-Animation, wo man minutenlang nur zuschaut).
// Freischalten pro App: Sim hier eintragen ODER window.GGS_IDLE_PAUSE=true setzen.
var IDLE_PAUSE_SIMS = ['klima', 'klima-3d'];
var IDLE_PAUSE_SIMS = ['klima', 'klima-3d', 'heli'];
var IDLE_PAUSE_ENABLED = IDLE_PAUSE_SIMS.indexOf(simId) !== -1 || window.GGS_IDLE_PAUSE === true;
var MAX_SESSION_MS = 7200000; // 120 min — Plattform-Hardcap
var TICK_MS = 1000; // Auflösung der activeMs-Akkumulation
@@ -76,11 +76,34 @@
lastInteractionAt = Date.now();
}
// Passive Listener, damit Scrollen/Touch nicht ausgebremst wird.
var EVENTS = ['mousemove', 'mousedown', 'keydown', 'touchstart', 'wheel', 'click', 'pointerdown'];
var EVENTS = ['mousemove', 'mousedown', 'keydown', 'keyup', 'touchstart', 'touchmove', 'wheel', 'click', 'pointerdown', 'pointermove'];
EVENTS.forEach(function (ev) {
window.addEventListener(ev, onInteraction, { passive: true, capture: true });
});
// Interaktionen auch aus (gleich-origin) iFrames erfassen — sonst gilt aktives
// Steuern in einem Sub-iFrame (z. B. Heli-Start/-Flug/-Landung) fälschlich als
// idle, obwohl die Schüler:in gerade lenkt. iFrames werden dynamisch geladen/
// getauscht → periodisch nachhängen. Cross-origin wirft → still ignorieren.
function _hookFrame(doc) {
if (!doc || doc.__ggsActivityHooked) return;
doc.__ggsActivityHooked = true;
EVENTS.forEach(function (ev) {
try { doc.addEventListener(ev, onInteraction, { passive: true, capture: true }); } catch (_) {}
});
}
function _scanFrames() {
var frames = document.getElementsByTagName('iframe');
for (var i = 0; i < frames.length; i++) {
try { _hookFrame(frames[i].contentDocument); } catch (_) { /* cross-origin */ }
}
}
setInterval(_scanFrames, 2500);
// Fallback: Sims/iFrames können aktives Arbeiten explizit signalisieren.
window.addEventListener('message', function (e) {
if (e && e.data && e.data.type === 'ggs-activity') onInteraction();
});
// Tick-Loop für activeMs-Akkumulation. Läuft auch wenn Sim nichts tut,
// hält die Buchhaltung sauber. Inkrementiert in Echtzeit-Schritten, deckt
// damit auch große Lücken (Tab-Sleep) korrekt ab.
@@ -129,6 +152,8 @@
get paused() { return paused; },
// Sim ruft dies bei Pause/Fortsetzen — friert die Aktivzeit-Buchhaltung ein.
setPaused: function (v) { paused = !!v; },
// Sim/iFrame kann aktives Arbeiten signalisieren (setzt den Idle-Zähler zurück).
ping: function () { onInteraction(); },
MAX_SESSION_MS: MAX_SESSION_MS,
IDLE_THRESHOLD_MS: IDLE_THRESHOLD_MS,
});