News container (better than ever)
This commit is contained in:
76
src/components/News.tsx
Normal file
76
src/components/News.tsx
Normal file
@ -0,0 +1,76 @@
|
||||
import * as React from "react";
|
||||
import { XMLParser } from "fast-xml-parser";
|
||||
import * as styles from "../styles/containers/News.module.css"
|
||||
|
||||
const NEWS_REFRESH_INTERVAL = 15 * 60 * 1000;
|
||||
|
||||
const News = () => {
|
||||
const [news, setNews] = React.useState([])
|
||||
|
||||
React.useEffect(() => {
|
||||
pullNews()
|
||||
const newsInterval = setInterval(pullNews, NEWS_REFRESH_INTERVAL);
|
||||
|
||||
return () => clearInterval(newsInterval);
|
||||
}, [])
|
||||
|
||||
const processNews = (news: {title: string; updated: string;}[], postillon: {title: string; pubDate: string; categories: string[]}[]) => {
|
||||
const newsTable = []
|
||||
|
||||
for (const n of news) {
|
||||
if (!n.title || n.title === "") continue;
|
||||
|
||||
const updated = new Date(n.updated);
|
||||
newsTable.push(
|
||||
<tr key={n.title}>
|
||||
<td>{n.title}</td>
|
||||
<td>{updated.getHours()}:{updated.getMinutes().toString().padStart(2, "0")}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
const toUsePostillon = postillon.filter((news) => !news.categories.includes("Sonntagsfrage") && !news.categories.includes("Newsticker") && !news.categories.includes("Ratgeber") && !news.categories.includes("PamS") && !news.categories.includes("Leserbriefe") && !news.categories.includes("Podcast"));
|
||||
toUsePostillon.forEach((n, index) => {
|
||||
if (index > 2) return;
|
||||
const randTablePos = Math.floor(Math.random() * newsTable.length);
|
||||
const updated = new Date(n.pubDate);
|
||||
newsTable.splice(randTablePos, 0,
|
||||
<tr key={n.title}>
|
||||
<td>{n.title}</td>
|
||||
<td>{updated.getHours()}:{updated.getMinutes().toString().padStart(2, "0")}</td>
|
||||
</tr>
|
||||
)
|
||||
})
|
||||
|
||||
setNews(newsTable);
|
||||
}
|
||||
|
||||
const pullNews = async () => {
|
||||
const xml = new XMLParser();
|
||||
const response = await fetch("https://www.tagesschau.de/xml/atom/");
|
||||
const feed: {title: string; updated: string;}[] = xml.parse(await response.text()).feed.entry;
|
||||
|
||||
// Feedburner does not allow cors but at least we get JSON
|
||||
const postResponse = await fetch("https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2FrkEL");
|
||||
const data = await postResponse.json()
|
||||
|
||||
processNews(feed, data.items);
|
||||
}
|
||||
|
||||
return <div className={`container ${styles.container}`}>
|
||||
<div className={styles.inner}>
|
||||
<table>
|
||||
<tbody>
|
||||
{news}
|
||||
</tbody>
|
||||
</table>
|
||||
<table>
|
||||
<tbody>
|
||||
{news}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
export default News;
|
@ -1,6 +1,7 @@
|
||||
import * as React from "react"
|
||||
import secrets from "../../secrets.json"
|
||||
import Calendar from "../components/Calendar";
|
||||
import News from "../components/News";
|
||||
import WeatherAndTimeContainer from "../components/WeatherAndTime"
|
||||
import WeatherRadar from "../components/WeatherRadar";
|
||||
|
||||
@ -34,6 +35,7 @@ const IndexPage = () => {
|
||||
<WeatherAndTimeContainer secrets={secrets.weather} />
|
||||
<Calendar secrets={secrets.calendar} />
|
||||
<WeatherRadar />
|
||||
<News />
|
||||
</main>)
|
||||
}
|
||||
|
||||
|
38
src/styles/containers/News.module.css
Normal file
38
src/styles/containers/News.module.css
Normal file
@ -0,0 +1,38 @@
|
||||
.container {
|
||||
grid-area: news;
|
||||
}
|
||||
|
||||
.inner {
|
||||
height:100%;
|
||||
width: 100%;
|
||||
overflow:hidden;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.inner table {
|
||||
animation: newsSlider 60s linear 0s infinite normal;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.inner tr {
|
||||
background:rgba(0, 0, 0, .1);
|
||||
border-bottom: 2px solid black;
|
||||
}
|
||||
|
||||
.inner td {
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
.inner td:last-child {
|
||||
text-align: right;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.inner td:first-child {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
@keyframes newsSlider {
|
||||
from {transform: translateY(0);}
|
||||
to {transform: translateY(-100%);}
|
||||
}
|
Reference in New Issue
Block a user