openvibers/openvibe.live Commits
The home page leads with live content and creators (roadmap 32.7, critique 1): the creator rows (Recently Online, Recent VODs, Recent Clips, Recent Pastes) move from under the site's introduction to above it, after the digest, star and pulse and before AI Moments (33.6: made, then derived), so the restream tour and the collapsed About banner follow what people made. Live Now stays first; nothing is removed, ids and header-before-grid pairs are unchanged, the home budgets hold (HTML 83.1 KB). test/home-order.test.js
Changes
@@@ -306,6 +306,44 @@<div class="pulse-grid" id="pulse-grid"></div></div>++ <!-- What people made, above the introduction to the site (roadmap 32.7: the home leads with live++ content and creators): channels that were just on, their recordings, the clips people took++ and their pastes. What the AI made follows it (AI Moments; 33.6: made, then derived). -->++ <!-- Recently Online -->++ <div class="section-header" style="--sc:#60a5fa">++ <h2><i class="fa-solid fa-clock-rotate-left"></i> Recently Online<small class="section-kicker">just missed them</small></h2>++ </div>++ <div class="stream-grid" id="stream-grid-recent">++ <div class="empty-state">++ <p class="muted">No recent streams</p>++ </div>++ </div>++ <div id="stream-grid-recent-pagination" class="pastes-pagination" style="display:none"></div>++++ <!-- Recent VODs -->++ <div class="section-header" style="--sc:#a78bfa;display:none" id="home-recent-vods-header">++ <h2><i class="fa-solid fa-video"></i> Recent VODs<small class="section-kicker">full streams</small></h2>++ <a href="/content?type=vods" onclick="return handleLinkClick(event, '/content?type=vods')" class="section-action">View all</a>++ </div>++ <div class="stream-grid" id="home-recent-vods-grid"></div>++ <div id="home-recent-vods-pagination" class="pastes-pagination" style="display:none"></div>++++ <!-- Recent Clips -->++ <div class="section-header" style="--sc:#f472b6;display:none" id="home-clips-header">++ <h2><i class="fa-solid fa-scissors"></i> Recent Clips<small class="section-kicker">the good bits</small></h2>++ <a href="/content?type=clips" onclick="return handleLinkClick(event, '/content?type=clips')" class="section-action">View all</a>++ </div>++ <div class="stream-grid home-clips-grid" id="home-clips-grid"></div>++ <div id="home-clips-pagination" class="pastes-pagination" style="display:none"></div>++++ <!-- Recent Pastes -->++ <div class="section-header" style="--sc:#2dd4bf;display:none" id="home-pastes-header">++ <h2><i class="fa-solid fa-paste"></i> Recent Pastes<small class="section-kicker">shots & snippets</small></h2>++ <a href="/content?type=pastes" onclick="return handleLinkClick(event, '/content?type=pastes')" class="section-action">View all</a>++ </div>++ <div class="home-pastes-list" id="home-pastes-list"></div>++ <div id="home-pastes-pagination" class="pastes-pagination" style="display:none"></div>++<!-- AI Moments showcase --><div class="home-section-lazy" id="home-moments-section" style="display:none"><div class="section-header" style="--sc:#22d3ee">@@@ -459,41 +497,6 @@</div><div class="container">-- <!-- Recently Online -->-- <div class="section-header" style="--sc:#60a5fa">-- <h2><i class="fa-solid fa-clock-rotate-left"></i> Recently Online<small class="section-kicker">just missed them</small></h2>-- </div>-- <div class="stream-grid" id="stream-grid-recent">-- <div class="empty-state">-- <p class="muted">No recent streams</p>-- </div>-- </div>-- <div id="stream-grid-recent-pagination" class="pastes-pagination" style="display:none"></div>---- <!-- Recent VODs -->-- <div class="section-header" style="--sc:#a78bfa;display:none" id="home-recent-vods-header">-- <h2><i class="fa-solid fa-video"></i> Recent VODs<small class="section-kicker">full streams</small></h2>-- <a href="/content?type=vods" onclick="return handleLinkClick(event, '/content?type=vods')" class="section-action">View all</a>-- </div>-- <div class="stream-grid" id="home-recent-vods-grid"></div>-- <div id="home-recent-vods-pagination" class="pastes-pagination" style="display:none"></div>---- <!-- Recent Clips -->-- <div class="section-header" style="--sc:#f472b6;display:none" id="home-clips-header">-- <h2><i class="fa-solid fa-scissors"></i> Recent Clips<small class="section-kicker">the good bits</small></h2>-- <a href="/content?type=clips" onclick="return handleLinkClick(event, '/content?type=clips')" class="section-action">View all</a>-- </div>-- <div class="stream-grid home-clips-grid" id="home-clips-grid"></div>-- <div id="home-clips-pagination" class="pastes-pagination" style="display:none"></div>---- <!-- Recent Pastes -->-- <div class="section-header" style="--sc:#2dd4bf;display:none" id="home-pastes-header">-- <h2><i class="fa-solid fa-paste"></i> Recent Pastes<small class="section-kicker">shots & snippets</small></h2>-- <a href="/content?type=pastes" onclick="return handleLinkClick(event, '/content?type=pastes')" class="section-action">View all</a>-- </div>-- <div class="home-pastes-list" id="home-pastes-list"></div>-- <div id="home-pastes-pagination" class="pastes-pagination" style="display:none"></div>--<!-- Scraplandia Leaderboards --><div class="section-header" style="--sc:#fbbf24;display:none" id="home-quest-header"><h2><i class="fa-solid fa-trophy"></i> Scraplandia Leaderboards<small class="section-kicker">the ladder</small></h2>nnew file mode 100644@@@ -0,0 +1,68 @@++/**++ * The home page leads with live content and creators (roadmap 32.7, critique 1): Live Now first,++ * then, above the introduction to the site (the restream tour and the collapsed About banner), what++ * people made (Recently Online, Recent VODs, Recent Clips, Recent Pastes), then what the AI made++ * (AI Moments; 33.6: made, then derived). Nothing else on the page was removed.++ *++ * node test/home-order.test.js++ */++'use strict';++const assert = require('assert');++++const assets = require('../server/web/assets');++try { assets.setSharedDir(require('openvibe-shared/files').dir); } catch { /* */ }++const html = assets.renderRoute(assets.document('index.html').html, '/');++const home = html.slice(html.indexOf('<section id="page-home"'), html.indexOf('</section>', html.indexOf('<section id="page-home"')));++const at = (needle) => {++ const i = home.indexOf(needle);++ assert.ok(i >= 0, `${needle} is on the home page`);++ return i;++};++++let failures = 0;++function check(name, fn) {++ try { fn(); console.log(' ✓', name); }++ catch (e) { failures++; console.log(' ✗', name, '\n ', e.message); }++}++++console.log('Home order');++++check('Live Now is the first section after the hero', () => {++ const live = at('id="stream-grid-live"');++ for (const id of ['stream-grid-recent', 'home-recent-vods-grid', 'home-clips-grid', 'home-pastes-list', 'home-moments-section', 'home-tour-mount', 'home-cta-banner', 'home-digest', 'home-star-section']) {++ assert.ok(live < at(`id="${id}"`), `Live Now before ${id}`);++ }++});++++check('the creator rows sit above the introduction (tour and About banner)', () => {++ const intro = Math.min(at('id="home-tour-mount"'), at('id="home-cta-banner"'));++ for (const id of ['stream-grid-recent', 'home-recent-vods-grid', 'home-clips-grid', 'home-pastes-list']) {++ assert.ok(at(`id="${id}"`) < intro, `${id} above the introduction`);++ }++});++++check("people's work comes before the AI's", () => {++ const ai = at('id="home-moments-section"');++ for (const id of ['stream-grid-recent', 'home-recent-vods-grid', 'home-clips-grid', 'home-pastes-list']) {++ assert.ok(at(`id="${id}"`) < ai, `${id} before AI Moments`);++ }++});++++check('each rail keeps its header right before its grid (the density control reads it)', () => {++ const recent = at('id="stream-grid-recent"');++ const header = home.lastIndexOf('<div class="section-header"', recent);++ assert.ok(home.slice(header, recent).includes('Recently Online'));++});++++check('nothing was removed', () => {++ for (const id of ['home-featured', 'stream-grid-live', 'home-digest', 'home-star-section', 'hero-egg', 'home-pulse-section',++ 'stream-grid-recent', 'stream-grid-recent-pagination', 'home-recent-vods-header', 'home-recent-vods-grid', 'home-clips-header',++ 'home-clips-grid', 'home-pastes-header', 'home-pastes-list', 'home-moments-section', 'home-tour-mount', 'home-cta-banner',++ 'home-about-body', 'home-quest-header', 'home-leaderboards', 'home-canvas-header', 'home-canvas-preview']) {++ at(`id="${id}"`);++ }++ assert.ok(home.includes('class="network-hub"'));++});++++console.log(failures ? `\n${failures} check(s) failed` : '\nhome order: all checks passed');++process.exit(failures ? 1 : 0);
@@ -306,6 +306,44 @@
@@ -306,6 +306,44 @@
<div class="pulse-grid" id="pulse-grid"></div>
<div class="pulse-grid" id="pulse-grid"></div>
</div>
</div>
+ <!-- What people made, above the introduction to the site (roadmap 32.7: the home leads with live
+ content and creators): channels that were just on, their recordings, the clips people took
+ and their pastes. What the AI made follows it (AI Moments; 33.6: made, then derived). -->
+ <!-- Recently Online -->
+ <div class="section-header" style="--sc:#60a5fa">
+ <h2><i class="fa-solid fa-clock-rotate-left"></i> Recently Online<small class="section-kicker">just missed them</small></h2>
+ </div>
+ <div class="stream-grid" id="stream-grid-recent">
+ <div class="empty-state">
+ <p class="muted">No recent streams</p>
+ </div>
+ </div>
+ <div id="stream-grid-recent-pagination" class="pastes-pagination" style="display:none"></div>
+
+ <!-- Recent VODs -->
+ <div class="section-header" style="--sc:#a78bfa;display:none" id="home-recent-vods-header">
+ <h2><i class="fa-solid fa-video"></i> Recent VODs<small class="section-kicker">full streams</small></h2>
+ <a href="/content?type=vods" onclick="return handleLinkClick(event, '/content?type=vods')" class="section-action">View all</a>
+ </div>
+ <div class="stream-grid" id="home-recent-vods-grid"></div>
+ <div id="home-recent-vods-pagination" class="pastes-pagination" style="display:none"></div>
+
+ <!-- Recent Clips -->
+ <div class="section-header" style="--sc:#f472b6;display:none" id="home-clips-header">
+ <h2><i class="fa-solid fa-scissors"></i> Recent Clips<small class="section-kicker">the good bits</small></h2>
+ <a href="/content?type=clips" onclick="return handleLinkClick(event, '/content?type=clips')" class="section-action">View all</a>
+ </div>
+ <div class="stream-grid home-clips-grid" id="home-clips-grid"></div>
+ <div id="home-clips-pagination" class="pastes-pagination" style="display:none"></div>
+
+ <!-- Recent Pastes -->
+ <div class="section-header" style="--sc:#2dd4bf;display:none" id="home-pastes-header">
+ <h2><i class="fa-solid fa-paste"></i> Recent Pastes<small class="section-kicker">shots & snippets</small></h2>
+ <a href="/content?type=pastes" onclick="return handleLinkClick(event, '/content?type=pastes')" class="section-action">View all</a>
+ </div>
+ <div class="home-pastes-list" id="home-pastes-list"></div>
+ <div id="home-pastes-pagination" class="pastes-pagination" style="display:none"></div>
+
<!-- AI Moments showcase -->
<!-- AI Moments showcase -->
<div class="home-section-lazy" id="home-moments-section" style="display:none">
<div class="home-section-lazy" id="home-moments-section" style="display:none">
<div class="section-header" style="--sc:#22d3ee">
<div class="section-header" style="--sc:#22d3ee">
@@ -459,41 +497,6 @@
@@ -459,41 +497,6 @@
</div>
</div>
<div class="container">
<div class="container">
- <!-- Recently Online -->
- <div class="section-header" style="--sc:#60a5fa">
- <h2><i class="fa-solid fa-clock-rotate-left"></i> Recently Online<small class="section-kicker">just missed them</small></h2>
- </div>
- <div class="stream-grid" id="stream-grid-recent">
- <div class="empty-state">
- <p class="muted">No recent streams</p>
- </div>
- </div>
- <div id="stream-grid-recent-pagination" class="pastes-pagination" style="display:none"></div>
-
- <!-- Recent VODs -->
- <div class="section-header" style="--sc:#a78bfa;display:none" id="home-recent-vods-header">
- <h2><i class="fa-solid fa-video"></i> Recent VODs<small class="section-kicker">full streams</small></h2>
- <a href="/content?type=vods" onclick="return handleLinkClick(event, '/content?type=vods')" class="section-action">View all</a>
- </div>
- <div class="stream-grid" id="home-recent-vods-grid"></div>
- <div id="home-recent-vods-pagination" class="pastes-pagination" style="display:none"></div>
-
- <!-- Recent Clips -->
- <div class="section-header" style="--sc:#f472b6;display:none" id="home-clips-header">
- <h2><i class="fa-solid fa-scissors"></i> Recent Clips<small class="section-kicker">the good bits</small></h2>
- <a href="/content?type=clips" onclick="return handleLinkClick(event, '/content?type=clips')" class="section-action">View all</a>
- </div>
- <div class="stream-grid home-clips-grid" id="home-clips-grid"></div>
- <div id="home-clips-pagination" class="pastes-pagination" style="display:none"></div>
-
- <!-- Recent Pastes -->
- <div class="section-header" style="--sc:#2dd4bf;display:none" id="home-pastes-header">
- <h2><i class="fa-solid fa-paste"></i> Recent Pastes<small class="section-kicker">shots & snippets</small></h2>
- <a href="/content?type=pastes" onclick="return handleLinkClick(event, '/content?type=pastes')" class="section-action">View all</a>
- </div>
- <div class="home-pastes-list" id="home-pastes-list"></div>
- <div id="home-pastes-pagination" class="pastes-pagination" style="display:none"></div>
-
<!-- Scraplandia Leaderboards -->
<!-- Scraplandia Leaderboards -->
<div class="section-header" style="--sc:#fbbf24;display:none" id="home-quest-header">
<div class="section-header" style="--sc:#fbbf24;display:none" id="home-quest-header">
<h2><i class="fa-solid fa-trophy"></i> Scraplandia Leaderboards<small class="section-kicker">the ladder</small></h2>
<h2><i class="fa-solid fa-trophy"></i> Scraplandia Leaderboards<small class="section-kicker">the ladder</small></h2>
new file mode 100644
new file mode 100644
@@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
+/**
+ * The home page leads with live content and creators (roadmap 32.7, critique 1): Live Now first,
+ * then, above the introduction to the site (the restream tour and the collapsed About banner), what
+ * people made (Recently Online, Recent VODs, Recent Clips, Recent Pastes), then what the AI made
+ * (AI Moments; 33.6: made, then derived). Nothing else on the page was removed.
+ *
+ * node test/home-order.test.js
+ */
+'use strict';
+const assert = require('assert');
+
+const assets = require('../server/web/assets');
+try { assets.setSharedDir(require('openvibe-shared/files').dir); } catch { /* */ }
+const html = assets.renderRoute(assets.document('index.html').html, '/');
+const home = html.slice(html.indexOf('<section id="page-home"'), html.indexOf('</section>', html.indexOf('<section id="page-home"')));
+const at = (needle) => {
+ const i = home.indexOf(needle);
+ assert.ok(i >= 0, `${needle} is on the home page`);
+ return i;
+};
+
+let failures = 0;
+function check(name, fn) {
+ try { fn(); console.log(' ✓', name); }
+ catch (e) { failures++; console.log(' ✗', name, '\n ', e.message); }
+}
+
+console.log('Home order');
+
+check('Live Now is the first section after the hero', () => {
+ const live = at('id="stream-grid-live"');
+ for (const id of ['stream-grid-recent', 'home-recent-vods-grid', 'home-clips-grid', 'home-pastes-list', 'home-moments-section', 'home-tour-mount', 'home-cta-banner', 'home-digest', 'home-star-section']) {
+ assert.ok(live < at(`id="${id}"`), `Live Now before ${id}`);
+ }
+});
+
+check('the creator rows sit above the introduction (tour and About banner)', () => {
+ const intro = Math.min(at('id="home-tour-mount"'), at('id="home-cta-banner"'));
+ for (const id of ['stream-grid-recent', 'home-recent-vods-grid', 'home-clips-grid', 'home-pastes-list']) {
+ assert.ok(at(`id="${id}"`) < intro, `${id} above the introduction`);
+ }
+});
+
+check("people's work comes before the AI's", () => {
+ const ai = at('id="home-moments-section"');
+ for (const id of ['stream-grid-recent', 'home-recent-vods-grid', 'home-clips-grid', 'home-pastes-list']) {
+ assert.ok(at(`id="${id}"`) < ai, `${id} before AI Moments`);
+ }
+});
+
+check('each rail keeps its header right before its grid (the density control reads it)', () => {
+ const recent = at('id="stream-grid-recent"');
+ const header = home.lastIndexOf('<div class="section-header"', recent);
+ assert.ok(home.slice(header, recent).includes('Recently Online'));
+});
+
+check('nothing was removed', () => {
+ for (const id of ['home-featured', 'stream-grid-live', 'home-digest', 'home-star-section', 'hero-egg', 'home-pulse-section',
+ 'stream-grid-recent', 'stream-grid-recent-pagination', 'home-recent-vods-header', 'home-recent-vods-grid', 'home-clips-header',
+ 'home-clips-grid', 'home-pastes-header', 'home-pastes-list', 'home-moments-section', 'home-tour-mount', 'home-cta-banner',
+ 'home-about-body', 'home-quest-header', 'home-leaderboards', 'home-canvas-header', 'home-canvas-preview']) {
+ at(`id="${id}"`);
+ }
+ assert.ok(home.includes('class="network-hub"'));
+});
+
+console.log(failures ? `\n${failures} check(s) failed` : '\nhome order: all checks passed');
+process.exit(failures ? 1 : 0);