diff --git a/script.js b/script.js
index b5f6e58..ea639a0 100644
--- a/script.js
+++ b/script.js
@@ -1,107 +1,51 @@
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');
+ const presetModal = document.getElementById('preset-modal');
+ const tableBody = document.querySelector('#sortable-tbody');
const editPresetsButton = document.getElementById('edit-presets-button');
- let currentPlayingItem = null; // Speichert das aktuell spielende Element
+ let currentSound = null;
+ let presets = [];
- // === Abschnitt: Initialisierung ===
initializeFooter();
+ loadPresets();
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;
- }
+ document.getElementById('current-year').textContent = currentYear;
+ document.getElementById('server-name').textContent = window.location.hostname;
}
- // === Funktion: Titel dynamisch ändern ===
function updateTitle(stationName) {
- if (stationName) {
- document.title = `${stationName} - Radioplayer mit Presets`;
- } else {
- document.title = "Radioplayer mit Presets";
- }
+ document.title = stationName ? `${stationName} - Radioplayer mit Presets` : "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;
- }
-
- if (!isValidHttpUrl(presetUrl)) {
- alert("Bitte geben Sie eine gültige HTTP- oder HTTPS-URL ein.");
- return;
- }
-
- addNewPreset(presetName, presetUrl);
- savePresetToLocalStorage(presetName, presetUrl);
-
- newPresetNameInput.value = '';
- newPresetUrlInput.value = '';
- });
-
- exportButton.addEventListener('click', exportPresets);
- importButton.addEventListener('click', importPresets);
- loadPresetsLink.addEventListener('click', loadPresetsFromFile);
stopButton.addEventListener('click', stopPlayback);
-
- // Event-Listener für den "Presets bearbeiten"-Button
- editPresetsButton.addEventListener('click', () => {
- toggleEditMode();
- const isPressed = editPresetsButton.getAttribute('aria-pressed') === 'true';
- editPresetsButton.setAttribute('aria-pressed', !isPressed);
- });
+ editPresetsButton.addEventListener('click', openModal);
}
- // === Funktion: URL-Validierung ===
- function isValidHttpUrl(url) {
- try {
- const parsedUrl = new URL(url);
- return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
- } catch (e) {
- return false;
+ async function loadPresets() {
+ presets = JSON.parse(localStorage.getItem('presets')) || [];
+ if (presets.length === 0) {
+ try {
+ const response = await fetch('webradio_presets.json');
+ if (!response.ok) throw new Error('Datei konnte nicht geladen werden');
+ presets = await response.json();
+ localStorage.setItem('presets', JSON.stringify(presets));
+ } catch (error) {
+ alert('Fehler beim Laden der Presets: ' + error.message);
+ }
}
+ displayPresets(presets);
+ renderPresets();
+ initSortable();
}
- // Funktion zum Ein- und Ausblenden der Bearbeitungsbuttons
- function toggleEditMode() {
- const presetItems = document.querySelectorAll('.preset-item');
- presetItems.forEach(item => {
- const buttons = item.querySelectorAll('.edit-button, .delete-button, .move-button');
- buttons.forEach(button => button.classList.toggle('hidden'));
- });
- }
-
- // === Funktion: Preset-Handling ===
- function loadExistingPresets() {
- const presets = JSON.parse(localStorage.getItem('presets')) || [];
+ function displayPresets(presets) {
+ presetContainer.innerHTML = '';
presets.forEach(preset => addNewPreset(preset.name, preset.url));
}
@@ -109,177 +53,139 @@ document.addEventListener('DOMContentLoaded', function () {
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.innerHTML = `${name}
`;
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 renderPresets() {
+ tableBody.innerHTML = '';
+ presets.forEach((preset, index) => {
+ const row = document.createElement('tr');
+ row.setAttribute('data-index', index);
+ row.innerHTML = `
+ ☰ |
+ |
+ |
+ |
+ `;
+ tableBody.appendChild(row);
+ });
}
- 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();
+ stopPlayback();
+ currentSound = new Howl({
+ src: [url],
+ html5: true,
+ volume: 0.5,
+ onplay: () => {
+ stopButton.classList.remove('hidden');
+ updateTitle(item.querySelector('h3').textContent);
+ currentStationName.textContent = 'Es läuft: ' + item.querySelector('h3').textContent;
+ },
+ onstop: () => {
+ stopButton.classList.add('hidden');
+ currentStationName.textContent = 'Wähle einen Sender aus';
+ updateTitle('');
}
- 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 = 'Es läuft: ' + item.querySelector('h3').textContent;
-
- stopButton.classList.remove('hidden'); // Stopp-Button einblenden
- updateTitle(item.querySelector('h3').textContent);
+ });
+ currentSound.play();
}
function stopPlayback() {
- if (currentPlayingItem) {
- const audioElement = currentPlayingItem.querySelector('audio');
- if (audioElement) {
- audioElement.pause();
- audioElement.currentTime = 0;
- currentPlayingItem.classList.remove('playing');
- currentPlayingItem = null;
- currentStationName.textContent = 'Wähle einen Sender aus';
- }
+ if (currentSound) {
+ currentSound.stop();
+ currentSound = null;
}
-
- stopButton.classList.add('hidden'); // Stopp-Button ausblenden
- updateTitle('');
}
- // === Funktion: Preset-Import und -Export ===
- function exportPresets() {
- const presets = JSON.parse(localStorage.getItem('presets')) || [];
- const json = JSON.stringify(presets, null, 2);
+ function openModal() {
+ presetModal.classList.remove('hidden');
+ presetModal.style.display = 'block';
+ renderPresets();
+ }
- const blob = new Blob([json], { type: 'application/json' });
+ window.closeModal = function() {
+ presetModal.classList.add('hidden');
+ presetModal.style.display = 'none';
+ }
+
+ window.addPreset = function() {
+ presets.push({ name: 'Neuer Sender', url: '' });
+ renderPresets();
+ }
+
+ window.changeName = function(index, newName) {
+ presets[index].name = newName;
+ }
+
+ window.changeURL = function(index, newURL) {
+ presets[index].url = newURL;
+ }
+
+ window.deletePreset = function(index) {
+ presets.splice(index, 1);
+ renderPresets();
+ }
+
+ window.saveAndClose = function() {
+ savePresets();
+ closeModal();
+ location.reload();
+ }
+
+ function savePresets() {
+ localStorage.setItem('presets', JSON.stringify(presets));
+ }
+
+ function initSortable() {
+ const sortable = new Sortable(tableBody, {
+ handle: '.drag-handle',
+ animation: 150,
+ onEnd: function (evt) {
+ const newOrder = Array.from(tableBody.children).map(row => parseInt(row.getAttribute('data-index')));
+ presets = newOrder.map(index => presets[index]);
+ }
+ });
+ }
+
+ window.exportPreset = function() {
+ const presetsJSON = JSON.stringify(presets, null, 2);
+ const blob = new Blob([presetsJSON], { type: 'application/json' });
const url = URL.createObjectURL(blob);
-
const a = document.createElement('a');
a.href = url;
- a.download = 'webradio_presets.json';
+ a.download = 'radio_presets.json';
+ document.body.appendChild(a);
a.click();
-
+ document.body.removeChild(a);
URL.revokeObjectURL(url);
}
- function importPresets() {
+ window.importPreset = function() {
const input = document.createElement('input');
input.type = 'file';
- input.accept = '.json';
- input.addEventListener('change', (event) => {
+ input.accept = 'application/json';
+ input.onchange = function(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
- reader.onload = (e) => {
+ reader.onload = function(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.");
- }
+ presets = importedPresets;
+ localStorage.setItem('presets', JSON.stringify(presets));
+ renderPresets();
+ displayPresets(presets);
+ location.reload();
} catch (error) {
- alert("Fehler beim Importieren: " + error.message);
+ alert('Fehler beim Importieren der Presets: Ungültige Datei.');
}
};
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
- });
- }
});