251 lines
No EOL
8.9 KiB
JavaScript
251 lines
No EOL
8.9 KiB
JavaScript
// Public Domain - Hauptlogik des Radioplayers (Schaltzentrale)
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
// --- UI ELEMENTE ---
|
|
const presetContainer = document.getElementById('preset-container');
|
|
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');
|
|
|
|
let currentSound = null;
|
|
|
|
// --- INITIALISIERUNG ---
|
|
if (window.UI) window.UI.initializeFooter();
|
|
initializeEventListeners();
|
|
|
|
// Manager verknüpfen
|
|
if (window.SleepTimer) {
|
|
window.SleepTimer.init(() => stopPlayback());
|
|
}
|
|
|
|
if (window.PresetManager) {
|
|
window.PresetManager.load((loadedPresets) => {
|
|
displayPresets(loadedPresets);
|
|
initSortable();
|
|
});
|
|
}
|
|
|
|
// --- EVENT LISTENER ---
|
|
function initializeEventListeners() {
|
|
// Stop Button
|
|
if (stopButton) {
|
|
stopButton.onclick = stopPlayback;
|
|
}
|
|
|
|
// Preset Modal öffnen
|
|
const editBtn = document.getElementById('edit-presets-button');
|
|
if (editBtn) {
|
|
editBtn.onclick = openPresetModal;
|
|
}
|
|
|
|
// Sleep Timer Modal öffnen
|
|
const sleepBtn = document.getElementById('open-sleep-timer-modal');
|
|
if (sleepBtn) {
|
|
sleepBtn.onclick = openSleepModal;
|
|
}
|
|
|
|
// Sleep Timer Modal schließen (X-Button)
|
|
const closeSleepBtn = document.getElementById('close-sleep-timer-modal');
|
|
if (closeSleepBtn) {
|
|
closeSleepBtn.onclick = () => {
|
|
const sm = document.getElementById('sleep-timer-modal');
|
|
sm.classList.add('hidden');
|
|
sm.style.display = 'none';
|
|
};
|
|
}
|
|
|
|
// Sleep Timer wirklich ausschalten
|
|
const offSleepBtn = document.getElementById('off-sleep-timer-modal');
|
|
if (offSleepBtn) {
|
|
offSleepBtn.onclick = () => {
|
|
if (window.SleepTimer) {
|
|
window.SleepTimer.clear(); // Stoppt den Timeout und resettet die UI
|
|
}
|
|
const sm = document.getElementById('sleep-timer-modal');
|
|
if (sm) {
|
|
sm.classList.add('hidden');
|
|
sm.style.display = 'none';
|
|
}
|
|
};
|
|
}
|
|
|
|
// Zeit-Optionen im Sleep Timer
|
|
document.querySelectorAll('.time-option').forEach(btn => {
|
|
btn.onclick = () => {
|
|
const minutes = parseInt(btn.getAttribute('data-time')) / 60000;
|
|
window.SleepTimer.start(minutes);
|
|
const sm = document.getElementById('sleep-timer-modal');
|
|
sm.classList.add('hidden');
|
|
sm.style.display = 'none';
|
|
};
|
|
});
|
|
}
|
|
|
|
// --- PLAYER LOGIK ---
|
|
function playStream(url, item) {
|
|
stopPlayback();
|
|
if (window.MetaHandler) window.MetaHandler.stop();
|
|
|
|
currentSound = new Howl({
|
|
src: [url],
|
|
html5: true,
|
|
volume: 0.5,
|
|
// In der playStream Funktion innerhalb von onplay:
|
|
onplay: () => {
|
|
stopButton.classList.remove('hidden');
|
|
const stationName = item.querySelector('h3').textContent;
|
|
if (window.UI) window.UI.updateDocumentTitle(stationName);
|
|
|
|
// Wir setzen das Icon für den Sender
|
|
currentStationName.innerHTML = `<i class="fa-solid fa-tower-broadcast"></i> ${stationName}`;
|
|
|
|
if (window.MetaHandler) window.MetaHandler.start(url);
|
|
},
|
|
onstop: () => {
|
|
stopButton.classList.add('hidden');
|
|
currentStationName.textContent = 'Wähle einen Sender aus';
|
|
if (window.UI) window.UI.updateDocumentTitle('');
|
|
if (window.MetaHandler) window.MetaHandler.stop();
|
|
}
|
|
});
|
|
currentSound.play();
|
|
}
|
|
|
|
function stopPlayback() {
|
|
if (currentSound) {
|
|
currentSound.stop();
|
|
currentSound = null;
|
|
}
|
|
}
|
|
|
|
// --- PRESET UI ---
|
|
function displayPresets(presets) {
|
|
presetContainer.innerHTML = '';
|
|
presets.forEach(preset => {
|
|
const presetItem = document.createElement('div');
|
|
presetItem.classList.add('preset-item');
|
|
presetItem.innerHTML = `<h3>${preset.name}</h3>`;
|
|
presetItem.onclick = () => playStream(preset.url, presetItem);
|
|
presetContainer.appendChild(presetItem);
|
|
});
|
|
}
|
|
|
|
function renderPresetsTable() {
|
|
if (!tableBody) return;
|
|
tableBody.innerHTML = '';
|
|
window.PresetManager.presets.forEach((preset, index) => {
|
|
const row = document.createElement('tr');
|
|
row.setAttribute('data-index', index);
|
|
row.innerHTML = `
|
|
<td class="drag-handle">☰</td>
|
|
<td><input type="text" value="${preset.name}" onchange="changeName(${index}, this.value)"></td>
|
|
<td><input type="text" value="${preset.url}" onchange="changeURL(${index}, this.value)"></td>
|
|
<td><button class="delete-btn" onclick="deletePreset(${index})"><i class="fas fa-trash-alt"></i></button></td>
|
|
`;
|
|
tableBody.appendChild(row);
|
|
});
|
|
}
|
|
|
|
// --- MODAL WRAPPER ---
|
|
function openPresetModal() {
|
|
if (!presetModal) return;
|
|
presetModal.classList.remove('hidden');
|
|
presetModal.style.display = 'block';
|
|
renderPresetsTable();
|
|
if (window.PresetManager) window.PresetManager.generateExportCode();
|
|
}
|
|
|
|
function openSleepModal() {
|
|
const sm = document.getElementById('sleep-timer-modal');
|
|
if (sm) {
|
|
sm.classList.remove('hidden');
|
|
sm.style.display = 'block';
|
|
if (window.SleepTimer) window.SleepTimer.updateButtonUI();
|
|
}
|
|
}
|
|
|
|
// --- GLOBALE HELFER (für HTML onclicks & Manager) ---
|
|
window.closeModal = () => {
|
|
if (presetModal) {
|
|
presetModal.classList.add('hidden');
|
|
presetModal.style.display = 'none';
|
|
}
|
|
};
|
|
|
|
window.addPreset = () => {
|
|
window.PresetManager.presets.push({ name: 'Neuer Sender', url: '' });
|
|
renderPresetsTable();
|
|
};
|
|
|
|
window.deletePreset = (index) => {
|
|
window.UI.showConfirm("Löschen", "Sender wirklich entfernen?", (conf) => {
|
|
if (conf) {
|
|
window.PresetManager.presets.splice(index, 1);
|
|
renderPresetsTable();
|
|
window.PresetManager.generateExportCode();
|
|
}
|
|
});
|
|
};
|
|
|
|
window.saveAndClose = () => {
|
|
window.PresetManager.save();
|
|
location.reload();
|
|
};
|
|
|
|
window.changeName = (i, v) => {
|
|
window.PresetManager.presets[i].name = v;
|
|
window.PresetManager.generateExportCode();
|
|
};
|
|
|
|
window.changeURL = (i, v) => {
|
|
window.PresetManager.presets[i].url = v;
|
|
window.PresetManager.generateExportCode();
|
|
};
|
|
|
|
window.exportPreset = () => window.PresetManager.exportToFile();
|
|
|
|
window.importPreset = () => {
|
|
window.UI.showConfirm("Vorsicht", "Alle Sender werden überschrieben!", (conf) => {
|
|
if (conf) {
|
|
const input = document.createElement('input');
|
|
input.type = 'file';
|
|
input.accept = 'application/json';
|
|
input.onchange = e => {
|
|
const reader = new FileReader();
|
|
reader.onload = ev => {
|
|
try {
|
|
window.PresetManager.presets = JSON.parse(ev.target.result);
|
|
window.PresetManager.save();
|
|
location.reload();
|
|
} catch (err) { window.UI.showAlert("Fehler", "Ungültige Datei."); }
|
|
};
|
|
reader.readAsText(e.target.files[0]);
|
|
};
|
|
input.click();
|
|
}
|
|
});
|
|
};
|
|
|
|
window.importFromString = () => {
|
|
const field = document.getElementById('import-string-field');
|
|
const code = field ? field.value.trim() : "";
|
|
if (!code) return window.UI.showAlert("Fehler", "Bitte Code einfügen.");
|
|
window.UI.showConfirm("Vorsicht", "Alle Sender werden überschrieben!", (conf) => {
|
|
if (conf) window.PresetManager.importFromString(code);
|
|
});
|
|
};
|
|
|
|
function initSortable() {
|
|
if (!tableBody) return;
|
|
new Sortable(tableBody, {
|
|
handle: '.drag-handle',
|
|
animation: 150,
|
|
onEnd: () => {
|
|
const newOrder = Array.from(tableBody.children).map(row => parseInt(row.getAttribute('data-index')));
|
|
window.PresetManager.presets = newOrder.map(index => window.PresetManager.presets[index]);
|
|
window.PresetManager.generateExportCode();
|
|
}
|
|
});
|
|
}
|
|
}); |