openvibers/openvibe.news Commits

News home: with no editor's story, the AI briefs are the latest stories (no "no stories have been published yet") (#70)

OP OpenVibers committed 28 days ago · 438323ffc5 · 4 files, +16 −11

Changes

ddiff --git a/server/render/pages.js b/server/render/pages.js
iindex 3edf504..9dbf1b8 100644
---- a/server/render/pages.js
++++ b/server/render/pages.js
@@@ -45,18 +45,21 @@ ${raw(feedLinksHtml(feeds))}
<p class="lede">Source-backed stories. Every paragraph cites the reports it rests on; corrections and retractions stay on the record.</p>
${raw(feedLinksHtml(feeds))}
</header>`}
--<section id="stories" aria-label="Stories">${storyList(items, wire || briefs.length ? `No stories have been published yet: editors write them from the sources, and every paragraph cites them. Until then, ${briefs.length ? 'the AI briefs and the wire below show' : 'the wire below shows'} what the sources report.` : 'No stories have been published yet. OpenVibe.News publishes only what an editor has written from its sources.')}</section>
--${raw(ssr.paginationHtml(pager))}
--${raw(briefsSection(briefs))}
++${items.length || !showcase ? h`<section id="stories" aria-label="Stories">${storyList(items, 'No stories on this page.')}</section>
++${raw(ssr.paginationHtml(pager))}` : ''}
++${raw(briefsSection(briefs, { lead: showcase && !items.length }))}
++${showcase && !items.length && !briefs.length && !wire ? h`<p class="empty">The first reports are on their way: the AI briefs and the wire fill in as the sources report.</p>` : ''}
${raw(wire)}
${topics.length ? h`<section class="side" aria-label="Topics"><h2>Topics</h2><ul class="topic-list">${topics.map((t) => h`<li><a href="/topics/${t.slug}">${t.name}</a></li>`)}</ul></section>` : ''}`);
}
/** The front page's latest AI briefs (server/domain/briefs.js), labelled as AI, each opening on its first paragraph. */
--function briefsSection(briefs) {
++// With no editor's story yet (`lead`), the briefs are the front page's latest stories, under its "Latest stories"
++// heading: still labelled AI, and an editor's story takes the top when one is published.
++function briefsSection(briefs, { lead = false } = {}) {
if (!briefs.length) return '';
-- return String(h`<section class="home-briefs" aria-labelledby="briefs-h"><h2 id="briefs-h">AI briefs</h2>
--<p class="meta">What the reports on a subject say, summarized by OpenVibe.AI with every paragraph linked to its reports. Written by AI, not by an editor.</p>
++ return String(h`<section class="home-briefs" aria-labelledby="briefs-h">${lead ? '' : h`<h2 id="briefs-h">AI briefs</h2>`}
++<p class="meta"${lead ? raw(' id="briefs-h"') : ''}>What the reports on each subject say, summarized by OpenVibe.AI with every paragraph linked to its reports. Written by AI, not by an editor${lead ? '; stories by editors appear here first when they are published' : ''}.</p>
<ol class="story-list">${briefs.map((b) => h`<li class="story-item"><h3 class="story-item-title"><a href="/briefs/${b.cluster_id}">${b.headline || b.label}</a> <span class="badge">AI</span></h3>
<p class="meta">${time(b.window_end)} · from ${b.item_count} reports</p>${b.paragraphs[0] ? h`<p class="summary">${b.paragraphs[0].text.length > 240 ? `${b.paragraphs[0].text.slice(0, 237)}…` : b.paragraphs[0].text}</p>` : ''}</li>`)}</ol>
<p><a href="/briefs">All AI briefs</a></p></section>`);
ddiff --git a/test/briefs.test.js b/test/briefs.test.js
iindex df7f0a6..ce7ba29 100644
---- a/test/briefs.test.js
++++ b/test/briefs.test.js
@@@ -46,8 +46,10 @@ const SAME = { 'sec-fetch-site': 'same-origin' };
const list = await t.get('/briefs');
assert.ok(list.text.includes(`/briefs/${clusterId}`));
const home = await t.get('/');
-- assert.ok(home.text.includes('<h2 id="briefs-h">AI briefs</h2>') && home.text.includes(`href="/briefs/${clusterId}"`), 'the front page shows the latest briefs');
-- assert.ok(home.text.includes('Written by AI, not by an editor.') && home.text.includes('the AI briefs and the wire below show'));
++ // With no editor's story, the briefs are the front page's latest stories: under "Latest stories", labelled AI.
++ assert.ok(home.text.includes('<h2>Latest stories</h2>') && home.text.includes(`href="/briefs/${clusterId}"`), 'the front page leads with the latest briefs');
++ assert.ok(home.text.includes('Written by AI, not by an editor; stories by editors appear here first') && home.text.includes('<span class="badge">AI</span>'));
++ assert.ok(!home.text.includes('No stories have been published yet'));
});
await check('a reader asks for another tone with a POST from this site; a GET never runs AI', async () => {
ddiff --git a/test/ingest.test.js b/test/ingest.test.js
iindex 0275ede..6db4c88 100644
---- a/test/ingest.test.js
++++ b/test/ingest.test.js
@@@ -16,7 +16,7 @@ const { boot, check, done, launchReports } = require('./helpers/boot');
assert.ok(await count('news_topics') >= 10);
for (const table of ['news_stories', 'news_source_items', 'news_story_clusters', 'news_story_revisions', 'news_editorial_flags']) assert.strictEqual(await count(table), 0, table);
const home = await t.get('/');
-- assert.match(home.text, /No stories have been published yet/);
++ assert.match(home.text, /The first reports are on their way/, 'an empty front page says what comes, not that nothing was published');
});
let reports;
ddiff --git a/test/wire.test.js b/test/wire.test.js
iindex b063ac7..174b785 100644
---- a/test/wire.test.js
++++ b/test/wire.test.js
@@@ -29,9 +29,9 @@ const { boot, check, done, launchReports } = require('./helpers/boot');
assert.match(r.headers.get('cache-control') || '', /public/);
});
-- await check('the front page keeps "no stories yet", and shows the latest clusters from the wire', async () => {
++ await check('the front page shows the latest clusters from the wire, and no "no stories yet" apology', async () => {
const r = await t.get('/');
-- assert.ok(r.text.includes('No stories have been published yet'));
++ assert.ok(!r.text.includes('No stories have been published yet'));
assert.ok(r.text.includes('From the wire') && r.text.includes('href="/wire"'));
assert.ok(r.text.includes('Europa Clipper'));
assert.ok(!/noindex/.test(r.headers.get('x-robots-tag') || ''), 'with the wire, the front page is not empty: it is indexed');