document.addEventListener('DOMContentLoaded', function () { // === Abschnitt: Globale Variablen === const presetContainer = document.getElementById('preset-container'); const newPresetForm = document.getElementById('new-preset-form'); const newPresetNameInput = document.getElementById('new-preset-name'); const newPresetUrlInput = document.getElementById('new-preset-url'); const exportButton = document.getElementById('export-button'); const importButton = document.getElementById('import-button'); const loadPresetsLink = document.getElementById('load-presets-link'); const stopButton = document.querySelector('.stop-button'); const currentStationName = document.getElementById('current-station-name'); let currentPlayingItem = null; // Speichert das aktuell spielende Element // === Abschnitt: Initialisierung === initializeFooter(); initializeEventListeners(); loadExistingPresets(); setupSortable(); // === Funktion: Footer dynamisch aktualisieren === function initializeFooter() { const currentYear = new Date().getFullYear(); const currentYearElement = document.getElementById('current-year'); if (currentYearElement) { currentYearElement.textContent = currentYear; } const serverName = window.location.hostname; const serverNameElement = document.getElementById('server-name'); if (serverNameElement) { serverNameElement.textContent = serverName; } } // === Funktion: Titel dynamisch ändern === function updateTitle(stationName) { if (stationName) { document.title = `${stationName} - Radioplayer mit Presets`; } else { document.title = "Radioplayer mit Presets"; } } // === Abschnitt: Event-Listener === function initializeEventListeners() { newPresetForm.addEventListener('submit', (event) => { event.preventDefault(); // Verhindert die Standardaktion (Seiten-Reload) const presetName = newPresetNameInput.value.trim(); const presetUrl = newPresetUrlInput.value.trim(); if (!presetName || !presetUrl) { alert("Bitte geben Sie einen Namen und eine URL ein."); return; } // URL-Validierung: Prüfen, ob die URL mit http:// oder https:// beginnt if (!isValidHttpUrl(presetUrl)) { alert("Bitte geben Sie eine gültige HTTP- oder HTTPS-URL ein."); return; } addNewPreset(presetName, presetUrl); savePresetToLocalStorage(presetName, presetUrl); // Felder zurücksetzen newPresetNameInput.value = ''; newPresetUrlInput.value = ''; }); // Hilfsfunktion zur Überprüfung von URLs function isValidHttpUrl(url) { try { const parsedUrl = new URL(url); return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:"; } catch (e) { return false; } } exportButton.addEventListener('click', exportPresets); importButton.addEventListener('click', importPresets); loadPresetsLink.addEventListener('click', loadPresetsFromFile); stopButton.addEventListener('click', stopPlayback); } // === Funktion: Preset-Handling === function loadExistingPresets() { const presets = JSON.parse(localStorage.getItem('presets')) || []; presets.forEach(preset => addNewPreset(preset.name, preset.url)); } function addNewPreset(name, url) { const presetItem = document.createElement('div'); presetItem.classList.add('preset-item'); presetItem.dataset.streamUrl = url; presetItem.innerHTML = `

${name}

`; presetItem.querySelector('.edit-button').addEventListener('click', (event) => { event.stopPropagation(); editPreset(presetItem, name, url); }); presetItem.querySelector('.delete-button').addEventListener('click', (event) => { event.stopPropagation(); deletePreset(presetItem); }); presetItem.addEventListener('click', () => playStream(url, presetItem)); presetContainer.appendChild(presetItem); } function editPreset(item, currentName, currentUrl) { const newName = prompt("Neuer Name:", currentName); const newUrl = prompt("Neue URL:", currentUrl); if (newName !== null && newUrl !== null) { item.querySelector('h3').textContent = newName; item.dataset.streamUrl = newUrl; savePresetOrder(); } } function deletePreset(item) { if (confirm("Möchten Sie diesen Sender wirklich löschen?")) { presetContainer.removeChild(item); savePresetOrder(); } } function savePresetToLocalStorage(name, url) { const presets = JSON.parse(localStorage.getItem('presets')) || []; presets.push({ name, url }); localStorage.setItem('presets', JSON.stringify(presets)); } function savePresetOrder() { const presetItems = Array.from(presetContainer.children); const presets = presetItems.map(item => ({ name: item.querySelector('h3').textContent, url: item.dataset.streamUrl })); localStorage.setItem('presets', JSON.stringify(presets)); } // === Funktion: Audio-Handling === function playStream(url, item) { if (currentPlayingItem) { const currentAudio = currentPlayingItem.querySelector('audio'); if (currentAudio) { currentAudio.pause(); currentAudio.remove(); } currentPlayingItem.classList.remove('playing'); } const audioElement = new Audio(url); audioElement.autoplay = true; audioElement.loop = true; audioElement.volume = 0.5; audioElement.onerror = () => alert('Fehler beim Laden des Streams: ' + url); item.appendChild(audioElement); item.classList.add('playing'); currentPlayingItem = item; currentStationName.textContent = item.querySelector('h3').textContent; updateTitle(item.querySelector('h3').textContent); // Sendername in den Titel einfügen } function stopPlayback() { if (currentPlayingItem) { const audioElement = currentPlayingItem.querySelector('audio'); if (audioElement) { audioElement.pause(); audioElement.currentTime = 0; currentPlayingItem.classList.remove('playing'); currentPlayingItem = null; currentStationName.textContent = 'Kein Sender ausgewählt.'; } } updateTitle(''); } // === Funktion: Preset-Import und -Export === function exportPresets() { const presets = JSON.parse(localStorage.getItem('presets')) || []; const json = JSON.stringify(presets, null, 2); const blob = new Blob([json], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'webradio_presets.json'; a.click(); URL.revokeObjectURL(url); } function importPresets() { const input = document.createElement('input'); input.type = 'file'; input.accept = '.json'; input.addEventListener('change', (event) => { const file = event.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = (e) => { try { const importedPresets = JSON.parse(e.target.result); if (Array.isArray(importedPresets)) { localStorage.setItem('presets', JSON.stringify(importedPresets)); presetContainer.innerHTML = ''; importedPresets.forEach(preset => addNewPreset(preset.name, preset.url)); alert("Presets erfolgreich importiert."); } else { throw new Error("Ungültiges Format."); } } catch (error) { alert("Fehler beim Importieren: " + error.message); } }; reader.readAsText(file); } }); input.click(); } function loadPresetsFromFile(event) { event.preventDefault(); fetch('/webradio_presets.json') .then(response => { if (!response.ok) { throw new Error('Datei konnte nicht geladen werden'); } return response.json(); }) .then(data => { localStorage.setItem('presets', JSON.stringify(data)); presetContainer.innerHTML = ''; data.forEach(preset => addNewPreset(preset.name, preset.url)); alert('Presets erfolgreich geladen.'); }) .catch(error => alert('Fehler: ' + error.message)); } // === Funktion: Sortierbare Presets === function setupSortable() { new Sortable(presetContainer, { animation: 250, ghostClass: 'ghost', handle: '.move-button', onEnd: savePresetOrder }); } });