aboutsummaryrefslogtreecommitdiffstats
path: root/partials/partials_vibe.php
diff options
context:
space:
mode:
authorsillylaird <sillyfanboy@gmail.com>2026-09-03 00:33:59 +0000
committersillylaird <sillyfanboy@gmail.com>2026-09-03 00:33:59 +0000
commit898b52edcb47bcb3e9d6106e74ca73e74ea01e70 (patch)
tree85c6ee5ad58b860144551184d4cf86b560c62b91 /partials/partials_vibe.php
downloadwww-898b52edcb47bcb3e9d6106e74ca73e74ea01e70.tar.gz
www-898b52edcb47bcb3e9d6106e74ca73e74ea01e70.zip
import live www.sillylaird.ca webrootHEADmain
Diffstat (limited to '')
-rw-r--r--partials/partials_vibe.php212
1 files changed, 212 insertions, 0 deletions
diff --git a/partials/partials_vibe.php b/partials/partials_vibe.php
new file mode 100644
index 0000000..aa77598
--- /dev/null
+++ b/partials/partials_vibe.php
@@ -0,0 +1,212 @@
+<?php
+// partials/vibe.php — renders "My Current Vibe" section
+// Reads from vibe.php config, detects URL type and embeds accordingly.
+
+$vibe = file_exists(__DIR__ . '/../vibe.php')
+ ? require __DIR__ . '/../vibe.php'
+ : ['description' => '', 'url' => '', 'updated' => ''];
+
+$vibe_section_title_raw = $vibe_section_title ?? 'My Current Vibe';
+$vibe_desc_raw = trim((string)($vibe['description'] ?? ''));
+$vibe_url = $vibe['url'] ?? '';
+$vibe_updated = htmlspecialchars($vibe['updated'] ?? '', ENT_QUOTES, 'UTF-8');
+
+// Hide description if it is empty or duplicates the section heading
+$show_desc = $vibe_desc_raw !== '' && strcasecmp($vibe_desc_raw, $vibe_section_title_raw) !== 0;
+$vibe_desc = htmlspecialchars($vibe_desc_raw, ENT_QUOTES, 'UTF-8');
+
+function vibe_detect_type(string $url): string {
+ if (empty($url)) return 'none';
+ $path = strtolower(parse_url($url, PHP_URL_PATH) ?? '');
+ $ext = pathinfo($path, PATHINFO_EXTENSION);
+
+ $images = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg', 'avif'];
+ $videos = ['mp4', 'webm', 'ogv', 'mov'];
+ $audio = ['mp3', 'flac', 'wav', 'ogg', 'aac', 'opus', 'm4a'];
+
+ if (in_array($ext, $images)) return 'image';
+ if (in_array($ext, $videos)) return 'video';
+ if (in_array($ext, $audio)) return 'audio';
+
+ if (preg_match('/(?:youtube\.com\/watch\?.*v=|youtu\.be\/|youtube\.com\/shorts\/)([A-Za-z0-9_-]{11})/', $url, $m))
+ return 'youtube:' . $m[1];
+
+ if (preg_match('/vimeo\.com\/(?:video\/)?(\d+)/', $url, $m))
+ return 'vimeo:' . $m[1];
+
+ // Dailymotion: dailymotion.com/video/{id} or dai.ly/{id} (id may have a _slug)
+ if (preg_match('#(?:dailymotion\.com/video|dai\.ly)/([A-Za-z0-9]+)#i', $url, $m))
+ return 'dailymotion:' . $m[1];
+
+ // Bilibili: bilibili.com/video/{BVxxxx} (BV id) or /video/av{n}
+ if (preg_match('#bilibili\.com/video/(BV[A-Za-z0-9]+)#i', $url, $m))
+ return 'bilibili:bvid:' . $m[1];
+ if (preg_match('#bilibili\.com/video/av(\d+)#i', $url, $m))
+ return 'bilibili:aid:' . $m[1];
+
+ // Niconico: nicovideo.jp/watch/{sm123} or nico.ms/{sm123}
+ if (preg_match('#(?:nicovideo\.jp/watch|nico\.ms)/((?:sm|nm|so)?\d+)#i', $url, $m))
+ return 'niconico:' . $m[1];
+
+ return 'link';
+}
+
+// Extract ?t= / &t= / #t= start offset for YouTube (supports `90`, `1m30s`, `1h2m3s`)
+function vibe_youtube_start(string $url): int {
+ $q = [];
+ parse_str((string)parse_url($url, PHP_URL_QUERY), $q);
+ $t = $q['t'] ?? $q['start'] ?? null;
+ if ($t === null) {
+ $frag = parse_url($url, PHP_URL_FRAGMENT) ?? '';
+ if (preg_match('/(?:^|&)t=([^&]+)/', $frag, $m)) $t = $m[1];
+ }
+ if ($t === null) return 0;
+ if (ctype_digit((string)$t)) return (int)$t;
+ if (preg_match('/^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/', $t, $m)) {
+ return ((int)($m[1] ?? 0)) * 3600 + ((int)($m[2] ?? 0)) * 60 + ((int)($m[3] ?? 0));
+ }
+ return 0;
+}
+
+// Map a detected iframe-provider type to an embed URL + friendly label.
+// Returns [] for non-iframe types (image/audio/video/link/none).
+function vibe_provider_embed(string $type, string $url): array {
+ if (str_starts_with($type, 'youtube:')) {
+ $id = substr($type, 8);
+ $start = vibe_youtube_start($url);
+ $embed = 'https://www.youtube-nocookie.com/embed/' . rawurlencode($id)
+ . '?rel=0&modestbranding=1' . ($start > 0 ? '&start=' . $start : '');
+ return ['embed' => $embed, 'label' => 'YouTube'];
+ }
+ if (str_starts_with($type, 'vimeo:')) {
+ $id = substr($type, 6);
+ return ['embed' => 'https://player.vimeo.com/video/' . rawurlencode($id) . '?dnt=1', 'label' => 'Vimeo'];
+ }
+ if (str_starts_with($type, 'dailymotion:')) {
+ $id = substr($type, 12);
+ return ['embed' => 'https://geo.dailymotion.com/player.html?video=' . rawurlencode($id), 'label' => 'Dailymotion'];
+ }
+ if (str_starts_with($type, 'bilibili:bvid:')) {
+ $id = substr($type, 14);
+ return ['embed' => 'https://player.bilibili.com/player.html?bvid=' . rawurlencode($id) . '&page=1&high_quality=1&danmaku=0', 'label' => 'Bilibili'];
+ }
+ if (str_starts_with($type, 'bilibili:aid:')) {
+ $id = substr($type, 13);
+ return ['embed' => 'https://player.bilibili.com/player.html?aid=' . rawurlencode($id) . '&page=1&high_quality=1&danmaku=0', 'label' => 'Bilibili'];
+ }
+ if (str_starts_with($type, 'niconico:')) {
+ $id = substr($type, 9);
+ return ['embed' => 'https://embed.nicovideo.jp/watch/' . rawurlencode($id), 'label' => 'Niconico'];
+ }
+ return [];
+}
+
+$type = vibe_detect_type($vibe_url);
+$safe_url = htmlspecialchars($vibe_url, ENT_QUOTES, 'UTF-8');
+?>
+
+<style>
+ .vibe-embed {
+ position: relative;
+ padding-top: 56.25%;
+ overflow: hidden;
+ border-radius: 6px;
+ background: #000;
+ margin: 0.5rem 0;
+ }
+ .vibe-embed > iframe,
+ .vibe-embed > video,
+ .vibe-embed > img {
+ position: absolute;
+ top: 0; left: 0;
+ width: 100%; height: 100%;
+ border: 0;
+ object-fit: contain;
+ }
+ .vibe-media-audio { width: 100%; margin: 0.5rem 0; }
+ .vibe-media-img { max-width: 100%; height: auto; border-radius: 6px; }
+ .vibe-caption {
+ margin: 0.25rem 0 0;
+ font-size: 0.9em;
+ opacity: 0.8;
+ }
+ .vibe-meta {
+ font-size: 0.85em;
+ opacity: 0.7;
+ margin: 0.5rem 0 0;
+ }
+</style>
+
+<section id="vibe" aria-labelledby="vibe-title" class="vibe-section">
+ <h2 id="vibe-title" class="section-accent-title"><?= htmlspecialchars($vibe_section_title_raw, ENT_QUOTES, 'UTF-8') ?></h2>
+
+ <?php if ($show_desc): ?>
+ <p><?= $vibe_desc ?></p>
+ <?php endif; ?>
+
+ <?php if ($vibe_url): ?>
+ <?php if ($type === 'image'): ?>
+ <a href="<?= $safe_url ?>" target="_blank" rel="noopener noreferrer">
+ <img class="vibe-media-img" src="<?= $safe_url ?>" alt="Current vibe" loading="lazy" decoding="async">
+ </a>
+
+ <?php elseif ($type === 'video'): ?>
+ <div class="vibe-embed">
+ <video controls preload="none">
+ <source src="<?= $safe_url ?>">
+ </video>
+ </div>
+ <p class="vibe-caption">
+ <a href="<?= $safe_url ?>" target="_blank" rel="noopener noreferrer">Open video ↗</a>
+ </p>
+
+ <?php elseif ($type === 'audio'): ?>
+ <audio class="vibe-media-audio" controls preload="none">
+ <source src="<?= $safe_url ?>">
+ Your browser does not support audio. <a href="<?= $safe_url ?>">Download it</a>.
+ </audio>
+ <p class="vibe-caption">
+ <a href="<?= $safe_url ?>" target="_blank" rel="noopener noreferrer">Open audio ↗</a>
+ </p>
+
+ <?php elseif ($prov = vibe_provider_embed($type, $vibe_url)): ?>
+ <?php
+ $embed = $prov['embed'];
+ $label = $prov['label'];
+ $safe_embed = htmlspecialchars($embed, ENT_QUOTES);
+ $safe_label = htmlspecialchars($label, ENT_QUOTES);
+ ?>
+ <div class="vibe-embed">
+ <noscript>
+ <iframe
+ src="<?= $safe_embed ?>"
+ title="Current vibe — <?= $safe_label ?> video"
+ loading="lazy"
+ referrerpolicy="strict-origin-when-cross-origin"
+ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen"
+ allowfullscreen></iframe>
+ </noscript>
+ <button type="button" class="vibe-facade js-only"
+ data-embed="<?= $safe_embed ?>"
+ aria-label="Load and play the <?= $safe_label ?> video">
+ <span class="vibe-facade-play" aria-hidden="true">▶</span>
+ <span class="vibe-facade-text">Load <?= $safe_label ?> video<br><small>Nothing loads from <?= $safe_label ?> until you click</small></span>
+ </button>
+ </div>
+ <p class="vibe-caption">
+ <a href="<?= $safe_url ?>" target="_blank" rel="noopener noreferrer">Watch on <?= $safe_label ?> ↗</a>
+ </p>
+
+ <?php else: ?>
+ <p>
+ <a href="<?= $safe_url ?>" target="_blank" rel="noopener noreferrer"><?= $safe_url ?></a>
+ </p>
+ <?php endif; ?>
+ <?php endif; ?>
+
+ <?php if ($vibe_updated): ?>
+ <p class="vibe-meta">Updated <?= $vibe_updated ?></p>
+ <?php endif; ?>
+
+ <?php if (!empty($vibe_section_extra)) echo $vibe_section_extra; ?>
+</section>