feat(*.php, *.psql): deduplicate API code + performance improvements

This commit is contained in:
Cory Dransfeldt 2025-04-22 12:39:42 -07:00
parent cf3dac8a46
commit 4bad005e58
No known key found for this signature in database
31 changed files with 502 additions and 666 deletions

View file

@ -1,48 +1,80 @@
window.addEventListener("load", () => {
// dialog controls
(() => {
if (document.querySelectorAll(".dialog-open").length) {
document.querySelectorAll(".dialog-open").forEach((button) => {
const dialogId = button.getAttribute("data-dialog-trigger");
const dialog = document.getElementById(`dialog-${dialogId}`);
const dialogButtons = document.querySelectorAll(".dialog-open");
if (!dialogButtons.length) return;
if (!dialog) return;
dialogButtons.forEach((button) => {
const dialogId = button.getAttribute("data-dialog-trigger");
const dialog = document.getElementById(`dialog-${dialogId}`);
if (!dialog) return;
const closeButton = dialog.querySelector(".dialog-close");
const closeButton = dialog.querySelector(".dialog-close");
button.addEventListener("click", () => {
dialog.showModal();
dialog.classList.remove("closing");
});
button.addEventListener("click", async () => {
const isDynamic = dialog.dataset.dynamic;
const isLoaded = dialog.dataset.loaded;
if (closeButton)
closeButton.addEventListener("click", () => {
dialog.classList.add("closing");
setTimeout(() => dialog.close(), 200);
});
if (isDynamic && !isLoaded) {
const markdownFields = dialog.dataset.markdown || "";
try {
const res = await fetch(`/api/proxy.php?data=${isDynamic}&id=${dialogId}&markdown=${encodeURIComponent(markdownFields)}`);
const [data] = await res.json();
const firstField = markdownFields.split(",")[0]?.trim();
const html = data?.[`${firstField}_html`] || "<p>No notes available.</p>";
dialog.addEventListener("click", (event) => {
const rect = dialog.getBoundingClientRect();
dialog.querySelectorAll(".dialog-dynamic").forEach((el) => el.remove());
if (
event.clientX < rect.left ||
event.clientX > rect.right ||
event.clientY < rect.top ||
event.clientY > rect.bottom
) {
dialog.classList.add("closing");
setTimeout(() => dialog.close(), 200);
const container = document.createElement("div");
container.classList.add("dialog-dynamic");
container.innerHTML = html;
dialog.appendChild(container);
dialog.dataset.loaded = "true";
} catch (err) {
dialog.querySelectorAll(".dialog-dynamic").forEach((el) => el.remove());
const errorNode = document.createElement("div");
errorNode.classList.add("dialog-dynamic");
errorNode.textContent = "Failed to load content.";
dialog.appendChild(errorNode);
console.warn("Dialog content load error:", err);
}
});
}
dialog.showModal();
dialog.classList.remove("closing");
});
dialog.addEventListener("cancel", (event) => {
event.preventDefault();
if (closeButton) {
closeButton.addEventListener("click", () => {
dialog.classList.add("closing");
setTimeout(() => dialog.close(), 200);
});
}
dialog.addEventListener("click", (event) => {
const rect = dialog.getBoundingClientRect();
const outsideClick =
event.clientX < rect.left ||
event.clientX > rect.right ||
event.clientY < rect.top ||
event.clientY > rect.bottom;
if (outsideClick) {
dialog.classList.add("closing");
setTimeout(() => dialog.close(), 200);
}
});
}
dialog.addEventListener("cancel", (event) => {
event.preventDefault();
dialog.classList.add("closing");
setTimeout(() => dialog.close(), 200);
});
});
})();
// text toggle for media pages
@ -51,12 +83,9 @@ window.addEventListener("load", () => {
const content = document.querySelector("[data-toggle-content]");
const text = document.querySelectorAll("[data-toggle-content] p");
const minHeight = 500; // this needs to match the height set on [data-toggle-content].text-toggle-hidden in text-toggle.css
const interiorHeight = Array.from(text).reduce(
(acc, node) => acc + node.scrollHeight,
0,
);
const interiorHeight = Array.from(text).reduce((acc, node) => acc + node.scrollHeight, 0);
if (!button || !content || !text) return;
if (!button || !content || !text.length) return;
if (interiorHeight < minHeight) {
content.classList.remove("text-toggle-hidden");

View file

@ -6,22 +6,6 @@
font-display: swap;
}
@font-face {
font-family: 'Lexend';
src: url('/assets/fonts/ll.woff2') format('woff2');
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Lexend';
src: url('/assets/fonts/lb.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Space Grotesk";
src: url("/assets/fonts/sg.woff2") format("woff2");

View file

@ -1,7 +1,7 @@
html,
body {
font-family: var(--font-body);
font-weight: var(--font-weight-light);
font-weight: var(--font-weight-regular);
color: var(--text-color);
background: var(--background-color);
}

View file

@ -71,7 +71,7 @@
--border-gray: 1px solid var(--gray-light);
/* fonts */
--font-body: "Lexend", -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, Cantarell, Ubuntu, roboto, noto, helvetica, arial, sans-serif;
--font-body: Helvetica Neue, Helvetica, Arial, sans-serif;
--font-heading: "Space Grotesk", "Arial Black", "Arial Bold", Gadget, sans-serif;
--font-code: "MonoLisa", SFMono-Regular, Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
@ -84,7 +84,6 @@
--font-size-2xl: 1.45rem;
--font-size-3xl: 1.6rem;
--font-weight-light: 300;
--font-weight-regular: 400;
--font-weight-bold: 700;

View file

@ -54,7 +54,7 @@ dialog {
font-size: var(--font-size-lg);
}
h1, h2, h3 {
* {
margin-top: 0;
}

View file

@ -9,9 +9,15 @@
<button class="dialog-open client-side" aria-label="{{ label }}" data-dialog-trigger="{{ dialogId }}" data-dialog-button>
{{ labelContent }}
</button>
<dialog id="dialog-{{ dialogId }}" class="client-side">
<dialog
id="dialog-{{ dialogId }}"
class="client-side"
{% if dynamic %}data-dynamic="{{ dynamic }}"{% endif %}
{% if markdown %}data-markdown="{{ markdown }}"{% endif %}>
<button class="dialog-close" aria-label="Close dialog" data-dialog-button>
{% tablericon "circle-x" %}
</button>
{%- unless dynamic -%}
{{ content }}
{%- endunless -%}
</dialog>

View file

@ -15,12 +15,13 @@
• {{ item.label }}
<span class="client-side">
{%- if item.notes -%}
{% assign notes = item.notes | prepend: "### Notes\n" | markdown %}
{% assign notes = item.notes | markdown %}
{% render "blocks/dialog.liquid",
icon:"info-circle",
label:"View info about this concert"
content:notes,
id:item.content_date
dynamic:"optimized_concerts",
markdown:"concert_notes",
id:item.id
%}
{%- endif -%}
</span>

View file

@ -3,8 +3,6 @@
<head>
<meta charset="utf-8" />
<link rel="preload" href="/assets/fonts/sg.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" href="/assets/fonts/ll.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" href="/assets/fonts/lb.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" href="/assets/fonts/ml.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<noscript>
<link rel="stylesheet" href="/assets/styles/noscript.css?v={% appVersion %}" type="text/css" />

View file

@ -84,7 +84,7 @@ schema: artist
$dialogId = "dialog-" . htmlspecialchars($concert["id"]);
?>
<li class="concerts">
On <mark><?php echo date("F j, Y", strtotime($concert["date"])); ?></mark>
On&puncsp;<mark><?php echo date("F j, Y", strtotime($concert["date"])); ?></mark>&puncsp;
<?php if (!empty($venue)): ?>
at <?php echo $venue; ?>
<?php endif; ?>

View file

@ -41,7 +41,7 @@ schema: book
<span class="sub-meta tattoo">{% tablericon "needle" %} I have a tattoo inspired by this book!</span>
<?php endif; ?>
<?php if ($book["status"] == 'finished'): ?>
<span class="sub-meta">Finished on: <mark><?= date('F j, Y', strtotime($book["date_finished"])) ?></mark></span>
<span class="sub-meta">Finished on:&puncsp;<mark><?= date('F j, Y', strtotime($book["date_finished"])) ?></mark></span>
<?php elseif ($book["status"] == 'started'): ?>
<progress value="<?= htmlspecialchars($book["progress"]) ?>" max="100"><?php $book["progress"] . '%'; ?></progress>
<?php endif; ?>

View file

@ -8,7 +8,7 @@ schema: genre
<article class="genre-focus">
<?php $artistCount = count($genre["artists"]); ?>
<?php if ($artistCount > 0): ?>
<p>My top <mark><?= htmlspecialchars($genre["name"]) ?></mark>&thinsp;artists are
<p>My top&puncsp;<mark><?= htmlspecialchars($genre["name"]) ?></mark>&puncsp;artists are
<?php
$artists = array_slice($genre["artists"], 0, 5);
$artistLinks = [];
@ -16,7 +16,7 @@ schema: genre
$artistLinks[] = '<a href="' . htmlspecialchars($artist["url"]) . '">' . htmlspecialchars($artist["name"]) . '</a>';
}
echo implode(', ', $artistLinks);
?>. I've listened to <mark><?= $genre["total_plays"] . ' ' . pluralize($genre["total_plays"], "play") ?></mark>&thinsp;tracks from this genre.</p>
?>. I've listened to&puncsp;<mark><?= $genre["total_plays"] . ' ' . pluralize($genre["total_plays"], "play") ?></mark>&puncsp;tracks from this genre.</p>
<hr />
<?php endif; ?>
<?php

View file

@ -33,10 +33,7 @@ schema: show
<span class="sub-meta tattoo">{% tablericon "needle" %} I have a tattoo inspired by this show!</span>
<?php endif; ?>
<?php if (!empty($show["episode"]["formatted_episode"])): ?>
<span class="sub-meta">I last watched
<mark><?= htmlspecialchars($show["episode"]["formatted_episode"]) ?></mark>&thinsp;
on <?= date('F j, Y', strtotime($show["episode"]["last_watched_at"])) ?>.
</span>
<span class="sub-meta">I last watched&puncsp;<mark><?= htmlspecialchars($show["episode"]["formatted_episode"]) ?></mark>&puncsp;on <?= date('F j, Y', strtotime($show["episode"]["last_watched_at"])) ?>.</span>
<?php endif; ?>
</div>
<?php if (!empty($show["review"])): ?>

View file

@ -5,7 +5,7 @@ schema: tags
---
<a class="back-link" href="/tags" title="Go back to the tags index page">{% tablericon "arrow-left" %} Back to tags</a>
<h2 class="page-title">#<?= htmlspecialchars($tag) ?></h2>
<p><mark><?= number_format($totalCount) ?> item<?= $totalCount === 1 ? '' : 's' ?></mark>&thinsp;items tagged with <mark>#<?= htmlspecialchars($tag) ?></mark>. <a class="search" href="/search">You can search my site as well</a>.</p>
<p><mark><?= number_format($totalCount) ?>&puncsp;item<?= $totalCount === 1 ? '' : 's' ?></mark>&puncsp;items tagged with&puncsp;<mark>#<?= htmlspecialchars($tag) ?></mark>. <a class="search" href="/search">You can search my site as well</a>.</p>
<hr />
<?php foreach ($tagged as $item): ?>
<article class="<?= $item['type'] ?>">
@ -19,9 +19,9 @@ schema: tags
• <?= $item['label'] ?>
</aside>
<h3>
<a href="<?= htmlspecialchars($item['url']) ?>"><?= htmlspecialchars($item['title']) ?><?php if (!empty($item['rating'])): ?>&thinsp;(<?= $item['rating'] ?>)<?php endif; ?></a>
<a href="<?= htmlspecialchars($item['url']) ?>"><?= htmlspecialchars($item['title']) ?><?php if (!empty($item['rating'])): ?>&puncsp;(<?= $item['rating'] ?>)<?php endif; ?></a>
<?php if (!empty($item['author'])): ?>
&thinsp;via&thinsp;
&puncsp;via&puncsp;
<?php if (!empty($item['author']['url'])): ?>
<a href="<?= $item['author']['url'] ?>">
<?= $item['author']['name'] ?>

View file

@ -33,12 +33,13 @@ permalink: "/music/concerts/{% if pagination.pageNumber > 0 %}{{ pagination.page
<strong>{{ artistName }}</strong> on {{ concert.date | date: "%B %e, %Y" }}
{% if venue %} at {{ venue }}{% endif %}
<span class="client-side" style="display:inline">
{%- if concert.notes -%}
{% assign notes = concert.notes | prepend: "### Notes\n" | markdown %}
{%- if concert.concert_notes -%}
{% assign notes = concert.concert_notes | markdown %}
{% render "blocks/dialog.liquid",
icon:"info-circle",
label:"View info about this concert"
content:notes,
dynamic:"optimized_concerts",
markdown:"concert_notes",
id:concert.id
%}
{%- endif -%}