News container (better than ever)

This commit is contained in:
Daniel Kluge 2022-01-03 13:33:42 +01:00
parent 7a916bc899
commit 0ac2eb2125
6 changed files with 213 additions and 37 deletions

13
gatsby-node.js Normal file
View File

@ -0,0 +1,13 @@
exports.onCreateWebpackConfig = ({
stage,
rules,
loaders,
plugins,
actions,
}) => {
actions.setWebpackConfig({
resolve: {
fallback: { "os": require.resolve("os-browserify/browser") }
}
})
}

119
package-lock.json generated
View File

@ -8,8 +8,10 @@
"name": "infoscreen_gatsby",
"version": "1.0.0",
"dependencies": {
"fast-xml-parser": "^4.0.0-beta.8",
"gatsby": "^4.4.0",
"gatsby-plugin-react-svg": "^3.1.0",
"os-browserify": "^0.3.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
@ -7451,6 +7453,21 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"node_modules/fast-xml-parser": {
"version": "4.0.0-beta.8",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.0-beta.8.tgz",
"integrity": "sha512-2QEZ/WRt6mfrguLsluhvpTWNxdKYgvdZx3dA+Tnx0pUmlEA4ZWt32qSmA1sR1jXscFozHIKqZrikUeiCYSe3ow==",
"dependencies": {
"strnum": "^1.0.5"
},
"bin": {
"fxparser": "src/cli/cli.js"
},
"funding": {
"type": "paypal",
"url": "https://paypal.me/naturalintelligence"
}
},
"node_modules/fastest-levenshtein": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
@ -11551,6 +11568,11 @@
"resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.2.1.tgz",
"integrity": "sha512-Zl2RCcj/wRCakW9/yI83gutgNf7JFOPEHrCK72z+boIrU+PWAnIt6HADd1w+3keDQ90GCKbp1BduKZgkeNbz7A=="
},
"node_modules/os-browserify": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc="
},
"node_modules/os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@ -14826,6 +14848,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strnum": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
},
"node_modules/strtok3": {
"version": "6.2.4",
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.2.4.tgz",
@ -14995,6 +15022,26 @@
"node": ">=4.0.0"
}
},
"node_modules/svg-react-loader/node_modules/xml2js": {
"version": "0.4.17",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
"integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "^4.1.0"
}
},
"node_modules/svg-react-loader/node_modules/xmlbuilder": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
"integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=",
"dependencies": {
"lodash": "^4.0.0"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/svgo": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
@ -16382,26 +16429,6 @@
"node": ">=8"
}
},
"node_modules/xml2js": {
"version": "0.4.17",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
"integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "^4.1.0"
}
},
"node_modules/xmlbuilder": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
"integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=",
"dependencies": {
"lodash": "^4.0.0"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/xmlhttprequest-ssl": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",
@ -22145,6 +22172,14 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"fast-xml-parser": {
"version": "4.0.0-beta.8",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.0-beta.8.tgz",
"integrity": "sha512-2QEZ/WRt6mfrguLsluhvpTWNxdKYgvdZx3dA+Tnx0pUmlEA4ZWt32qSmA1sR1jXscFozHIKqZrikUeiCYSe3ow==",
"requires": {
"strnum": "^1.0.5"
}
},
"fastest-levenshtein": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
@ -25213,6 +25248,11 @@
"resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.2.1.tgz",
"integrity": "sha512-Zl2RCcj/wRCakW9/yI83gutgNf7JFOPEHrCK72z+boIrU+PWAnIt6HADd1w+3keDQ90GCKbp1BduKZgkeNbz7A=="
},
"os-browserify": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc="
},
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@ -27623,6 +27663,11 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
},
"strnum": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
},
"strtok3": {
"version": "6.2.4",
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.2.4.tgz",
@ -27742,6 +27787,23 @@
"emojis-list": "^2.0.0",
"json5": "^0.5.0"
}
},
"xml2js": {
"version": "0.4.17",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
"integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "^4.1.0"
}
},
"xmlbuilder": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
"integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=",
"requires": {
"lodash": "^4.0.0"
}
}
}
},
@ -28750,23 +28812,6 @@
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
"integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q=="
},
"xml2js": {
"version": "0.4.17",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
"integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "^4.1.0"
}
},
"xmlbuilder": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
"integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=",
"requires": {
"lodash": "^4.0.0"
}
},
"xmlhttprequest-ssl": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",

View File

@ -15,8 +15,10 @@
"clean": "gatsby clean"
},
"dependencies": {
"fast-xml-parser": "^4.0.0-beta.8",
"gatsby": "^4.4.0",
"gatsby-plugin-react-svg": "^3.1.0",
"os-browserify": "^0.3.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},

76
src/components/News.tsx Normal file
View 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;

View File

@ -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>)
}

View 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%);}
}