diff --git a/App/php/api/live.php b/App/php/api/live.php index 9e262d6..eb9685e 100644 --- a/App/php/api/live.php +++ b/App/php/api/live.php @@ -347,21 +347,32 @@ if ($method === 'GET') { } elseif (isset($state['score']) && is_numeric($state['score'])) { $liveScore = max(0, min(100, (int)round($state['score']))); } + // Pausiert? (Idle-Pause-Overlay oder Sim-Pause). activeUntilMs = letzter + // Interaktionszeitpunkt → der Balken kann ab da halbhoch weitergezeichnet + // werden, solange die Pause läuft. + // Pausiert: Plattform-Idle-Pause, Sim-Pause ODER die Sim meldet phase=paused + // (z. B. Klima bei Geschwindigkeit 0). activeUntilMs = letzter Interaktions- + // zeitpunkt → ab da wird der Balken halbhoch weitergezeichnet. + $isPaused = !empty($state['__idlePaused']) || !empty($state['__paused']) + || (isset($state['phase']) && $state['phase'] === 'paused'); + $activeUntil = isset($state['__lastInteractionAt']) ? (int)$state['__lastInteractionAt'] : 0; $byStudent[$sid]['sessions'][] = [ - 'simId' => $simId, - 'simTitle' => $mi['title'] ?? $simId, - 'simIcon' => $mi['icon'] ?? '📚', - 'lessonKind' => $lessonKind, - 'lessonLabel' => $lessonLabel, - 'startMs' => $startMs, - 'endMs' => $endMs, - 'durationSec' => $durSec, - 'stars' => null, - 'score' => $liveScore, - 'completed' => null, - 'success' => 'running', - 'rowCount' => 1, - 'isLive' => true, + 'simId' => $simId, + 'simTitle' => $mi['title'] ?? $simId, + 'simIcon' => $mi['icon'] ?? '📚', + 'lessonKind' => $lessonKind, + 'lessonLabel' => $lessonLabel, + 'startMs' => $startMs, + 'endMs' => $endMs, + 'durationSec' => $durSec, + 'stars' => null, + 'score' => $liveScore, + 'completed' => null, + 'success' => 'running', + 'rowCount' => 1, + 'isLive' => true, + 'paused' => $isPaused, + 'activeUntilMs'=> ($activeUntil > $startMs && $activeUntil < $endMs) ? $activeUntil : 0, ]; $byStudent[$sid]['totalSec'] += $durSec; } diff --git a/App/teacher.html b/App/teacher.html index ddff25e..965d9d8 100644 --- a/App/teacher.html +++ b/App/teacher.html @@ -2230,7 +2230,12 @@ async function renderLiveSummary() { var realDurSec = _liveRealDurSec(sess); var endMs = sess.startMs + realDurSec * 1000; var pctL = _msToPct(sess.startMs); - var pctR = _msToPct(endMs); + // Pausierter Lauf: der Hauptbalken (volle Höhe) reicht nur bis zum Pausenbeginn, + // danach zeichnen wir einen halbhohen „Pausen-Schwanz" bis jetzt weiter. + var isPausedRun = (sess.isLive || sess.success === 'running') && sess.paused + && sess.activeUntilMs && sess.activeUntilMs > sess.startMs && sess.activeUntilMs < endMs; + var mainEndMs = isPausedRun ? sess.activeUntilMs : endMs; + var pctR = _msToPct(mainEndMs); var pctW = Math.max(0.8, pctR - pctL); // mindestens 0.8 % sichtbar var icon = sess.simIcon || '📚'; var simName = sess.simTitle || simWord(sess.simId); @@ -2246,9 +2251,10 @@ async function renderLiveSummary() { var border = aborted ? 'border:1.5px dashed rgba(255,255,255,.7);' : inProgress ? 'border:1.5px solid rgba(255,255,255,.7);border-right:2px dotted #fff;' : 'border:1.5px solid rgba(20,20,20,.25);'; - // Laufende Spiele: langsam blinkender Block (Balken wächst ohnehin mit der Zeit). - var anim = inProgress ? 'animation:_tagblink 1.8s ease-in-out infinite;' : ''; - var stateWord = inProgress ? 'läuft noch' : aborted ? 'abgebrochen' : 'fertig'; + // Laufende Spiele: langsam blinkender Block. Pausiert → Hauptbalken ruhig + // (der halbhohe Schwanz blinkt stattdessen). + var anim = (inProgress && !sess.paused) ? 'animation:_tagblink 1.8s ease-in-out infinite;' : ''; + var stateWord = !inProgress ? (aborted ? 'abgebrochen' : 'fertig') : (sess.paused ? 'pausiert ⏸' : 'läuft noch'); var tip = (sess.simTitle||sess.simId) + (sess.lessonLabel?' · '+sess.lessonLabel:'') + ' · ' + _fmtHM(sess.startMs) + '–' + _fmtHM(endMs) + ' · ' + _liveFmtMin(realDurSec) + ' · ' + stateWord @@ -2265,6 +2271,15 @@ async function renderLiveSummary() { + 'white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;' + 'text-shadow:0 1px 1px rgba(0,0,0,.3);box-shadow:0 1px 2px rgba(0,0,0,.12)">' + inner + ''; + // Pausen-Schwanz: halbhoch, gedämpft, blinkt langsam — „läuft noch, aber gerade ruhig". + if (isPausedRun) { + var halfH = 9; + var tailW = Math.max(0.6, _msToPct(endMs) - pctR); + html += '
'; + } if (aborted) { html += '✖'; @@ -2285,6 +2300,7 @@ async function renderLiveSummary() { + ' stark → schwach'; html += 'Symbol = Simulation · Klick = Details'; html += 'läuft noch'; + html += 'pausiert'; html += '✖ Abbruch'; html += '';