feat(*): add image grids for album and associated media displays

This commit is contained in:
Cory Dransfeldt 2025-05-24 17:19:30 -07:00
parent 9b4baad5fb
commit 36fbba761a
No known key found for this signature in database
53 changed files with 1179 additions and 764 deletions

View file

@ -1,19 +1,12 @@
<?php
function renderMediaGrid(array $items, string $cdnUrl, string $shape = 'square', int $count = 0, string $loading = 'lazy') {
$imageClass = 'square';
$width = 150;
$height = 150;
if ($shape === 'vertical') {
$imageClass = 'vertical';
$width = 120;
$height = 184;
}
function renderMediaGrid(array $items, int $count = 0, string $loading = 'lazy') {
$limit = $count > 0 ? $count : count($items);
$firstType = $items[0]['type'] ?? ($items[0]['grid']['type'] ?? '');
$shapeClass = in_array($firstType, ['books', 'movies', 'tv']) ? 'vertical' : 'square';
echo '<div class="media-grid ' . $shapeClass . '">';
echo '<div class="media-grid ' . htmlspecialchars($shape) . '">';
foreach (array_slice($items, 0, $limit) as $item) {
$grid = $item['grid'] ?? $item;
$alt = htmlspecialchars($grid['alt'] ?? '');
@ -21,8 +14,13 @@
$title = htmlspecialchars($grid['title'] ?? '');
$subtext = htmlspecialchars($grid['subtext'] ?? '');
$url = $grid['url'] ?? null;
$type = $item['type'] ?? '';
$isVertical = in_array($type, ['books', 'movies', 'tv']);
$imageClass = $isVertical ? 'vertical' : 'square';
$width = $isVertical ? 120 : 150;
$height = $isVertical ? 184 : 150;
$openLink = $url ? '<a href="' . htmlspecialchars($url) . '" title="' . $alt . '">' : '';
$openLink = $url ? '<a class="' . htmlspecialchars($type) . '" href="' . htmlspecialchars($url) . '" title="' . $alt . '">' : '';
$closeLink = $url ? '</a>' : '';
echo $openLink;
@ -36,10 +34,10 @@
}
echo '<img
srcset="' . $cdnUrl . $image . '?class=' . $imageClass . 'sm&type=webp ' . $width . 'w, ' .
$cdnUrl . $image . '?class=' . $imageClass . 'md&type=webp ' . ($width * 2) . 'w"
srcset="' . $image . '?class=' . $imageClass . 'sm&type=webp ' . $width . 'w, ' .
$image . '?class=' . $imageClass . 'md&type=webp ' . ($width * 2) . 'w"
sizes="(max-width: 450px) ' . $width . 'px, ' . ($width * 2) . 'px"
src="' . $cdnUrl . $image . '?class=' . $imageClass . 'sm&type=webp"
src="' . $image . '?class=' . $imageClass . 'sm&type=webp"
alt="' . $alt . '"
loading="' . $loading . '"
decoding="async"
@ -49,60 +47,48 @@
echo '</div>';
echo $closeLink;
}
echo '</div>';
}
function renderAssociatedMedia($artists = [], $books = [], $genres = [], $movies = [], $posts = [], $shows = [])
{
$media = array_merge($artists, $books, $genres, $movies, $posts, $shows);
if (empty($media)) return;
function renderAssociatedMedia(
array $artists = [],
array $books = [],
array $genres = [],
array $movies = [],
array $posts = [],
array $shows = [],
) {
$sections = [
"artists" => ["icon" => "headphones", "css_class" => "music", "label" => "Related artist(s)"],
"books" => ["icon" => "books", "css_class" => "books", "label" => "Related book(s)"],
"genres" => ["icon" => "headphones", "css_class" => "music", "label" => "Related genre(s)"],
"movies" => ["icon" => "movie", "css_class" => "movies", "label" => "Related movie(s)"],
"posts" => ["icon" => "article", "css_class" => "article", "label" => "Related post(s)"],
"shows" => ["icon" => "device-tv-old", "css_class" => "tv", "label" => "Related show(s)"]
"artists" => ["icon" => "headphones", "css_class" => "music", "label" => "Related artist(s)", "hasGrid" => true],
"books" => ["icon" => "books", "css_class" => "books", "label" => "Related book(s)", "hasGrid" => true],
"genres" => ["icon" => "headphones", "css_class" => "music", "label" => "Related genre(s)", "hasGrid" => false],
"movies" => ["icon" => "movie", "css_class" => "movies", "label" => "Related movie(s)", "hasGrid" => true],
"posts" => ["icon" => "article", "css_class" => "article", "label" => "Related post(s)", "hasGrid" => false],
"shows" => ["icon" => "device-tv-old", "css_class" => "tv", "label" => "Related show(s)", "hasGrid" => true]
];
$allMedia = compact('artists', 'books', 'genres', 'movies', 'posts', 'shows');
echo '<div class="associated-media">';
foreach ($sections as $key => $section) {
switch ($key) {
case "artists":
$items = $artists;
break;
case "books":
$items = $books;
break;
case "genres":
$items = $genres;
break;
case "movies":
$items = $movies;
break;
case "posts":
$items = $posts;
break;
case "shows":
$items = $shows;
break;
default:
$items = [];
}
$items = $allMedia[$key];
if (!empty($items)) {
echo '<p id="' . htmlspecialchars($key) . '" class="' . htmlspecialchars($section['css_class']) . '">';
echo '<span class="icon">' . getTablerIcon($section['icon']) . '</span> ';
echo htmlspecialchars($section['label']);
echo '</p>';
if (empty($items)) continue;
echo '<h3 id="' . htmlspecialchars($key) . '" class="' . htmlspecialchars($section['css_class']) . '">';
echo getTablerIcon($section['icon']);
echo htmlspecialchars($section['label']);
echo '</h3>';
if ($section['hasGrid']) {
renderMediaGrid($items);
} else {
echo '<ul>';
foreach ($items as $item) {
echo '<li class="' . htmlspecialchars($section['css_class']) . '">';
echo '<a href="' . htmlspecialchars($item['url']) . '">' . htmlspecialchars($item['title'] ?? $item['name'] ?? 'Untitled') . '</a>';
echo '<a href="' . htmlspecialchars($item['url']) . '">' . htmlspecialchars($item['title'] ?? $item['name'] ?? '') . '</a>';
if ($key === "artists" && isset($item['total_plays']) && $item['total_plays'] > 0) {
echo ' (' . htmlspecialchars($item['total_plays']) . ' play' . ($item['total_plays'] > 1 ? 's' : '') . ')';
@ -116,7 +102,6 @@
echo '</li>';
}
echo '</ul>';
}
}