openvibers/openvibe.food Commits

Share: one Share sheet on every recipe (#218)

OP OpenVibers committed 7 days ago · bc163f41ed · 2 files, +52 −2

* Share: the one Share sheet on every recipe

Put the network's Share button (data-ov-share-sheet) in each recipe's
head with its canonical address, title and line. Recipes have no picture
of their own, so no data-image is set.

* Share: the shared kit button, one look everywhere

Render the one Share button with openvibe-shared 4.114.0's kit.share
(or its exact markup where the page is built in the browser), so every
site shows the same quiet button with the share icon. Remove the
site-specific Share styles.

Changes

ddiff --git a/server/http/library-routes.js b/server/http/library-routes.js
iindex 3e5d978..65f81ef 100644
---- a/server/http/library-routes.js
++++ b/server/http/library-routes.js
@@@ -12,7 +12,8 @@
* Every page says the recipe was written by OpenVibe.AI; an unreviewed one is noindex.
*/
const showcase = require('openvibe-shared/showcase');
--const { html, notice, time } = require('../render/html');
++const kit = require('openvibe-shared/kit');
++const { html, raw, notice, time } = require('../render/html');
const { sameOrigin } = require('./principal');
const { COST_NOTE } = require('../food/recipes');
@@@ -79,11 +80,12 @@ ${pages > 1 ? html`<nav class="pager" aria-label="Pages">${pageNo > 1 ? html`<a
author: { '@type': 'Organization', name: 'OpenVibe.Food' }, datePublished: x.created_at,
}] : [];
page(req, res, {
-- title: x.title, index: Boolean(x.reviewed && x.status === 'published'), localStyles: ['css/recipes.css'], jsonLd,
++ title: x.title, index: Boolean(x.reviewed && x.status === 'published'), localStyles: ['css/recipes.css'], styles: [showcase.STYLESHEET, 'kit.css'], jsonLd,
description: `${x.title}: ${meta(x)}. A budget recipe from OpenVibe.Food's food list, written by AI.`,
crumbs: [{ label: 'Recipe library', href: '/recipes/library' }, { label: x.title }],
body: html`<article class="recipe lib-recipe">
<header class="recipe-head"><h1>${x.title}</h1><p class="recipe-meta">${meta(x)}</p></header>
++<p>${raw(kit.share({ title: x.title, url, text: `${x.title}: ${meta(x)}. A budget recipe from OpenVibe.Food's food list, written by AI.` }))}</p>
<p class="notice">${AI_LINE}${x.reviewed ? ' A person at OpenVibe has checked this one.' : ''}</p>
<div class="recipe-body">
<section class="recipe-ingredients" aria-label="Ingredients"><h2 class="h4">Ingredients</h2>
ddiff --git a/test/share-sheet.test.js b/test/share-sheet.test.js
nnew file mode 100644
iindex 0000000..9cd9332
---- /dev/null
++++ b/test/share-sheet.test.js
@@@ -0,0 +1,48 @@
++'use strict';
++/**
++ * Every recipe in the library carries the network's one Share button (openvibe-shared 4.114.0): one
++ * [data-ov-share-sheet] in its head, with the recipe's canonical address, title and line. A recipe has no picture of
++ * its own, so there is no data-image. The navbar loads the sheet on the first press.
++ */
++const assert = require('assert');
++const { boot } = require('./helpers/boot');
++const { buildSources } = require('../server/food/recipes');
++
++const src = buildSources();
++const at = (slug) => src.findIndex((x) => x.source_id === slug);
++const ai = {
++ async run() {
++ return {
++ runId: 'run_share_1',
++ output: {
++ recipes: [{
++ title: 'Beans and Rice', serves: 4, minutes: 25,
++ ingredients: [
++ { name: 'Rice', amount: '2 cups', from_pantry: false, citations: [at('white-rice')] },
++ { name: 'Beans', amount: '1 can', from_pantry: false, citations: [at('canned-beans')] },
++ ],
++ steps: ['Cook the rice.', 'Warm the beans.', 'Serve together.'], notes: 'Add hot sauce.',
++ }],
++ citations: [], gaps: [],
++ },
++ };
++ },
++};
++
++(async () => {
++ const t = await boot({ env: { OV_AI_INTERNAL_URL: 'http://ai.test' }, ai });
++ try {
++ const [recipe] = await t.ctx.library.tick({ force: true });
++ const r = await t.get(`/recipes/library/${recipe.slug}`);
++ assert.strictEqual(r.status, 200, r.text.slice(0, 200));
++ assert.strictEqual((r.text.match(/data-ov-share-sheet/g) || []).length, 1, 'one Share button');
++ assert.ok(r.text.includes(`data-url="https://openvibe.food/recipes/library/${recipe.slug}"`), 'the recipe address');
++ assert.ok(r.text.includes('data-title="Beans and Rice"'), 'its title');
++ assert.ok(r.text.includes('data-text="Beans and Rice: Serves 4 · About 25 min'), 'its line');
++ assert.ok(r.text.includes('class="ovk-btn ovk-btn--quiet"') && r.text.includes('<span>Share</span>'), 'the shared kit button');
++ assert.ok(!r.text.includes('data-image='), 'no picture: no data-image');
++ console.log('food share sheet ok');
++ } finally {
++ await t.close();
++ }
++})().catch((e) => { console.error(e); process.exit(1); });