Radio: http-Streams in nativen Hüllen abspielen lassen; Play-Session nicht mehr verlieren (SW v49)
All checks were successful
Build and push Docker image / build (push) Successful in 15s
Test / test (push) Successful in 1m34s

playStation() öffnet http-Sender auf einer https-Seite in einem neuen
Fenster. Native Hüllen (diora Android, diora desktop), die den Stream
selbst abspielen, setzen window.DIORA_PLAYS_HTTP_STREAMS und überspringen
das.

stopPlaySession() wurde von playStation() ohne await aufgerufen und
setzte currentPlayId erst nach dem fetch auf null – beim Senderwechsel
also die frisch gesetzte ID der neuen Session. Die ID wird jetzt vor dem
await übernommen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mrwnslz 2026-09-29 20:00:42 +02:00
parent 77d662a9cb
commit bca9d6b5e9
2 changed files with 10 additions and 5 deletions

View file

@ -157,7 +157,9 @@ function customPrompt(message, defaultValue = '') {
function playStation(url, name, stationId) { function playStation(url, name, stationId) {
stopPlayback(false); stopPlayback(false);
if (location.protocol === 'https:' && url.startsWith('http://')) { // A secure page can't load plain-http streams (mixed content). Native shells
// that play the stream themselves set window.DIORA_PLAYS_HTTP_STREAMS.
if (location.protocol === 'https:' && url.startsWith('http://') && !window.DIORA_PLAYS_HTTP_STREAMS) {
window.open(url, '_blank'); window.open(url, '_blank');
return; return;
} }
@ -280,15 +282,18 @@ async function startPlaySession(stationName, stationUrl) {
} }
async function stopPlaySession() { async function stopPlaySession() {
if (!currentPlayId) return; // Take the id before awaiting: playStation() calls this without waiting and
// starts the next session right away, whose id must not be cleared here.
const playId = currentPlayId;
if (!playId) return;
currentPlayId = null;
try { try {
await fetch('/radio/play/stop/', { await fetch('/radio/play/stop/', {
method: 'POST', method: 'POST',
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCsrfToken()}, headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCsrfToken()},
body: JSON.stringify({play_id: currentPlayId}) body: JSON.stringify({play_id: playId})
}); });
} catch (e) {} } catch (e) {}
currentPlayId = null;
} }
window.addEventListener('beforeunload', () => { window.addEventListener('beforeunload', () => {

View file

@ -2,7 +2,7 @@
* diora service worker — caches the app shell for offline use. * diora service worker — caches the app shell for offline use.
*/ */
const CACHE = 'diora-v48'; const CACHE = 'diora-v49';
const PODCAST_CACHE = 'diora-podcast-v1'; const PODCAST_CACHE = 'diora-podcast-v1';
const SHELL = [ const SHELL = [
'/static/css/app.css', '/static/css/app.css',