openvibers/openvibe.live Commits
Show unique views on VOD/clip/paste pages
Changes
@@@ -4999,7 +4999,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=127" defer></script>++<script src="/js/app.js?v=128" 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>@@@ -5072,7 +5072,7 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig<script src="/js/dashboard-moderation.js?v=5" defer></script><script src="/js/ai-viewers.js?v=2" defer></script><script src="/js/powerchat.js?v=8" defer></script>--<script src="/js/pastes.js?v=14" defer></script>++<script src="/js/pastes.js?v=15" defer></script><script src="/js/draggable-fab.js?v=2" defer></script><script src="/js/messenger.js?v=2" defer></script>@@@ -6291,7 +6291,7 @@ async function loadVodPlayer(vodId, seekTo) {{ const _a = document.getElementById('vp-avatar'); if (_a) _a.innerHTML = _avatarInner(v.avatar_url, v.username); }document.getElementById('vp-date').textContent = formatDateTime(v.created_at);document.getElementById('vp-duration').textContent = formatDuration(v.duration_seconds || v.duration);-- document.getElementById('vp-views').textContent = `${v.view_count || 0} views`;++ document.getElementById('vp-views').textContent = `${v.view_count || 0} views${v.unique_views != null ? ` · ${v.unique_views} unique` : ''}`;document.getElementById('vp-description').textContent = v.description || '';_renderMediaAiOverview('vp-description', v.ai_overview);_renderMediaTranscript('vp-description', 'vod', v);@@@ -6990,7 +6990,7 @@ async function loadClipPlayer(clipId) {// View countconst clpViews = document.getElementById('clp-views');-- if (clpViews) clpViews.textContent = `${cl.view_count || 0} views`;++ if (clpViews) clpViews.textContent = `${cl.view_count || 0} views${cl.unique_views != null ? ` · ${cl.unique_views} unique` : ''}`;// Protocol badgeconst clpProto = document.getElementById('clp-protocol');@@@ -486,7 +486,7 @@ async function loadPasteViewer(slug) {<div class="paste-view-meta"><span><i class="fa-solid fa-user"></i> ${escapeHtml(author)}</span><span><i class="fa-solid fa-clock"></i> ${formatTimeAgo(p.created_at)}</span>-- <span><i class="fa-solid fa-eye"></i> ${p.views} view${p.views !== 1 ? 's' : ''}</span>++ <span title="Views count once per visitor per 6 hours; unique = distinct visitors"><i class="fa-solid fa-eye"></i> ${p.views} view${p.views !== 1 ? 's' : ''}${p.unique_views != null ? ` · ${p.unique_views} unique` : ''}</span><span><i class="fa-solid fa-copy"></i> ${p.copies || 0} cop${(p.copies || 0) !== 1 ? 'ies' : 'y'}</span><button class="paste-like-btn ${userLiked ? 'liked' : ''}" id="paste-like-btn"onclick="togglePasteLike('${p.slug}')" title="${isLoggedIn ? (userLiked ? 'Unlike' : 'Like') : 'Log in to like'}">
@@ -4999,7 +4999,7 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig
@@ -4999,7 +4999,7 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig
<!-- Scripts -->
<!-- Scripts -->
<script src="/js/theme-engine.js?v=4"></script>
<script src="/js/theme-engine.js?v=4"></script>
<script src="/live-notify.js?v=3" defer></script>
<script src="/live-notify.js?v=3" defer></script>
-<script src="/js/app.js?v=127" defer></script>
+<script src="/js/app.js?v=128" defer></script>
<script src="/js/stream-player.js?v=21" 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/stream-pip.js?v=1" defer></script>
<script src="/js/chat-shared.js?v=3" defer></script>
<script src="/js/chat-shared.js?v=3" defer></script>
@@ -5072,7 +5072,7 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig
@@ -5072,7 +5072,7 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig
<script src="/js/dashboard-moderation.js?v=5" defer></script>
<script src="/js/dashboard-moderation.js?v=5" defer></script>
<script src="/js/ai-viewers.js?v=2" defer></script>
<script src="/js/ai-viewers.js?v=2" defer></script>
<script src="/js/powerchat.js?v=8" defer></script>
<script src="/js/powerchat.js?v=8" defer></script>
-<script src="/js/pastes.js?v=14" defer></script>
+<script src="/js/pastes.js?v=15" defer></script>
<script src="/js/draggable-fab.js?v=2" defer></script>
<script src="/js/draggable-fab.js?v=2" defer></script>
<script src="/js/messenger.js?v=2" defer></script>
<script src="/js/messenger.js?v=2" defer></script>
@@ -6291,7 +6291,7 @@ async function loadVodPlayer(vodId, seekTo) {
@@ -6291,7 +6291,7 @@ async function loadVodPlayer(vodId, seekTo) {
{ const _a = document.getElementById('vp-avatar'); if (_a) _a.innerHTML = _avatarInner(v.avatar_url, v.username); }
{ const _a = document.getElementById('vp-avatar'); if (_a) _a.innerHTML = _avatarInner(v.avatar_url, v.username); }
document.getElementById('vp-date').textContent = formatDateTime(v.created_at);
document.getElementById('vp-date').textContent = formatDateTime(v.created_at);
document.getElementById('vp-duration').textContent = formatDuration(v.duration_seconds || v.duration);
document.getElementById('vp-duration').textContent = formatDuration(v.duration_seconds || v.duration);
- document.getElementById('vp-views').textContent = `${v.view_count || 0} views`;
+ document.getElementById('vp-views').textContent = `${v.view_count || 0} views${v.unique_views != null ? ` · ${v.unique_views} unique` : ''}`;
document.getElementById('vp-description').textContent = v.description || '';
document.getElementById('vp-description').textContent = v.description || '';
_renderMediaAiOverview('vp-description', v.ai_overview);
_renderMediaAiOverview('vp-description', v.ai_overview);
_renderMediaTranscript('vp-description', 'vod', v);
_renderMediaTranscript('vp-description', 'vod', v);
@@ -6990,7 +6990,7 @@ async function loadClipPlayer(clipId) {
@@ -6990,7 +6990,7 @@ async function loadClipPlayer(clipId) {
// View count
// View count
const clpViews = document.getElementById('clp-views');
const clpViews = document.getElementById('clp-views');
- if (clpViews) clpViews.textContent = `${cl.view_count || 0} views`;
+ if (clpViews) clpViews.textContent = `${cl.view_count || 0} views${cl.unique_views != null ? ` · ${cl.unique_views} unique` : ''}`;
// Protocol badge
// Protocol badge
const clpProto = document.getElementById('clp-protocol');
const clpProto = document.getElementById('clp-protocol');
@@ -486,7 +486,7 @@ async function loadPasteViewer(slug) {
@@ -486,7 +486,7 @@ async function loadPasteViewer(slug) {
<div class="paste-view-meta">
<div class="paste-view-meta">
<span><i class="fa-solid fa-user"></i> ${escapeHtml(author)}</span>
<span><i class="fa-solid fa-user"></i> ${escapeHtml(author)}</span>
<span><i class="fa-solid fa-clock"></i> ${formatTimeAgo(p.created_at)}</span>
<span><i class="fa-solid fa-clock"></i> ${formatTimeAgo(p.created_at)}</span>
- <span><i class="fa-solid fa-eye"></i> ${p.views} view${p.views !== 1 ? 's' : ''}</span>
+ <span title="Views count once per visitor per 6 hours; unique = distinct visitors"><i class="fa-solid fa-eye"></i> ${p.views} view${p.views !== 1 ? 's' : ''}${p.unique_views != null ? ` · ${p.unique_views} unique` : ''}</span>
<span><i class="fa-solid fa-copy"></i> ${p.copies || 0} cop${(p.copies || 0) !== 1 ? 'ies' : 'y'}</span>
<span><i class="fa-solid fa-copy"></i> ${p.copies || 0} cop${(p.copies || 0) !== 1 ? 'ies' : 'y'}</span>
<button class="paste-like-btn ${userLiked ? 'liked' : ''}" id="paste-like-btn"
<button class="paste-like-btn ${userLiked ? 'liked' : ''}" id="paste-like-btn"
onclick="togglePasteLike('${p.slug}')" title="${isLoggedIn ? (userLiked ? 'Unlike' : 'Like') : 'Log in to like'}">
onclick="togglePasteLike('${p.slug}')" title="${isLoggedIn ? (userLiked ? 'Unlike' : 'Like') : 'Log in to like'}">