mirror of https://github.com/Lissy93/dashy.git
🔀 Merge pull request #1194 from josuablejeru/feature/hackernews-widget
hackernews widget
This commit is contained in:
commit
1fd7e6b15c
|
@ -35,6 +35,7 @@ Dashy has support for displaying dynamic content in the form of widgets. There a
|
||||||
- [GitHub Trending](#github-trending)
|
- [GitHub Trending](#github-trending)
|
||||||
- [GitHub Profile Stats](#github-profile-stats)
|
- [GitHub Profile Stats](#github-profile-stats)
|
||||||
- [Healthchecks Status](#healthchecks-status)
|
- [Healthchecks Status](#healthchecks-status)
|
||||||
|
- [Hackernews Trending](#hackernews-trending)
|
||||||
- [Mvg Departure](#mvg-departure)
|
- [Mvg Departure](#mvg-departure)
|
||||||
- [Mvg Connection](#mvg-connection)
|
- [Mvg Connection](#mvg-connection)
|
||||||
- [Custom search](#custom-search)
|
- [Custom search](#custom-search)
|
||||||
|
@ -1182,6 +1183,27 @@ Display status of one or more HealthChecks project(s). Works with healthcheck.io
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Hackernews Trending
|
||||||
|
|
||||||
|
Display new and trending Posts from Hackernews
|
||||||
|
|
||||||
|
#### Options
|
||||||
|
**Field** | **Type** | **Required** | **Description**
|
||||||
|
--- | --- | --- | ---
|
||||||
|
**`stories`** | `string` | _Optional_ | HN Stories to display defaults to `topstories`. Options are: `beststories`, `topstories` or `newstories`
|
||||||
|
**`limit`** | `int` | _Optional_ | The size of the list of Posts to show.
|
||||||
|
|
||||||
|
##### Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- type: hackernews-trending
|
||||||
|
options:
|
||||||
|
stories: newstories
|
||||||
|
limit: 10
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### MVG Departure
|
### MVG Departure
|
||||||
|
|
||||||
Display departure time of a MVG (Münchner Verkehrs Gesellschaft) station.
|
Display departure time of a MVG (Münchner Verkehrs Gesellschaft) station.
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
<template>
|
||||||
|
<div class="hackernews-wrapper">
|
||||||
|
<!-- Hackernews Trending Posts-->
|
||||||
|
<div class="posts-wrapper" v-if="trendingPosts">
|
||||||
|
<div class="post-row" v-for="(trendingPosts, index) in trendingPosts" :key="index">
|
||||||
|
<a class="post-top" :href="trendingPosts.originURL">
|
||||||
|
<div class="post-title-wrap">
|
||||||
|
<p class="post-title">{{ trendingPosts.title }}</p>
|
||||||
|
<p class="post-date">
|
||||||
|
{{ formatDate(trendingPosts.time) }}
|
||||||
|
</p>
|
||||||
|
<p class="post-score" v-if="trendingPosts.score">score: {{ trendingPosts.score }}</p>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// import axios from 'axios';
|
||||||
|
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||||
|
import { widgetApiEndpoints } from '@/utils/defaults';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [WidgetMixin],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
trendingPosts: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
stories() {
|
||||||
|
// This can be `beststories`, `topstories` or newstories
|
||||||
|
// TODO: display error message if another string not matching the keywords was insert
|
||||||
|
return this.options.stories || 'topstories';
|
||||||
|
},
|
||||||
|
limit() {
|
||||||
|
return this.options.limit || 10;
|
||||||
|
},
|
||||||
|
endpoint() {
|
||||||
|
return `${widgetApiEndpoints.hackernewsTrending}/${this.stories}.json`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchData() {
|
||||||
|
this.makeRequest(this.endpoint).then(this.fetchPostDetails);
|
||||||
|
},
|
||||||
|
async fetchPostDetails(data) {
|
||||||
|
const topPosts = data.slice(0, this.limit);
|
||||||
|
const allData = topPosts.map((post) => {
|
||||||
|
const url = `${widgetApiEndpoints.hackernewsTrending}/item/${post}.json`;
|
||||||
|
return this.makeRequest(url);
|
||||||
|
});
|
||||||
|
Promise.all(allData).then((resolvedPostValues) => {
|
||||||
|
this.trendingPosts = resolvedPostValues.map((element, index) => {
|
||||||
|
const trendingPost = { ...element, originURL: `https://news.ycombinator.com/item?id=${topPosts.at(index)}` };
|
||||||
|
return trendingPost;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
formatDate(unixTime) {
|
||||||
|
const date = new Date(unixTime * 1000);
|
||||||
|
// Then specify how you want your dates to be formatted
|
||||||
|
return new Intl.DateTimeFormat('default', { dateStyle: 'long' }).format(date);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.hackernews-wrapper {
|
||||||
|
.meta-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-decoration: none;
|
||||||
|
margin: 0.25rem 0 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-row {
|
||||||
|
border-top: 1px dashed var(--widget-text-color);
|
||||||
|
padding: 0.5rem 0 0.25rem 0;
|
||||||
|
.post-top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-decoration: none;
|
||||||
|
p.post-title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--widget-text-color);
|
||||||
|
}
|
||||||
|
p.post-date {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin: 0;
|
||||||
|
opacity: var(--dimming-factor);
|
||||||
|
color: var(--widget-text-color);
|
||||||
|
}
|
||||||
|
p.post-score {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin: 0;
|
||||||
|
opacity: var(--dimming-factor);
|
||||||
|
color: var(--widget-text-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -79,6 +79,7 @@ const COMPAT = {
|
||||||
'gl-system-load': 'GlSystemLoad',
|
'gl-system-load': 'GlSystemLoad',
|
||||||
'gl-cpu-temp': 'GlCpuTemp',
|
'gl-cpu-temp': 'GlCpuTemp',
|
||||||
'health-checks': 'HealthChecks',
|
'health-checks': 'HealthChecks',
|
||||||
|
'hackernews-trending': 'HackernewsTrending',
|
||||||
'gluetun-status': 'GluetunStatus',
|
'gluetun-status': 'GluetunStatus',
|
||||||
iframe: 'IframeWidget',
|
iframe: 'IframeWidget',
|
||||||
image: 'ImageWidget',
|
image: 'ImageWidget',
|
||||||
|
|
|
@ -107,11 +107,7 @@ module.exports = {
|
||||||
footer: true,
|
footer: true,
|
||||||
},
|
},
|
||||||
/* A list of route names that page furniture (header, footer, etc) should be hidden on */
|
/* A list of route names that page furniture (header, footer, etc) should be hidden on */
|
||||||
hideFurnitureOn: [
|
hideFurnitureOn: ['minimal', 'login', 'download'],
|
||||||
'minimal',
|
|
||||||
'login',
|
|
||||||
'download',
|
|
||||||
],
|
|
||||||
/* Key names for local storage identifiers */
|
/* Key names for local storage identifiers */
|
||||||
localStorageKeys: {
|
localStorageKeys: {
|
||||||
LANGUAGE: 'language',
|
LANGUAGE: 'language',
|
||||||
|
@ -166,9 +162,7 @@ module.exports = {
|
||||||
/* Amount of time to show splash screen, when enabled, in milliseconds */
|
/* Amount of time to show splash screen, when enabled, in milliseconds */
|
||||||
splashScreenTime: 1000,
|
splashScreenTime: 1000,
|
||||||
/* Page meta-data, rendered in the header of each view */
|
/* Page meta-data, rendered in the header of each view */
|
||||||
metaTagData: [
|
metaTagData: [{ name: 'description', content: "A simple static homepage for you're server" }],
|
||||||
{ name: 'description', content: 'A simple static homepage for you\'re server' },
|
|
||||||
],
|
|
||||||
/* Default option for Toast messages */
|
/* Default option for Toast messages */
|
||||||
toastedOptions: {
|
toastedOptions: {
|
||||||
position: 'bottom-center',
|
position: 'bottom-center',
|
||||||
|
@ -212,8 +206,10 @@ module.exports = {
|
||||||
generativeFallback: 'https://evatar.io/{icon}',
|
generativeFallback: 'https://evatar.io/{icon}',
|
||||||
localPath: './item-icons',
|
localPath: './item-icons',
|
||||||
faviconName: 'favicon.ico',
|
faviconName: 'favicon.ico',
|
||||||
homeLabIcons: 'https://raw.githubusercontent.com/walkxcode/dashboard-icons/master/png/{icon}.png',
|
homeLabIcons:
|
||||||
homeLabIconsFallback: 'https://raw.githubusercontent.com/NX211/homer-icons/master/png/{icon}.png',
|
'https://raw.githubusercontent.com/walkxcode/dashboard-icons/master/png/{icon}.png',
|
||||||
|
homeLabIconsFallback:
|
||||||
|
'https://raw.githubusercontent.com/NX211/homer-icons/master/png/{icon}.png',
|
||||||
},
|
},
|
||||||
/* API endpoints for widgets that need to fetch external data */
|
/* API endpoints for widgets that need to fetch external data */
|
||||||
widgetApiEndpoints: {
|
widgetApiEndpoints: {
|
||||||
|
@ -231,6 +227,7 @@ module.exports = {
|
||||||
exchangeRates: 'https://v6.exchangerate-api.com/v6/',
|
exchangeRates: 'https://v6.exchangerate-api.com/v6/',
|
||||||
flights: 'https://aerodatabox.p.rapidapi.com/flights/airports/icao/',
|
flights: 'https://aerodatabox.p.rapidapi.com/flights/airports/icao/',
|
||||||
githubTrending: 'https://gh-trending-repos.herokuapp.com/',
|
githubTrending: 'https://gh-trending-repos.herokuapp.com/',
|
||||||
|
hackernewsTrending: 'https://hacker-news.firebaseio.com/v0',
|
||||||
healthChecks: 'https://healthchecks.io/api/v1/checks',
|
healthChecks: 'https://healthchecks.io/api/v1/checks',
|
||||||
holidays: 'https://kayaposoft.com/enrico/json/v2.0/?action=getHolidaysForDateRange',
|
holidays: 'https://kayaposoft.com/enrico/json/v2.0/?action=getHolidaysForDateRange',
|
||||||
jokes: 'https://v2.jokeapi.dev/joke/',
|
jokes: 'https://v2.jokeapi.dev/joke/',
|
||||||
|
|
Loading…
Reference in New Issue