style.css aktualisiert

Für den neuen Bearbeite-Modus angepasst.
This commit is contained in:
simonpipe 2025-04-02 14:01:00 +00:00
parent b5a5432668
commit 7caed0f0e7

278
style.css
View file

@ -1,169 +1,191 @@
:root { document.addEventListener('DOMContentLoaded', function () {
--primary-color: #ff9999; const presetContainer = document.getElementById('preset-container');
--header-height: 120px; const stopButton = document.querySelector('.stop-button');
--padding-top: calc(10px + var(--header-height)); const currentStationName = document.getElementById('current-station-name');
--box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); const presetModal = document.getElementById('preset-modal');
const tableBody = document.querySelector('#sortable-tbody');
const editPresetsButton = document.getElementById('edit-presets-button');
let currentSound = null;
let presets = [];
initializeFooter();
loadPresets();
initializeEventListeners();
function initializeFooter() {
const currentYear = new Date().getFullYear();
document.getElementById('current-year').textContent = currentYear;
document.getElementById('server-name').textContent = window.location.hostname;
} }
body { function updateTitle(stationName) {
font-family: Arial, sans-serif; document.title = stationName ? `${stationName} - Radioplayer mit Presets` : "Radioplayer mit Presets";
text-align: center;
margin: 0;
padding: 20px;
padding-top: var(--padding-top);
} }
.header { function initializeEventListeners() {
background-color: #FFFFE3; stopButton.addEventListener('click', stopPlayback);
height: var(--header-height); editPresetsButton.addEventListener('click', openModal);
padding-bottom: 10px;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 1000;
box-shadow: var(--box-shadow);
} }
.titel { async function loadPresets() {
display: flex; presets = JSON.parse(localStorage.getItem('presets')) || [];
align-items: center; if (presets.length === 0) {
justify-content: center; try {
gap: 10px; 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();
} }
.titel img { function displayPresets(presets) {
height: 30px; presetContainer.innerHTML = '';
width: auto; presets.forEach(preset => addNewPreset(preset.name, preset.url));
} }
.hidden { function addNewPreset(name, url) {
display: none; const presetItem = document.createElement('div');
presetItem.classList.add('preset-item');
presetItem.dataset.streamUrl = url;
presetItem.innerHTML = `<h3>${name}</h3>`;
presetItem.addEventListener('click', () => playStream(url, presetItem));
presetContainer.appendChild(presetItem);
} }
.stop-button { function renderPresets() {
background-color: var(--primary-color); tableBody.innerHTML = '';
color: #fff; presets.forEach((preset, index) => {
font-weight: bold; const row = document.createElement('tr');
border: none; row.setAttribute('data-index', index);
border-radius: 5px; row.innerHTML = `
height: 30px; <td class="drag-handle"></td>
padding: 4px 10px; <td><input type="text" value="${preset.name}" onchange="changeName(${index}, this.value)"></td>
font-size: 18px; <td><input type="text" value="${preset.url}" onchange="changeURL(${index}, this.value)"></td>
margin: 0; <td><button class="delete-btn" onclick="deletePreset(${index})"><i class="fas fa-trash-alt" style="color:grey"></i></button></td>
margin-left: auto; `;
cursor: pointer; tableBody.appendChild(row);
transition: background-color 0.3s ease; });
position: relative;
top: -2px;
} }
.stop-button:focus { function playStream(url, item) {
outline: none; stopPlayback();
box-shadow: 0 0 5px rgba(255, 77, 77, 0.75); 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('');
}
});
currentSound.play();
} }
.current-station { function stopPlayback() {
font-weight: bold; if (currentSound) {
font-size: 16px; currentSound.stop();
margin-bottom: 15px; currentSound = null;
}
} }
#aktueller-sender { function openModal() {
background-color: #d2f8d2; presetModal.classList.remove('hidden');
border-radius: 5px; presetModal.style.display = 'block';
padding: 10px 20px; renderPresets();
} }
.edit-button, .delete-button, .move-button { window.closeModal = function() {
display: none; /* Standardmäßig ausgeblendet */ presetModal.classList.add('hidden');
presetModal.style.display = 'none';
} }
.edit-button.hidden, .delete-button.hidden, .move-button.hidden { window.addPreset = function() {
display: inline-block; /* Wird angezeigt, wenn die Klasse 'hidden' entfernt wird */ presets.push({ name: 'Neuer Sender', url: '' });
renderPresets();
} }
window.changeName = function(index, newName) {
.preset-container { presets[index].name = newName;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-gap: 20px;
margin-top: 30px;
margin-bottom: 30px;
} }
.preset-item { window.changeURL = function(index, newURL) {
background-color: #f1f1f1; presets[index].url = newURL;
padding: 15px;
border-radius: 5px;
box-shadow: var(--box-shadow);
cursor: pointer;
transition: background-color 0.3s ease;
display: flex;
align-items: center;
} }
.preset-item h3 { window.deletePreset = function(index) {
margin: 0; presets.splice(index, 1);
flex: 1; renderPresets();
} }
.preset-item button { window.saveAndClose = function() {
margin-left: 2px; savePresets();
cursor: pointer; closeModal();
location.reload();
} }
.preset-item:hover { function savePresets() {
background-color: #e6e6e6; localStorage.setItem('presets', JSON.stringify(presets));
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
} }
.new-preset-container { function initSortable() {
margin-bottom: 15px; 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]);
}
});
} }
.button-container { window.exportPreset = function() {
margin-bottom: 5px; 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 = 'radio_presets.json';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
} }
.preset-set { window.importPreset = function() {
margin: 0; const input = document.createElement('input');
text-align: center; input.type = 'file';
font-size: 12px; input.accept = 'application/json';
color: #666; input.onchange = function(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
try {
const importedPresets = JSON.parse(e.target.result);
presets = importedPresets;
localStorage.setItem('presets', JSON.stringify(presets));
renderPresets();
displayPresets(presets);
location.reload();
} catch (error) {
alert('Fehler beim Importieren der Presets: Ungültige Datei.');
} }
};
.preset-set a { reader.readAsText(file);
color: #666;
text-decoration: underline;
}
.preset-set a:hover {
text-decoration: underline;
color: #333;
}
.footer {
display: flex;
align-items: center;
justify-content: center;
margin: 20px 0;
font-size: 12px;
color: #666;
}
.footer a {
color: #666;
text-decoration: none;
}
.footer a:hover {
text-decoration: none;
color: #333;
}
@media (max-width: 600px) {
.preset-container {
grid-template-columns: 1fr;
} }
};
input.click();
} }
});