openvibers/openvibe.tips Commits
Creator cards name the creator by its @handle (#250)
Changes
@@@ -107,8 +107,8 @@ function tipScene() {function home({ creators, live = [] }) {const m = NEW_PAGE_MINIMUMS;-- const liveCards = live.length ? `<ul class="tp-cards">${live.map((c) => `<li class="tp-card"><p class="tp-card-top"><span class="tp-live">Live</span> <a href="${esc(c.url)}"><strong>${esc(c.name)}</strong></a></p>${c.title ? `<p>${esc(c.title)}</p>` : ''}<p class="meta">${[c.category, watching(c.viewers)].filter(Boolean).map(esc).join(' · ')}</p></li>`).join('')}</ul>` : '';-- const creatorCards = creators.length ? `<ul class="tp-cards">${creators.map((c) => `<li class="tp-card"><p class="tp-card-top">${c.avatar_url ? `<img src="${esc(mediaSrc(c.avatar_url, 96))}" alt="" width="40" height="40" loading="lazy">` : ''}<a href="/@${esc(c.handle)}"><strong>${esc(c.display_name)}</strong></a></p>${c.headline ? `<p>${esc(c.headline)}</p>` : ''}${c.goal ? `<p class="meta">Goal: ${esc(c.goal.title)}</p><div class="bar" role="progressbar" aria-label="${esc(c.goal.title)}" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${c.goal.percent}"><span style="width:${c.goal.percent}%"></span></div>` : ''}</li>`).join('')}</ul>` : '';++ const liveCards = live.length ? `<ul class="tp-cards">${live.map((c) => `<li class="tp-card"><p class="tp-card-top"><span class="tp-live">Live</span> <a href="${esc(c.url)}"><strong>${esc(c.username ? '@' + c.username : c.name)}</strong></a></p>${c.title ? `<p>${esc(c.title)}</p>` : ''}<p class="meta">${[c.category, watching(c.viewers)].filter(Boolean).map(esc).join(' · ')}</p></li>`).join('')}</ul>` : '';++ const creatorCards = creators.length ? `<ul class="tp-cards">${creators.map((c) => `<li class="tp-card"><p class="tp-card-top">${c.avatar_url ? `<img src="${esc(mediaSrc(c.avatar_url, 96))}" alt="" width="40" height="40" loading="lazy">` : ''}<a href="/@${esc(c.handle)}"><strong>${esc(c.display_name)}</strong> <span class="muted">@${esc(c.handle)}</span></a></p>${c.headline ? `<p>${esc(c.headline)}</p>` : ''}${c.goal ? `<p class="meta">Goal: ${esc(c.goal.title)}</p><div class="bar" role="progressbar" aria-label="${esc(c.goal.title)}" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${c.goal.percent}"><span style="width:${c.goal.percent}%"></span></div>` : ''}</li>`).join('')}</ul>` : '';return showcase.hero({eyebrow: 'OpenVibe.Tips',title: 'Support the creators', accent: 'you watch',@@@ -45,7 +45,7 @@ const { createLiveNow } = require('../server/clients/live-now');const body = text.slice(text.indexOf('<main'));assert.strictEqual(r.status, 200);assert.strictEqual((text.match(/<h1[\s>]/g) || []).length, 1, 'one h1');-- assert.ok(body.includes('id="live"') && body.includes('<a href="https://openvibe.live/@busy_1"><strong>Busy</strong></a>') && body.includes('gaming · 40 watching'));++ assert.ok(body.includes('id="live"') && body.includes('<a href="https://openvibe.live/@busy_1"><strong>@busy_1</strong></a>') && body.includes('gaming · 40 watching'));assert.ok(body.includes('For creators') && body.includes('Overlays for any stream'));assert.ok(body.includes('<li>Ko-fi</li>') && body.includes('<li>StreamElements</li>'), 'the services a creator can link');const ld = [...text.matchAll(/<script type="application\/ld\+json">([\s\S]*?)<\/script>/g)].map((m) => JSON.parse(m[1]));@@@ -31,6 +31,7 @@ const { boot, check, done } = require('./helpers/app');assert.match(r.text, /id="ov-footer"|class="ovf/);assert.match(r.text, /<script type="application\/ld\+json">[^<]*"@type":"WebSite"[^<]*"name":"OpenVibe.Tips"/, 'the home says what the site is (JSON-LD)');assert.match(r.text, /href="\/@alex"/);++ assert.ok(r.text.includes('class="muted">@alex</span>'), 'the creator card names the handle by its @address');assert.ok(!r.text.includes('href="/@bob"'), 'switched-off pages are not listed');// The home opens with the showcase kit (openvibe-shared/showcase): one h1 (the hero), the kit's sheet, the// pricing from the real defaults, and the creators list still below it.
@@ -107,8 +107,8 @@ function tipScene() {
@@ -107,8 +107,8 @@ function tipScene() {
function home({ creators, live = [] }) {
function home({ creators, live = [] }) {
const m = NEW_PAGE_MINIMUMS;
const m = NEW_PAGE_MINIMUMS;
- const liveCards = live.length ? `<ul class="tp-cards">${live.map((c) => `<li class="tp-card"><p class="tp-card-top"><span class="tp-live">Live</span> <a href="${esc(c.url)}"><strong>${esc(c.name)}</strong></a></p>${c.title ? `<p>${esc(c.title)}</p>` : ''}<p class="meta">${[c.category, watching(c.viewers)].filter(Boolean).map(esc).join(' · ')}</p></li>`).join('')}</ul>` : '';
- const creatorCards = creators.length ? `<ul class="tp-cards">${creators.map((c) => `<li class="tp-card"><p class="tp-card-top">${c.avatar_url ? `<img src="${esc(mediaSrc(c.avatar_url, 96))}" alt="" width="40" height="40" loading="lazy">` : ''}<a href="/@${esc(c.handle)}"><strong>${esc(c.display_name)}</strong></a></p>${c.headline ? `<p>${esc(c.headline)}</p>` : ''}${c.goal ? `<p class="meta">Goal: ${esc(c.goal.title)}</p><div class="bar" role="progressbar" aria-label="${esc(c.goal.title)}" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${c.goal.percent}"><span style="width:${c.goal.percent}%"></span></div>` : ''}</li>`).join('')}</ul>` : '';
+ const liveCards = live.length ? `<ul class="tp-cards">${live.map((c) => `<li class="tp-card"><p class="tp-card-top"><span class="tp-live">Live</span> <a href="${esc(c.url)}"><strong>${esc(c.username ? '@' + c.username : c.name)}</strong></a></p>${c.title ? `<p>${esc(c.title)}</p>` : ''}<p class="meta">${[c.category, watching(c.viewers)].filter(Boolean).map(esc).join(' · ')}</p></li>`).join('')}</ul>` : '';
+ const creatorCards = creators.length ? `<ul class="tp-cards">${creators.map((c) => `<li class="tp-card"><p class="tp-card-top">${c.avatar_url ? `<img src="${esc(mediaSrc(c.avatar_url, 96))}" alt="" width="40" height="40" loading="lazy">` : ''}<a href="/@${esc(c.handle)}"><strong>${esc(c.display_name)}</strong> <span class="muted">@${esc(c.handle)}</span></a></p>${c.headline ? `<p>${esc(c.headline)}</p>` : ''}${c.goal ? `<p class="meta">Goal: ${esc(c.goal.title)}</p><div class="bar" role="progressbar" aria-label="${esc(c.goal.title)}" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${c.goal.percent}"><span style="width:${c.goal.percent}%"></span></div>` : ''}</li>`).join('')}</ul>` : '';
return showcase.hero({
return showcase.hero({
eyebrow: 'OpenVibe.Tips',
eyebrow: 'OpenVibe.Tips',
title: 'Support the creators', accent: 'you watch',
title: 'Support the creators', accent: 'you watch',
@@ -45,7 +45,7 @@ const { createLiveNow } = require('../server/clients/live-now');
@@ -45,7 +45,7 @@ const { createLiveNow } = require('../server/clients/live-now');
const body = text.slice(text.indexOf('<main'));
const body = text.slice(text.indexOf('<main'));
assert.strictEqual(r.status, 200);
assert.strictEqual(r.status, 200);
assert.strictEqual((text.match(/<h1[\s>]/g) || []).length, 1, 'one h1');
assert.strictEqual((text.match(/<h1[\s>]/g) || []).length, 1, 'one h1');
- assert.ok(body.includes('id="live"') && body.includes('<a href="https://openvibe.live/@busy_1"><strong>Busy</strong></a>') && body.includes('gaming · 40 watching'));
+ assert.ok(body.includes('id="live"') && body.includes('<a href="https://openvibe.live/@busy_1"><strong>@busy_1</strong></a>') && body.includes('gaming · 40 watching'));
assert.ok(body.includes('For creators') && body.includes('Overlays for any stream'));
assert.ok(body.includes('For creators') && body.includes('Overlays for any stream'));
assert.ok(body.includes('<li>Ko-fi</li>') && body.includes('<li>StreamElements</li>'), 'the services a creator can link');
assert.ok(body.includes('<li>Ko-fi</li>') && body.includes('<li>StreamElements</li>'), 'the services a creator can link');
const ld = [...text.matchAll(/<script type="application\/ld\+json">([\s\S]*?)<\/script>/g)].map((m) => JSON.parse(m[1]));
const ld = [...text.matchAll(/<script type="application\/ld\+json">([\s\S]*?)<\/script>/g)].map((m) => JSON.parse(m[1]));
@@ -31,6 +31,7 @@ const { boot, check, done } = require('./helpers/app');
@@ -31,6 +31,7 @@ const { boot, check, done } = require('./helpers/app');
assert.match(r.text, /id="ov-footer"|class="ovf/);
assert.match(r.text, /id="ov-footer"|class="ovf/);
assert.match(r.text, /<script type="application\/ld\+json">[^<]*"@type":"WebSite"[^<]*"name":"OpenVibe.Tips"/, 'the home says what the site is (JSON-LD)');
assert.match(r.text, /<script type="application\/ld\+json">[^<]*"@type":"WebSite"[^<]*"name":"OpenVibe.Tips"/, 'the home says what the site is (JSON-LD)');
assert.match(r.text, /href="\/@alex"/);
assert.match(r.text, /href="\/@alex"/);
+ assert.ok(r.text.includes('class="muted">@alex</span>'), 'the creator card names the handle by its @address');
assert.ok(!r.text.includes('href="/@bob"'), 'switched-off pages are not listed');
assert.ok(!r.text.includes('href="/@bob"'), 'switched-off pages are not listed');
// The home opens with the showcase kit (openvibe-shared/showcase): one h1 (the hero), the kit's sheet, the
// The home opens with the showcase kit (openvibe-shared/showcase): one h1 (the hero), the kit's sheet, the
// pricing from the real defaults, and the creators list still below it.
// pricing from the real defaults, and the creators list still below it.