openvibers/openvibe.live Commits

OV mark: thumbnail placeholders, restream badge, settings empty state; version bumps

OP OpenVibers committed 16 Sept 2026 · a903a69c20 · 4 files, +11 −6

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CMxJm1dB8rdsaMSgNjVa82

Changes

ddiff --git a/public/css/style.css b/public/css/style.css
iindex fa1c6e1f..361a4306 100644
---- a/public/css/style.css
++++ b/public/css/style.css
@@@ -14804,3 +14804,4 @@ a .arena-thread:hover { color: var(--text-primary); background: color-mix(in srg
.rs-lite .ov-orbit, .rs-lite .ov-spark { filter: none; }
@media (prefers-reduced-motion: reduce) { .brand-mark svg, .ov-glow, .ov-comet, .ov-v, .ov-dot, .ov-spark { animation: none !important; } .ov-orbit, .ov-spark { display: none; } .ov-comet { stroke-dasharray: none; opacity: 0.9; } }
@media (max-width: 600px) { .brand-mark { width: 26px; height: 26px; } .brand-mark svg { width: 25px; height: 25px; } }
++.ov-mark--ph { opacity: 0.45; color: var(--text-muted); }
ddiff --git a/public/index.html b/public/index.html
iindex 34bd5b4e..6b93ec8e 100644
---- a/public/index.html
++++ b/public/index.html
@@@ -62,7 +62,7 @@
</script>
<!-- Stylesheets -->
-- <link rel="stylesheet" href="/css/style.css?v=163">
++ <link rel="stylesheet" href="/css/style.css?v=164">
<link rel="stylesheet" href="/css/chat-shared.css?v=1">
<link rel="stylesheet" href="/css/broadcast.css?v=11">
<link rel="stylesheet" href="/css/cosmetics.css?v=2">
@@@ -5088,7 +5088,7 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig
<!-- Scripts -->
<script src="/js/theme-engine.js?v=4"></script>
<script src="/live-notify.js?v=3" defer></script>
--<script src="/js/app.js?v=140" defer></script>
++<script src="/js/app.js?v=141" defer></script>
<script src="/js/stream-player.js?v=21" defer></script>
<script src="/js/stream-pip.js?v=1" defer></script>
<script src="/js/chat-shared.js?v=3" defer></script>
ddiff --git a/public/js/app.js b/public/js/app.js
iindex 1e701985..2dbd7c74 100644
---- a/public/js/app.js
++++ b/public/js/app.js
@@@ -4383,7 +4383,7 @@ function updateCumulativeViewers(liveStreams, rsRestream = {}, restreamLinks = n
// OpenVibe.Live-native viewer badge — styled like the platform restream badges, in brand
// green, so it reads as "this is the count HERE" alongside the RS/Twitch/etc badges.
if (liveStreams.length > 0) {
-- html += `<span class="ch-restream-badge" style="color:var(--accent)" title="Watching live on OpenVibe.Live${streamCount > 1 ? ` (across ${streamCount} streams)` : ''}"><i class="fa-solid fa-circle-nodes"></i> OV <i class="fa-solid fa-eye" style="font-size:0.75em"></i> ${hsTotal}</span>`;
++ html += `<span class="ch-restream-badge" style="color:var(--accent)" title="Watching live on OpenVibe.Live${streamCount > 1 ? ` (across ${streamCount} streams)` : ''}"><span class="ov-mark" data-size="14" data-static="1"></span> OV <i class="fa-solid fa-eye" style="font-size:0.75em"></i> ${hsTotal}</span>`;
}
// RS restream badge — reflect the WATCHED slot's robot only (not the first slot's).
@@@ -8089,14 +8089,18 @@ async function handleThumbnailError(img) {
}
function thumbImg(thumbnailUrl, fallbackIcon, alt, regenerateUrl = null) {
++ // The old brand glyph as a placeholder → the OV mark (static, muted).
++ const iconHtml = (extra) => fallbackIcon === 'fa-circle-nodes'
++ ? `<span class="ov-mark ov-mark--ph" data-size="44" data-static="1"${extra || ''}></span>`
++ : `<i class="fa-solid ${fallbackIcon}"${extra || ''}></i>`;
if (thumbnailUrl) {
return `<img src="${esc(thumbnailUrl)}" alt="${esc(alt || '')}" loading="lazy" data-regenerate-url="${esc(regenerateUrl || '')}" onerror="handleThumbnailError(this)">
-- <i class="fa-solid ${fallbackIcon}" style="display:none"></i>`;
++ ${iconHtml(' style="display:none"')}`;
}
if (regenerateUrl) {
// No thumbnail yet but we can try generating one — show icon and trigger generation
return `<img src="" alt="${esc(alt || '')}" style="display:none" data-regenerate-url="${esc(regenerateUrl)}" data-regenerate-tried="" onerror="handleThumbnailError(this)">
-- <i class="fa-solid ${fallbackIcon}"></i>`;
++ ${iconHtml()}`;
}
return `<i class="fa-solid ${fallbackIcon}"></i>`;
}
ddiff --git a/public/js/settings.js b/public/js/settings.js
iindex 3eac02a1..77b02748 100644
---- a/public/js/settings.js
++++ b/public/js/settings.js
@@@ -350,7 +350,7 @@ async function loadSettingsStreams() {
const allStreams = data.streams || [];
if (!allStreams.length) {
-- container.innerHTML = `<div class="empty-state"><i class="fa-solid fa-circle-nodes fa-3x" style="color:var(--accent)"></i><p>No streams yet</p><p class="muted">Go live from the <a href="#" onclick="event.preventDefault();navigate('/broadcast')">Go Live</a> page to create your first stream!</p></div>`;
++ container.innerHTML = `<div class="empty-state"><span class="ov-mark" data-size="44" data-static="1"></span><i class="fa-solid fa-circle-nodes" style="display:none" fa-3x" style="color:var(--accent)"></i><p>No streams yet</p><p class="muted">Go live from the <a href="#" onclick="event.preventDefault();navigate('/broadcast')">Go Live</a> page to create your first stream!</p></div>`;
return;
}