Split CSS

This commit is contained in:
Gogs
2026-07-07 10:42:45 +02:00
parent fc8e5ce3bb
commit dffd25fb47
10 changed files with 278 additions and 278 deletions
+34
View File
@@ -0,0 +1,34 @@
.channel-number {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 34px;
height: 26px;
margin-right: 10px;
border-radius: 999px;
background: var(--panel-3);
color: #dbeafe;
font-size: 0.85rem;
font-weight: 800;
}
.timeline-channel .channel-number {
margin-right: 0;
}
.timeline-channel-name {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.channel-logo {
width: 34px;
height: 24px;
object-fit: contain;
flex: 0 0 auto;
background: rgba(255, 255, 255, 0.08);
border-radius: 6px;
padding: 2px;
}
-19
View File
@@ -79,20 +79,6 @@
justify-content: space-between;
}
.channel-number {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 34px;
height: 26px;
margin-right: 10px;
border-radius: 999px;
background: var(--panel-3);
color: #dbeafe;
font-size: 0.85rem;
font-weight: 800;
}
.day-programme {
display: grid;
grid-template-columns: 92px 1fr;
@@ -101,11 +87,6 @@
border-top: 1px solid var(--border);
}
.day-programme.is-current {
background: rgba(34, 197, 94, 0.12);
border-left: 5px solid var(--success);
}
.day-programme.is-past {
opacity: 0.55;
}
+30
View File
@@ -0,0 +1,30 @@
.day-programme.is-current {
background: rgba(34, 197, 94, 0.12);
border-left: 5px solid var(--success);
}
.timeline-programme.is-current {
background: rgba(34, 197, 94, 0.22);
border-color: var(--success);
}
.timeline-now-line {
position: absolute;
top: 0;
bottom: 0;
width: 2px;
background: #ef4444;
z-index: 100;
pointer-events: none;
}
.timeline-now-line::before {
content: "";
position: absolute;
left: -5px;
top: -5px;
width: 12px;
height: 12px;
border-radius: 50%;
background: #ef4444;
}
-47
View File
@@ -100,27 +100,6 @@
font-weight: 800;
}
.timeline-channel .channel-number {
margin-right: 0;
}
.timeline-channel-name {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.channel-logo {
width: 34px;
height: 24px;
object-fit: contain;
flex: 0 0 auto;
background: rgba(255, 255, 255, 0.08);
border-radius: 6px;
padding: 2px;
}
.timeline-programmes {
position: relative;
min-height: 72px;
@@ -189,36 +168,10 @@
font-size: 0.75rem;
}
.timeline-programme.is-current {
background: rgba(34, 197, 94, 0.22);
border-color: var(--success);
}
.timeline-programme.is-past {
opacity: 0.55;
}
.timeline-now-line {
position: absolute;
top: 0;
bottom: 0;
width: 2px;
background: #ef4444;
z-index: 100;
pointer-events: none;
}
.timeline-now-line::before {
content: "";
position: absolute;
left: -5px;
top: -5px;
width: 12px;
height: 12px;
border-radius: 50%;
background: #ef4444;
}
.timeline-zoom {
display: flex;
gap: 8px;
+10 -211
View File
@@ -1,215 +1,14 @@
document.addEventListener("DOMContentLoaded", () => {
const wrap = document.querySelector(".timeline-wrap");
const line = document.querySelector(".timeline-now-line");
if (!wrap || !line)
return;
wrap.scrollLeft = Math.max(
0,
line.offsetLeft - wrap.clientWidth / 3
);
});
import { initNowLine } from "./modules/now.js";
import { initProgrammeModal } from "./modules/modal.js";
import { initGuideSearch } from "./modules/search.js";
import { initTimelineZoom, initTimelineDrag } from "./modules/timeline.js";
document.addEventListener("DOMContentLoaded", () => {
const modal = document.getElementById("programmeModal");
initNowLine();
initProgrammeModal();
initGuideSearch();
initTimelineZoom();
initTimelineDrag();
if (!modal) {
return;
}
const title = document.getElementById("modalTitle");
const subtitle = document.getElementById("modalSubtitle");
const description = document.getElementById("modalDescription");
const category = document.getElementById("modalCategory");
const time = document.getElementById("modalTime");
const openModal = (programmeElement) => {
const id = programmeElement.dataset.programmeId;
const programme = window.TVGUIDE_PROGRAMMES?.[id];
if (!programme) {
return;
}
title.textContent = programme.title || "";
subtitle.textContent = programme.subtitle || "";
description.textContent = programme.description || "Keine Beschreibung vorhanden.";
category.textContent = programme.category || "";
time.textContent = `${programme.channel || ""} · ${programme.start || ""} ${programme.stop || ""}`;
modal.hidden = false;
document.body.classList.add("modal-open");
};
const closeModal = () => {
modal.hidden = true;
document.body.classList.remove("modal-open");
};
document.querySelectorAll(".timeline-programme").forEach((programme) => {
programme.addEventListener("click", () => openModal(programme));
});
modal.querySelectorAll("[data-modal-close]").forEach((element) => {
element.addEventListener("click", closeModal);
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape" && !modal.hidden) {
closeModal();
}
});
console.log("TVGuide loaded");
});
document.addEventListener("DOMContentLoaded", () => {
const search = document.getElementById("guideSearch");
const results = document.getElementById("guideSearchResults");
const programmes = window.TVGUIDE_PROGRAMMES || {};
if (!search || !results) {
return;
}
const openProgrammeById = (id) => {
const element = document.querySelector(`[data-programme-id="${CSS.escape(id)}"]`);
if (element) {
element.click();
}
};
search.addEventListener("input", () => {
const query = search.value.trim().toLowerCase();
if (query.length < 2) {
results.hidden = true;
results.innerHTML = "";
return;
}
const matches = Object.values(programmes)
.filter((programme) => {
return [
programme.title,
programme.subtitle,
programme.description,
programme.category,
programme.channel
].some((value) => (value || "").toLowerCase().includes(query));
})
.slice(0, 12);
if (!matches.length) {
results.innerHTML = `<div class="guide-search-result"><strong>Nichts gefunden</strong></div>`;
results.hidden = false;
return;
}
results.innerHTML = matches.map((programme) => `
<div class="guide-search-result" data-search-programme-id="${programme.id}">
<strong>${programme.title || "Ohne Titel"}</strong>
<span>${programme.channel || ""} · ${programme.start || ""} ${programme.stop || ""}</span>
</div>
`).join("");
results.hidden = false;
});
results.addEventListener("click", (event) => {
const item = event.target.closest("[data-search-programme-id]");
if (!item) {
return;
}
openProgrammeById(item.dataset.searchProgrammeId);
results.hidden = true;
search.value = "";
});
document.addEventListener("click", (event) => {
if (!event.target.closest(".guide-search")) {
results.hidden = true;
}
});
});
document.addEventListener("DOMContentLoaded", () => {
const timelineWrap = document.querySelector(".timeline-wrap");
const zoomButtons = document.querySelectorAll("[data-zoom]");
if (!timelineWrap || !zoomButtons.length) {
return;
}
const savedZoom = localStorage.getItem("tvguideTimelineZoom") || "2";
const applyZoom = (zoom) => {
timelineWrap.style.setProperty("--minute-width", `${zoom}px`);
zoomButtons.forEach((button) => {
button.classList.toggle("active", button.dataset.zoom === zoom);
});
localStorage.setItem("tvguideTimelineZoom", zoom);
};
zoomButtons.forEach((button) => {
button.addEventListener("click", () => {
applyZoom(button.dataset.zoom);
});
});
applyZoom(savedZoom);
});
document.addEventListener("DOMContentLoaded", () => {
const timeline = document.querySelector(".timeline-wrap");
if (!timeline)
return;
let isDragging = false;
let startX = 0;
let scrollLeft = 0;
timeline.addEventListener("mousedown", (e) => {
// nicht wenn auf eine Sendung geklickt wird
if (e.target.closest(".timeline-programme"))
return;
isDragging = true;
timeline.classList.add("dragging");
startX = e.pageX;
scrollLeft = timeline.scrollLeft;
});
document.addEventListener("mouseup", () => {
isDragging = false;
timeline.classList.remove("dragging");
});
document.addEventListener("mousemove", (e) => {
if (!isDragging)
return;
e.preventDefault();
const walk = e.pageX - startX;
timeline.scrollLeft = scrollLeft - walk;
});
});
console.log('TVGuide loaded');
+50
View File
@@ -0,0 +1,50 @@
export function initProgrammeModal() {
const modal = document.getElementById("programmeModal");
if (!modal) {
return;
}
const title = document.getElementById("modalTitle");
const subtitle = document.getElementById("modalSubtitle");
const description = document.getElementById("modalDescription");
const category = document.getElementById("modalCategory");
const time = document.getElementById("modalTime");
const openModal = (programmeElement) => {
const id = programmeElement.dataset.programmeId;
const programme = window.TVGUIDE_PROGRAMMES?.[id];
if (!programme) {
return;
}
title.textContent = programme.title || "";
subtitle.textContent = programme.subtitle || "";
description.textContent = programme.description || "Keine Beschreibung vorhanden.";
category.textContent = programme.category || "";
time.textContent = `${programme.channel || ""} · ${programme.start || ""} ${programme.stop || ""}`;
modal.hidden = false;
document.body.classList.add("modal-open");
};
const closeModal = () => {
modal.hidden = true;
document.body.classList.remove("modal-open");
};
document.querySelectorAll(".timeline-programme").forEach((programme) => {
programme.addEventListener("click", () => openModal(programme));
});
modal.querySelectorAll("[data-modal-close]").forEach((element) => {
element.addEventListener("click", closeModal);
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape" && !modal.hidden) {
closeModal();
}
});
}
+13
View File
@@ -0,0 +1,13 @@
export function initNowLine() {
const wrap = document.querySelector(".timeline-wrap");
const line = document.querySelector(".timeline-now-line");
if (!wrap || !line) {
return;
}
wrap.scrollLeft = Math.max(
0,
line.offsetLeft - wrap.clientWidth / 3
);
}
+72
View File
@@ -0,0 +1,72 @@
export function initGuideSearch() {
const search = document.getElementById("guideSearch");
const results = document.getElementById("guideSearchResults");
const programmes = window.TVGUIDE_PROGRAMMES || {};
if (!search || !results) {
return;
}
const openProgrammeById = (id) => {
const element = document.querySelector(`[data-programme-id="${CSS.escape(id)}"]`);
if (element) {
element.click();
}
};
search.addEventListener("input", () => {
const query = search.value.trim().toLowerCase();
if (query.length < 2) {
results.hidden = true;
results.innerHTML = "";
return;
}
const matches = Object.values(programmes)
.filter((programme) => {
return [
programme.title,
programme.subtitle,
programme.description,
programme.category,
programme.channel
].some((value) => (value || "").toLowerCase().includes(query));
})
.slice(0, 12);
if (!matches.length) {
results.innerHTML = `<div class="guide-search-result"><strong>Nichts gefunden</strong></div>`;
results.hidden = false;
return;
}
results.innerHTML = matches.map((programme) => `
<div class="guide-search-result" data-search-programme-id="${programme.id}">
<strong>${programme.title || "Ohne Titel"}</strong>
<span>${programme.channel || ""} · ${programme.start || ""} ${programme.stop || ""}</span>
</div>
`).join("");
results.hidden = false;
});
results.addEventListener("click", (event) => {
const item = event.target.closest("[data-search-programme-id]");
if (!item) {
return;
}
openProgrammeById(item.dataset.searchProgrammeId);
results.hidden = true;
search.value = "";
});
document.addEventListener("click", (event) => {
if (!event.target.closest(".guide-search")) {
results.hidden = true;
}
});
}
+68
View File
@@ -0,0 +1,68 @@
export function initTimelineZoom() {
const timelineWrap = document.querySelector(".timeline-wrap");
const zoomButtons = document.querySelectorAll("[data-zoom]");
if (!timelineWrap || !zoomButtons.length) {
return;
}
const savedZoom = localStorage.getItem("tvguideTimelineZoom") || "2";
const applyZoom = (zoom) => {
timelineWrap.style.setProperty("--minute-width", `${zoom}px`);
zoomButtons.forEach((button) => {
button.classList.toggle("active", button.dataset.zoom === zoom);
});
localStorage.setItem("tvguideTimelineZoom", zoom);
};
zoomButtons.forEach((button) => {
button.addEventListener("click", () => {
applyZoom(button.dataset.zoom);
});
});
applyZoom(savedZoom);
}
export function initTimelineDrag() {
const timeline = document.querySelector(".timeline-wrap");
if (!timeline) {
return;
}
let isDragging = false;
let startX = 0;
let scrollLeft = 0;
timeline.addEventListener("mousedown", (event) => {
if (event.target.closest(".timeline-programme")) {
return;
}
isDragging = true;
timeline.classList.add("dragging");
startX = event.pageX;
scrollLeft = timeline.scrollLeft;
});
document.addEventListener("mouseup", () => {
isDragging = false;
timeline.classList.remove("dragging");
});
document.addEventListener("mousemove", (event) => {
if (!isDragging) {
return;
}
event.preventDefault();
const walk = event.pageX - startX;
timeline.scrollLeft = scrollLeft - walk;
});
}
+1 -1
View File
@@ -19,6 +19,6 @@
</div>
</div>
<script src="/assets/js/app.js"></script>
<script type="module" src="/assets/js/app.js"></script>
</body>
</html>