openvibers/openvibe.today Commits

Today's home leads with what is real; one 'be the first' row instead of an empty box (#32)

OP OpenVibers committed 13 days ago · 08417b3779 · 3 files, +31 −3

Changes

ddiff --git a/public/css/today.css b/public/css/today.css
iindex 0b31d73..561770d 100644
---- a/public/css/today.css
++++ b/public/css/today.css
@@@ -179,3 +179,9 @@ html[data-ov-motion=reduced] .td-demo-toast, html[data-ov-motion=reduced] .td-ri
a.td-more { position: relative; }
a.td-more::after { content: ''; position: absolute; left: 0; right: 0; top: -14px; bottom: -14px; }
}
++
++/* Be the first (10-31): an empty calendar is one short row after the scenes, never an empty box up top. */
++.td-first-list { list-style: none; margin: 10px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: 10px; }
++.td-first-list li { display: grid; gap: 4px; padding: 14px 16px; border-radius: 16px; border: 1px dashed color-mix(in srgb, var(--room-accent) 45%, var(--border, #2c3d5c)); }
++.td-first-list span { color: var(--text-secondary, #a8b3c4); font-size: 14px; line-height: 1.45; }
++.td-first-list a { justify-self: start; margin-top: 4px; font-weight: 700; color: var(--room-strong, var(--room-accent)); }
ddiff --git a/server/views/index.js b/server/views/index.js
iindex f6195d3..8f1458d 100644
---- a/server/views/index.js
++++ b/server/views/index.js
@@@ -133,8 +133,12 @@ function home({ upcoming = [], now = Date.now() } = {}) {
{ value: channels.size, label: 'channels' },
].filter((p) => p.value),
});
-- const coming = `<section class="td-coming" id="td-upcoming" aria-labelledby="td-coming-h"><div class="td-head-row"><h2 id="td-coming-h">Coming up</h2><a class="td-more" href="/developers#feeds">Subscribe${kit.icon('chevron')}</a></div>
--${days(upcoming, { now, empty: 'Nothing is scheduled yet. Schedule a stream and it shows here, on your channel and in your followers’ calendars.' })}</section>`;
++ // Real first (the owner, 10-31: empty sections made the rooms look unfinished): Coming up shows only with something in
++ // it; an empty calendar is one short "be the first" row after the scenes.
++ const coming = upcoming.length ? `<section class="td-coming" id="td-upcoming" aria-labelledby="td-coming-h"><div class="td-head-row"><h2 id="td-coming-h">Coming up</h2><a class="td-more" href="/developers#feeds">Subscribe${kit.icon('chevron')}</a></div>
++${days(upcoming, { now })}</section>` : '';
++ const beFirst = upcoming.length ? '' : `<section class="td-coming td-first" aria-labelledby="td-first-h"><h2 id="td-first-h">Be the first</h2>
++<ul class="td-first-list"><li><b>Schedule the first stream</b><span>It shows here, on your channel and in your followers’ calendars, and anyone can set a reminder for it.</span><a href="/schedule">Schedule a stream</a></li></ul></section>`;
const scenesHTML = `<section class="sc-room-scenes" aria-label="What you can do">${scenes.map((x, i) => `<article class="sc-scene${i % 2 ? ' is-flip' : ''}" data-ov-reveal">
<div class="sc-scene-text"><h2>${esc(x.title)}</h2>${x.text ? `<p>${esc(x.text)}</p>` : ''}${x.action ? `<a class="sc-scene-go" href="${esc(x.action.href)}">${esc(x.action.label)}${kit.icon('chevron')}</a>` : ''}</div>
<div class="sc-scene-stage">${x.html}</div></article>`).join('')}</section>`;
@@@ -148,7 +152,7 @@ ${days(upcoming, { now, empty: 'Nothing is scheduled yet. Schedule a stream and
['Can I see this in my own calendar app?', 'Yes. Every channel has a public calendar feed, and your agenda has a private one. Subscribe in any app that reads iCalendar (.ics); updates and cancellations follow.'],
['Who sees what I schedule?', 'A public stream is on your channel, here and in feeds. A followers-only one is seen only by the people who follow you. Followers hear about at most three new schedules from you a day.'],
] });
-- const body = hero.replace(/<\/div>\s*$/, `${coming}${scenesHTML}${explore}${faq}</div>`);
++ const body = hero.replace(/<\/div>\s*$/, `${coming}${scenesHTML}${beFirst}${explore}${faq}</div>`);
return `<div class="td-wrap" id="td-home">${body}</div>`;
}
ddiff --git a/test/home-real-first.test.js b/test/home-real-first.test.js
nnew file mode 100644
iindex 0000000..d00fac4
---- /dev/null
++++ b/test/home-real-first.test.js
@@@ -0,0 +1,18 @@
++'use strict';
++// Today's home leads with what is real (the owner, 10-31: empty sections made the rooms look unfinished). With nothing
++// coming up there is no empty "Coming up" box under the hero: one short "be the first" row follows the scenes.
++const assert = require('assert');
++const fs = require('fs');
++const path = require('path');
++
++const src = fs.readFileSync(path.join(__dirname, '..', 'server/views/index.js'), 'utf8');
++assert.match(src, /const coming = upcoming\.length \? `<section class="td-coming" id="td-upcoming"/, 'Coming up only with something in it');
++assert.match(src, /\$\{coming\}\$\{scenesHTML\}\$\{beFirst\}\$\{explore\}\$\{faq\}/, 'the missing comes after the scenes');
++assert.ok(!src.includes('Nothing is scheduled yet'), 'no empty box under the hero');
++
++const views = require('../server/views');
++const page = views.home({ upcoming: [], live: [], now: Date.parse('2026-10-31T12:00:00Z') });
++assert.ok(!page.includes('id="td-upcoming"'), 'no empty Coming up');
++assert.ok(page.indexOf('Be the first') > page.indexOf('class="sc-room-scenes"'), 'the row follows the scenes');
++assert.ok(page.includes('href="/schedule">Schedule a stream</a>'), 'it says how the first one starts');
++console.log('today home: real first, one "be the first" row while nothing is coming up');