summaryrefslogtreecommitdiffstats
path: root/VegaData/wwwroot
diff options
context:
space:
mode:
authorivar <i@oiee.no>2025-10-07 23:19:14 +0200
committerivar <i@oiee.no>2025-10-07 23:19:14 +0200
commit3d1d21ed0ab9c2a15a964e3d86104279e0d2cc60 (patch)
tree598f7315bfd446c6017a993c9b2691d47eaa0c0f /VegaData/wwwroot
parent46a1f50c0485b50267d5047f11282213c698491b (diff)
downloadvegadata-3d1d21ed0ab9c2a15a964e3d86104279e0d2cc60.tar.xz
vegadata-3d1d21ed0ab9c2a15a964e3d86104279e0d2cc60.zip
as
Diffstat (limited to 'VegaData/wwwroot')
-rw-r--r--VegaData/wwwroot/17.pngbin0 -> 5334 bytes
-rw-r--r--VegaData/wwwroot/framework.js22
-rw-r--r--VegaData/wwwroot/index.html30
-rw-r--r--VegaData/wwwroot/index.js122
4 files changed, 117 insertions, 57 deletions
diff --git a/VegaData/wwwroot/17.png b/VegaData/wwwroot/17.png
new file mode 100644
index 0000000..7895530
--- /dev/null
+++ b/VegaData/wwwroot/17.png
Binary files differ
diff --git a/VegaData/wwwroot/framework.js b/VegaData/wwwroot/framework.js
index e1652d0..de20d66 100644
--- a/VegaData/wwwroot/framework.js
+++ b/VegaData/wwwroot/framework.js
@@ -72,7 +72,7 @@ function trigger(target, key) {
// To use this in element props you need to supply the .value read as a function.
// */
export function r(target) {
- target = {value: target};
+ target = { value: target };
return new Proxy(target, {
get(obj, key, receiver) {
track(obj, key);
@@ -109,6 +109,24 @@ export function e(fn) {
return runner;
}
+export function gqp(key) {
+ return new URLSearchParams(location.search).get(key)
+}
+
+export function sqp(query) {
+ console.log(query);
+
+ if ('URLSearchParams' in window) {
+ const url = new URL(window.location)
+ for (const key of Object.keys(query)) {
+ const value = encodeURIComponent(query[key])
+ if (!value || value === "") url.searchParams.delete(key)
+ else url.searchParams.set(key, value)
+ }
+ history.pushState(null, '', url);
+ }
+}
+
//**
// Combine elements
// */
@@ -144,7 +162,7 @@ export function css(styleObject) {
// */
export function t(name, props, ...children) {
if (typeof name === "function") {
- return name({...props, children});
+ return name({ ...props, children });
}
return createElement(name, props, children);
}
diff --git a/VegaData/wwwroot/index.html b/VegaData/wwwroot/index.html
index 5ea2694..5beab75 100644
--- a/VegaData/wwwroot/index.html
+++ b/VegaData/wwwroot/index.html
@@ -7,14 +7,14 @@
<style>
@font-face {
font-family: 'Broadsheet Italic';
- src: url('./Broadsheet Italic/Broadsheet Italic.ttf') format('truetype');
+ src: url('https://vegaeller.oiee.no/Broadsheet Italic/Broadsheet Italic.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: 'Baskerville No.2 Regular';
- src: url('./Baskerville No.2 Regular/Baskerville No.2 Regular.otf') format('opentype');
+ src: url('https://vegaeller.oiee.no/Baskerville No.2 Regular/Baskerville No.2 Regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
@@ -31,11 +31,27 @@
box-sizing: border-box;
}
+ :root {
+ --bg: beige;
+ }
+
html,
body {
margin: 0;
padding: 0;
- background: beige;
+ background: var(--bg);
+ }
+
+ li:target {
+ padding-block: 2rem;
+ padding-inline: 1rem;
+ background-image: url("17.png");
+
+ div:first-of-type {
+ padding-block: .4rem;
+ padding-inline-start: .5rem;
+ background-color: var(--bg);
+ }
}
#ulShows {
@@ -94,10 +110,10 @@
</head>
<body>
- <h1>Bli med på vega</h1>
+ <h1>Bli med på vega?</h1>
<main>
- <button id="renderShowsBtn">last om</button>
- <input type="search" name="q" id="search" placeholder="søk">
+ <button id="renderShowsBtn">tilbakestill</button>
+ <input type="search" name="q1" id="search" placeholder="søk">
<ul id="ulShows"></ul>
</main>
<script type="importmap">
@@ -106,7 +122,7 @@
"temporal-polyfill": "https://esm.sh/temporal-polyfill@0.3.0"
}
}
-</script>
+ </script>
<script type="module" src="index.js"></script>
</body>
diff --git a/VegaData/wwwroot/index.js b/VegaData/wwwroot/index.js
index 29fbaeb..1a07ccb 100644
--- a/VegaData/wwwroot/index.js
+++ b/VegaData/wwwroot/index.js
@@ -1,12 +1,10 @@
import { Temporal } from "temporal-polyfill";
-import { t } from "./framework.js";
+import { gqp, sqp, t } from "./framework.js";
let _;
async function getShows() {
- if (_) {
- return _;
- }
+ if (_) return _;
const response = await fetch("/shows");
_ = await response.json();
return _;
@@ -15,46 +13,56 @@ async function getShows() {
const ulShows = document.getElementById("ulShows");
const search = document.getElementById("search");
const renderShowsBtn = document.getElementById("renderShowsBtn");
-const tzId = Temporal.Now.timeZoneId();
+
renderShowsBtn.addEventListener("click", () => {
- renderShows();
+ renderShows("");
search.value = "";
});
function dateString(date, small = false) {
- date = date + "+00:00";
- if (small) {
- return Temporal.Instant.from(date).toPlainDateTime().toLocaleString("nb-NO", {
- weekday: "long",
- calendar: "gregory",
- hour: "2-digit",
- minute: "2-digit",
- month: "long",
- day: "numeric"
- });
- }
- return Temporal.Instant.from(date).toPlainDateTime().toLocaleString("nb-NO", {
+ const instant = Temporal.Instant.from(`${date}Z`)
+ const stringOptions = {
weekday: "long",
- calendar: "gregory",
hour: "2-digit",
+ timeZone: "UTC",
minute: "2-digit",
- era: "long",
- year: "numeric",
month: "long",
+ calendar: "gregory",
day: "numeric"
+ }
+
+ if (small) {
+ return instant.toLocaleString("nb-NO", stringOptions);
+ }
+
+ return instant.toLocaleString("nb-NO", {
+ year: "numeric",
+ era: "long",
+ ...stringOptions
});
}
+function copyLink(e) {
+ if ("clipboard" in navigator) {
+ navigator.clipboard.writeText(`${location.origin}/index.html#${urlId(e)}`)
+ }
+}
+
+function vegascene(e) {
+ if (e.movieVersion.startsWith("KUL")) return `https://www.vegascene.no/teater/${e.movieVersion}`
+ return `https://www.vegascene.no/film/${e.movieVersion}`
+}
+
+if (gqp("q")) search.value = gqp("q")
search.addEventListener("input", e => renderShows(e.currentTarget.value));
-async function renderShows(query) {
+function urlId(e) {
+ return encodeURIComponent(`${e.movieVersion}-${e.startDateTime}`)
+}
+
+async function renderShows(query = search.value) {
query = query?.trim();
- const searchParams = new URLSearchParams(location.search);
- if (!query && searchParams.has("q")) {
- query = searchParams.get("q");
- }
- searchParams.set("q", query);
- let lis = [];
+ sqp({ q: query ?? "" })
const shows = (await getShows()).reduce((acc, curr) => {
const key = curr.title;
@@ -68,34 +76,52 @@ async function renderShows(query) {
async function share(show) {
const shareData = {
title: `${show.title} ${dateString(show.startDateTime, true)} på vega`,
- text: "",
- url: `#${show.title}-${show.startDateTime}`,
+ url: urlId(show),
};
await navigator.share(shareData);
}
+ const lis = [];
+
for (const showKey of Object.keys(shows).sort((a, b) => a.localeCompare(b))) {
- const times = shows[showKey].sort((a, b) => Temporal.PlainDate.compare(Temporal.PlainDate.from(a.startDateTime), Temporal.PlainDate.from(b.startDateTime)));
- if (query && !showKey.toLowerCase().match(query.toLowerCase())) {
- continue;
- }
- if (times.every(e => e.ticketUrl === "")) {
- continue;
+ const times = shows[showKey].sort((a, b) => Temporal.PlainDate.compare(Temporal.PlainDate.from(a.startDateTime), Temporal.PlainDate.from(b.startDateTime)))
+ if (query) {
+ const words = [showKey.toLowerCase()]
+ for (const time of times) {
+ words.push(dateString(time.startDateTime))
+ words.push(time.scene)
+ words.push(time.tags.join(" "))
+ }
+ if (!words.some((word) => word.match(query.toLowerCase()))) continue;
}
- lis.push(t("li", { class: "show", id: showKey }, [t("span", { class: "title italic" }, showKey), t("ul", undefined, [t("li", undefined,
- times.filter(e => e.ticketUrl !== "").map(e => t("li", { class: `time time-${e.id}`, id: `${showKey}-${e.startDateTime}` }, [t("a", undefined, [
- t("div", undefined, [
- t("span", { title: e.startDateTime }, dateString(e.startDateTime)),
- t("span", undefined, `${e.scene} - ${[e.type, ...e.tags].join(", ")}`),
- t("div", { class: "actions" }, [
- t("a", { href: e.ticketUrl }, "Billetter"),
- t("button", { onclick: () => share(e) }, "Del tid")
- ])
+
+ lis.push(
+ t("li", { class: "show", id: showKey }, [
+ t("span", { class: "title italic" }, showKey),
+ t("ul", undefined, [
+ t("li", undefined,
+ times.filter(e => e.ticketUrl !== "").map(e => {
+ const tagLine = `${e.scene} - ${[e.type, ...e.tags].join(", ")}`
+ return t("li", { class: `time time-${e.id}`, id: urlId(e) }, [
+ t("div", undefined, [
+ t("span", { title: e.startDateTime }, dateString(e.startDateTime)),
+ t("span", undefined, tagLine),
+ t("div", { class: "actions" }, [
+ t("a", { href: e.ticketUrl }, "Billetter"),
+ "share" in navigator ? t("button", { onclick: () => share(e) }, "Del tid") : null,
+ t("button", { onclick: () => copyLink(e) }, "Kopier lenke"),
+ t("a", { href: vegascene(e) }, "Åpne på vegascene.no")
+ ])
+ ])
+ ])
+ }))
])
- ])])))])]));
+ ])
+ )
}
- ulShows.replaceChildren(...lis);
+
+ if (!lis.length) ulShows.replaceChildren(...[t("i", undefined, "Dessverre")])
+ else ulShows.replaceChildren(...lis);
}
renderShows();
-