Zmiana iframe listy kanałow na pobierane lokalnie i parsowane
This commit is contained in:
@@ -1,20 +1,26 @@
|
|||||||
---
|
---
|
||||||
import ChannelSwitcher from "../../islands/ChannelSwitcher.jsx";
|
import ChannelSwitcher from "../../islands/ChannelSwitcher.jsx";
|
||||||
|
|
||||||
const { section } = Astro.props;
|
const { section } = Astro.props;
|
||||||
---
|
---
|
||||||
<section class="fuz-section bg-transparent">
|
|
||||||
|
<section class="f-section">
|
||||||
<div class="max-w-7xl mx-auto text-center">
|
<div class="max-w-7xl mx-auto text-center">
|
||||||
|
|
||||||
{section.title && (
|
{section.title && (
|
||||||
<h2 class="fuz-section-title">{section.title}</h2>
|
<h2 class="f-section-title">{section.title}</h2>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{section.content && (
|
{section.content && (
|
||||||
<div class="fuz-markdown mb-10" set:html={section.html} />
|
<div class="f-markdown mb-10" set:html={section.html} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<ChannelSwitcher client:load sets={section.iframe_sets} title={section.title} />
|
{section.iframe_sets && section.iframe_sets.length > 0 && (
|
||||||
|
<ChannelSwitcher
|
||||||
|
client:load
|
||||||
|
sets={section.iframe_sets}
|
||||||
|
title={section.title}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,19 +1,32 @@
|
|||||||
import { useState } from "preact/hooks";
|
import { useState, useEffect } from "preact/hooks";
|
||||||
|
|
||||||
export default function ChannelSwitcher({ sets = [], title = "" }) {
|
export default function ChannelSwitcher({ sets = [], title = "" }) {
|
||||||
const [activeId, setActiveId] = useState(sets[0]?.id);
|
const [activeId, setActiveId] = useState(sets[0]?.id);
|
||||||
|
const [channels, setChannels] = useState([]);
|
||||||
|
|
||||||
const active = sets.find((x) => x.id === activeId);
|
const active = sets.find((x) => x.id === activeId);
|
||||||
const iframeSrc = `https://www.jambox.pl/iframe-pakiet-logo?p=${active?.p}`;
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!active) return;
|
||||||
|
|
||||||
|
fetch(`/api/jambox/${active.p}`)
|
||||||
|
.then((r) => r.json())
|
||||||
|
.then((data) => {
|
||||||
|
setChannels(data);
|
||||||
|
})
|
||||||
|
.catch(() => setChannels([]));
|
||||||
|
}, [active]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
|
|
||||||
|
{/* SWITCHER */}
|
||||||
<div class="flex justify-center mb-10">
|
<div class="flex justify-center mb-10">
|
||||||
<div class="fuz-switch-group">
|
<div class="f-switch-group">
|
||||||
{sets.map((s) => (
|
{sets.map((s) => (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class={`fuz-switch ${activeId === s.id ? "active" : ""}`}
|
class={`f-switch ${activeId === s.id ? "active" : ""}`}
|
||||||
onClick={() => setActiveId(s.id)}
|
onClick={() => setActiveId(s.id)}
|
||||||
title={title}
|
title={title}
|
||||||
>
|
>
|
||||||
@@ -23,16 +36,31 @@ export default function ChannelSwitcher({ sets = [], title = "" }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 🔹 Iframe */}
|
{/* LISTA KANAŁÓW */}
|
||||||
<div class="w-full">
|
<div class="f-section-channel">
|
||||||
<div class="fuz-iframe-wrapper">
|
|
||||||
<iframe
|
{channels.length === 0 && (
|
||||||
title="Lista kanałów"
|
<p class="text-center col-span-full py-1">
|
||||||
src={iframeSrc}
|
Ładowanie…
|
||||||
class="fuz-iframe"
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{channels.map((ch) => (
|
||||||
|
<div
|
||||||
|
class="f-channel-box"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={ch.logo}
|
||||||
|
alt={ch.title}
|
||||||
|
class="h-14 object-contain "
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
></iframe>
|
/>
|
||||||
|
<p class="text-center text-sm text-[var(--fuz-text)] mt-2">
|
||||||
|
{ch.title}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
42
src/pages/api/jambox/[id].ts
Normal file
42
src/pages/api/jambox/[id].ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import type { APIRoute } from "astro";
|
||||||
|
import { JSDOM } from "jsdom";
|
||||||
|
|
||||||
|
interface Channel {
|
||||||
|
title: string;
|
||||||
|
logo: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cache = new Map<string, { time: number; data: Channel[] }>();
|
||||||
|
const CACHE_TIME = 1000 * 60 * 60 * 24 * 30; //miesiąc
|
||||||
|
|
||||||
|
export const GET: APIRoute = async ({ params }) => {
|
||||||
|
const id = params.id!;
|
||||||
|
const cached = cache.get(id);
|
||||||
|
|
||||||
|
if (cached && Date.now() - cached.time < CACHE_TIME) {
|
||||||
|
return new Response(JSON.stringify(cached.data), {
|
||||||
|
headers: { "Content-Type": "application/json" }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = `https://www.jambox.pl/iframe-pakiet-logo?p=${id}`;
|
||||||
|
const resp = await fetch(url, { headers: { "User-Agent": "Mozilla/5.0" } });
|
||||||
|
|
||||||
|
const html = await resp.text();
|
||||||
|
const dom = new JSDOM(html);
|
||||||
|
|
||||||
|
const images = [
|
||||||
|
...dom.window.document.querySelectorAll("img.imagefield-field_logo")
|
||||||
|
];
|
||||||
|
|
||||||
|
const channels = images.map((img) => ({
|
||||||
|
title: img.getAttribute("alt")?.trim() ?? "",
|
||||||
|
logo: img.getAttribute("src") ?? "",
|
||||||
|
}));
|
||||||
|
|
||||||
|
cache.set(id, { time: Date.now(), data: channels });
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(channels), {
|
||||||
|
headers: { "Content-Type": "application/json" }
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
@layer components {
|
@layer components {
|
||||||
#cookie-banner {
|
#cookie-banner {
|
||||||
@apply fixed bottom-0 left-0 w-full translate-y-full transition-transform duration-500 ease-in-out;
|
@apply fixed bottom-0 left-0 w-full translate-y-full transition-transform duration-500 ease-in-out;
|
||||||
background: var(--f-background-invert);
|
background: var(--f-cookie-background);
|
||||||
color: var(--f-text-invert);
|
color: var(--f-cookie-text);
|
||||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
/* border-top: 1px solid rgba(0, 0, 0, 0.1); */
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-cookie-panel-inner {
|
.f-cookie-panel-inner {
|
||||||
@apply max-w-4xl mx-auto flex flex-col md:flex-row items-start
|
@apply max-w-5xl mx-auto flex flex-col md:flex-row items-start md:items-center justify-between gap-4 px-6 py-6;
|
||||||
md:items-center justify-between gap-4 px-6 py-6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-cookie-text {
|
.f-cookie-text {
|
||||||
@@ -17,32 +16,21 @@
|
|||||||
|
|
||||||
.f-cookie-privacy-link {
|
.f-cookie-privacy-link {
|
||||||
@apply ml-3;
|
@apply ml-3;
|
||||||
color: var(--btn-outline-invert);
|
color: var(--f-link-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-cookie-accept,
|
.f-cookie-accept,
|
||||||
.f-cookie-reject {
|
.f-cookie-reject {
|
||||||
@apply px-4 py-2 rounded-md text-sm font-medium transition-colors;
|
@apply px-8 py-4 rounded-md text-sm font-medium transition-colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-cookie-accept {
|
.f-cookie-accept {
|
||||||
background: var(--btn-bg-invert);
|
background: var(--f-cookie-accept-background);
|
||||||
color: var(--btn-text-invert);
|
color: var(--f-cookie-accept-text);
|
||||||
}
|
|
||||||
|
|
||||||
.f-cookie-accept:hover {
|
|
||||||
background: var(--fuz-accent-hover);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-cookie-reject {
|
.f-cookie-reject {
|
||||||
@apply border;
|
background: var(--f-cookie-reject-background);
|
||||||
border-color: var(--btn-outline-invert);
|
color: var(--f-cookie-reject-text);
|
||||||
color: var(--btn-outline-invert);
|
|
||||||
background: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-cookie-reject:hover {
|
|
||||||
background: var(--btn-outline-bg-invert);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
.f-switches-wrapper {
|
.f-switches-wrapper {
|
||||||
@apply flex flex-wrap justify-center gap-6 mb-12;
|
@apply flex flex-wrap justify-center gap-6 mb-10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-switch-group {
|
.f-switch-group {
|
||||||
@apply inline-flex overflow-hidden relative bg-[var(--f-background-switch)];
|
@apply inline-flex overflow-hidden relative bg-[var(--f-background-switch)] mt-8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.f-switch {
|
.f-switch {
|
||||||
|
|||||||
@@ -43,7 +43,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.fuz-iframe-box {
|
.f-section-channel {
|
||||||
|
@apply grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-8 gap-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.f-channel-box {
|
||||||
|
@apply flex flex-col items-center p-4 rounded-xl bg-[var(--f-background)] border border-[var(--f-offers-border)] shadow-sm hover:shadow-md transition
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .fuz-iframe-box {
|
||||||
@apply bg-white dark:bg-slate-800 p-4 rounded-xl border border-gray-200 dark:border-slate-700 shadow;
|
@apply bg-white dark:bg-slate-800 p-4 rounded-xl border border-gray-200 dark:border-slate-700 shadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,4 +72,4 @@
|
|||||||
|
|
||||||
.dark .fuz-iframe {
|
.dark .fuz-iframe {
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
}
|
} */
|
||||||
@@ -69,27 +69,12 @@
|
|||||||
--f-offers-popular: var(--brand-light);
|
--f-offers-popular: var(--brand-light);
|
||||||
--f-offers-popular-bg: color-mix(in srgb, var(--f-offers-popular) 22%, transparent);
|
--f-offers-popular-bg: color-mix(in srgb, var(--f-offers-popular) 22%, transparent);
|
||||||
|
|
||||||
/* Invert Color */
|
--f-cookie-background: var(--text1-light);
|
||||||
/* --f-background-invert: #0d1117;
|
--f-cookie-text: var(--surface2-light);
|
||||||
--f-text-invert: #e6edf3;
|
|
||||||
--btn-bg-invert: #58a6ff;
|
|
||||||
--btn-text-invert: #0d1117;
|
|
||||||
--btn-outline-invert: #58a6ff;
|
|
||||||
--btn-outline-bg-invert: rgba(88, 166, 255, 0.15); */
|
|
||||||
/* Links */
|
|
||||||
/* --fuz-link: #0050c8;
|
|
||||||
--fuz-link-hover: #003f9a; */
|
|
||||||
|
|
||||||
/* Accent (buttons, highlights) */
|
--f-cookie-accept-background: green;
|
||||||
/* --fuz-accent: #0066ff;
|
/* --f-cookie-accept-text: */
|
||||||
--fuz-accent-hover: #004bcc;
|
--f-cookie-reject-background: var(--text2-light);
|
||||||
--fuz-accent-text: #ffffff;
|
|
||||||
|
|
||||||
|
|
||||||
--btn-ghost-text: var(--f-text);
|
|
||||||
--btn-ghost-hover-bg: rgba(0, 0, 0, 0.05);
|
|
||||||
---f-border-color: rgb(209 213 219); */
|
|
||||||
/* / var(--tw-border-opacity, 1)); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:root.dark {
|
:root.dark {
|
||||||
@@ -128,36 +113,12 @@
|
|||||||
--f-offers-popular: var(--brand-dark);
|
--f-offers-popular: var(--brand-dark);
|
||||||
--f-offers-popular-bg: color-mix(in srgb, var(--f-offers-popular) 22%, transparent);
|
--f-offers-popular-bg: color-mix(in srgb, var(--f-offers-popular) 22%, transparent);
|
||||||
|
|
||||||
|
--f-cookie-background: var(--text1-light);
|
||||||
|
--f-cookie-text: var(--surface2-light);
|
||||||
|
|
||||||
|
--f-cookie-accept-background: green;
|
||||||
/* Invert Color */
|
/* --f-cookie-accept-text: */
|
||||||
--f-background-invert: #ffffff;
|
--f-cookie-reject-background: var(--text2-light);
|
||||||
--f-text-invert: #0d0d0d;
|
|
||||||
--btn-bg-invert: #0066ff;
|
|
||||||
--btn-text-invert: #ffffff;
|
|
||||||
--btn-outline-invert: #0066ff;
|
|
||||||
|
|
||||||
/* Links (GitHub Dark palette) */
|
|
||||||
--fuz-link: var(--brand-dim);
|
|
||||||
--fuz-link-hover: #79b7ff;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Accent */
|
|
||||||
--fuz-accent: hsl(var(--hue) calc(var(--saturation) / 1.25) calc(var(--lightness) / 1.25));
|
|
||||||
--fuz-accent-hover: #79b7ff;
|
|
||||||
--fuz-accent-text: #0d1117;
|
|
||||||
|
|
||||||
/* Buttons */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--btn-ghost-text: var(--f-text);
|
|
||||||
--btn-ghost-hover-bg: rgba(255, 255, 255, 0.08);
|
|
||||||
|
|
||||||
--f-border-color: rgb(209 213 219);
|
|
||||||
/* / var(--tw-border-opacity, 1)) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Body */
|
/* Body */
|
||||||
|
|||||||
Reference in New Issue
Block a user