15
|
1 import { LitElement, css, html } from "lit";
|
|
2 import { customElement, property } from "lit/decorators.js";
|
|
3 import { sortBy } from "lodash";
|
|
4 import { DataFactory, Quad_Subject, Store } from "n3";
|
|
5 import { shared } from "./shared";
|
|
6 import { EV, fetchGraph, parseGraph, RDF } from "./parseRdf";
|
|
7 import { DisplayEvent } from "./DisplayEvent";
|
|
8
|
|
9 const { namedNode } = DataFactory;
|
|
10
|
|
11 @customElement("fd-countdown")
|
|
12 export class FdCountdown extends LitElement {
|
|
13 static styles = [
|
|
14 shared,
|
|
15 css`
|
|
16 ol {
|
|
17 list-style: none;
|
|
18 font-size: 16px;
|
|
19 background: #cd66bb2e;
|
|
20 padding: 9px;
|
|
21 width: fit-content;
|
|
22 position: relative;
|
|
23 top: -21px;
|
|
24 border-radius: 14px;
|
|
25 }
|
|
26 span.d {
|
|
27 opacity: 0.5;
|
|
28 }
|
|
29 li:has(.until) {
|
|
30 color: #666;
|
|
31 }
|
|
32 li:has(.until-2d) {
|
|
33 color: #fff;
|
|
34 }
|
|
35 li:has(.until-7d) {
|
|
36 color: #ccc;
|
|
37 }
|
|
38 li:has(.until-30d) {
|
|
39 color: #999;
|
|
40 }
|
|
41 li:has(.until)::before {
|
|
42 display: inline-block;
|
|
43 width: 1.4em;
|
|
44 content: "";
|
|
45 }
|
|
46 li:has(.until-2d)::before {
|
|
47 content: "🌕";
|
|
48 }
|
|
49 li:has(.until-7d)::before {
|
|
50 content: "🌙";
|
|
51 }
|
|
52 li:has(.until-30d)::before {
|
|
53 content: "🌑";
|
|
54 }
|
|
55 `,
|
|
56 ];
|
|
57 @property() evs: DisplayEvent[];
|
|
58 constructor() {
|
|
59 super();
|
|
60 this.evs = [];
|
|
61 this.load();
|
|
62 setInterval(this.load.bind(this), 5 * 60 * 1000);
|
|
63 }
|
|
64 async load() {
|
|
65 const store = new Store();
|
|
66 const r = await fetchGraph("/gcalendarwatch/graph/calendar/countdown");
|
|
67 await parseGraph(r, (store: Store) => {
|
|
68 const graph = namedNode(EV + "gcalendar");
|
|
69 this.evs = [];
|
|
70 store.getSubjects(namedNode(RDF + "type"), namedNode(EV + "Event"), graph).forEach((ev: Quad_Subject) => {
|
|
71 const de = new DisplayEvent(store, graph, ev);
|
|
72 this.evs = [...this.evs, de];
|
|
73 });
|
|
74 this.evs = sortBy(this.evs, "start");
|
|
75 });
|
|
76 }
|
|
77 render() {
|
|
78 return html`<h1 data-text="Coming Soon">Coming Soon</h1>
|
|
79 <ol>
|
|
80 ${this.evs.map((d) => html`<li>In ${d.inHowLong()}, ${d.title}</li>`)}
|
|
81 </ol> `;
|
|
82 }
|
|
83 }
|