view src/DisplayEvent.ts @ 21:a90cb6927c7d default tip

fix countdown queries. Display "now" instead of "In -0.4 hours"
author drewp@bigasterisk.com
date Sat, 07 Sep 2024 17:47:36 -0700
parents 20d1fa4250c0
children
line wrap: on
line source

import { addHours, endOfToday, endOfTomorrow, format, isAfter, isWithinInterval, parseISO, startOfToday } from "date-fns";
import { TemplateResult, html } from "lit";
import { DataFactory, NamedNode, Quad_Subject, Store, Term } from "n3";
import { getLiteral } from "./parseRdf";
import { hideFeeds, hideTitles } from "./private";
const EV = "http://bigasterisk.com/event#";
const { namedNode } = DataFactory;

export class DisplayEvent {
  constructor(private store: Store, private graph: Term, public uri: Quad_Subject) {}
  get title(): string {
    return getLiteral(this.store, this.graph, this.uri, namedNode(EV + "title"), "(unnamed)");
  }
  get start(): string {
    var ret = getLiteral(this.store, this.graph, this.uri, namedNode(EV + "start"), null);
    if (ret == null || ret === "") {
      ret = getLiteral(this.store, this.graph, this.uri, namedNode(EV + "startDate"), null);
    }
    return ret;
  }
  get calendar(): NamedNode {
    // todo: broken- it's now (calendar, :event, event)
    return namedNode(getLiteral(this.store, this.graph, this.uri, namedNode(EV + "feed"), null));
  }
  shortDate(): TemplateResult {
    const t = parseISO(this.start);
    return html`<span class="d">${format(t, "EEE, MMM d,")}</span> <span class="t">${format(t, "HH:mm")}</span>`;
  }
  inHowLong(): TemplateResult {
    // returns start()-now, like 'In 5 days'
    const t = parseISO(this.start).valueOf();
    const now = Date.now();
    const daysAway = (t - now) / 1000 / 86400;
    if (daysAway < 0) {
      return html`<span class="until until-2d">NOW</span>`;
    }
    const prec = daysAway < 2 ? 1 : 0;
    const cls = "until " + (daysAway < 2 ? "until-2d" : daysAway < 7 ? "until-7d" : daysAway < 30 ? "until-1mo" : "");
    return html`In <span class="${cls}">${daysAway.toFixed(prec)} days</span>`;
  }
  show(): boolean {
    const now = new Date();
    const t = parseISO(this.start);

    const start = startOfToday();
    let end = endOfToday();
    if (isAfter(now, addHours(startOfToday(), 18))) {
      end = endOfTomorrow();
    }

    return isWithinInterval(t, { start, end }) && !hideTitles.has(this.title) && !hideFeeds.has(this.calendar.value);
  }
}