diff options
author | gumi <git@gumi.ca> | 2019-07-24 14:59:24 -0400 |
---|---|---|
committer | gumi <git@gumi.ca> | 2019-07-24 14:59:24 -0400 |
commit | c9874173faea3ddb237592c26e09abb95885d444 (patch) | |
tree | 5a50c1b998281f47cfef1016688e3c557c46ae53 /src/components | |
parent | ff633c2ee469c4828f7e29b3a117969be58f38a9 (diff) | |
download | website-c9874173faea3ddb237592c26e09abb95885d444.tar.gz website-c9874173faea3ddb237592c26e09abb95885d444.tar.bz2 website-c9874173faea3ddb237592c26e09abb95885d444.tar.xz website-c9874173faea3ddb237592c26e09abb95885d444.zip |
automatically fetch news from github
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/News.vue | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/src/components/News.vue b/src/components/News.vue index 8a58514..c92e17f 100644 --- a/src/components/News.vue +++ b/src/components/News.vue @@ -2,10 +2,11 @@ <div class="news" v-if="count"> <span v-if="!entries.length">(no news entries)</span> - <article class="entry" v-for="entry in entries" :id="entry.date"> - <a :href="'#' + entry.date">{{ entry.title }}</a> + <article class="entry" v-for="entry in entries" :id="entry.id"> + <a :href="'#' + entry.id">{{ entry.title }}</a> <time :datetime="entry.date" class="date">{{ entry.date }}</time> <section class="body" v-html="entry.html"></section> + <q>{{entry.author}}</q> </article> </div> </template> @@ -30,15 +31,39 @@ & .body { margin-top: 5px; + + & :any-link { + color: inherit; + text-decoration: none; + + &::before { + content: "➜ "; + color: blue; + } + + &:hover { + text-decoration: underline; + } + } + } + + & q { + color: #009000; + margin-top: 0.5em; + display: inline-block; + + &::before { + content: "– "; + } } } </style> <script lang="ts"> import { Component, Prop, Vue } from "vue-property-decorator"; -import newsEntries from "@/assets/news.json"; interface NewsEntry { + id: string; title: string; date: string; author: string; @@ -49,6 +74,35 @@ interface NewsEntry { export default class News extends Vue { @Prop({ default: Infinity }) private count!: number; @Prop({ default: 0 }) private from!: number; - private entries: NewsEntry[] = (newsEntries as NewsEntry[]).slice(this.from, this.count); + private entries: NewsEntry[] = []; + + mounted () { + // restore from cache while we're loading a fresh copy + if (Reflect.has(self, "localStorage")) { + let newsCache = localStorage.getItem("newsCache"); + + if (newsCache !== null) { + this.entries = (JSON.parse(newsCache) as NewsEntry[]).slice(this.from, this.count); + } + } + + const req = new Request(process.env.VUE_APP_NEWS_JSON, { + method: "GET", + cache: "default", // serve if fresh, else fetch + }); + + fetch(req) + .then(data => data.json()) + .then(data => { + this.entries = (data as NewsEntry[]).slice(this.from, this.count); + + if (Reflect.has(self, "localStorage")) { + localStorage.setItem("newsCache", JSON.stringify(data)); + } + }) + .catch(e => { + // no news (will use cache, if any) + }) + } } </script> |