openvibers/openvibe.community Commits
The bar: main places with icons and the phone app bar, the rest under More (Search is the magnifier) (#162)
Changes
@@@ -60,12 +60,15 @@ function navbarInit(opts) {service: 'community',apiBase: NETWORK_URL,links: [-- { label: 'Pastes', href: '/pastes', active: opts.active === 'pastes' },-- { label: 'Forum', href: '/s', active: opts.active === 'spaces' },-- { label: 'Pulse', href: '/pulse', active: opts.active === 'pulse' },-- { label: 'Search', href: '/search', icon: 'fa-magnifying-glass', active: opts.active === 'search' },++ // The product's own places: the main ones carry an icon (phones get them as the bottom tab bar), the rest fold++ // into the navbar's More (Shared 4.22). Search is the navbar's magnifier; What shipped is the footer's.++ { label: 'Forum', href: '/s', icon: 'fa-comments', active: opts.active === 'spaces' },++ { label: 'Pastes', href: '/pastes', icon: 'fa-paste', active: opts.active === 'pastes' },++ { label: 'Pulse', href: '/pulse', icon: 'fa-bolt', active: opts.active === 'pulse' },{ label: 'New paste', href: '/new', icon: 'fa-plus', active: opts.active === 'new' },],++ appBar: true, // phones: the four places as the bottom tab bar (Shared 4.20)++ search: { page: '/search', label: 'OpenVibe.Community' }, // the magnifier offers this site's own search firstmenu: { after: [{ label: 'My pastes', href: '/my', icon: 'fa-paste' }] },history: { type: opts.historyType || 'page', title: opts.historyTitle || opts.title },silentLogin: `${config.baseUrl}/auth/login?silent=1&next={url}`,@@@ -41,12 +41,12 @@ const { createSearchQuery, SearchUnavailable } = require('../server/search/queryassert.ok(r.text.includes('noindex,follow'));});-- await check('no query asks Search nothing; the navbar links to /search', async () => {++ await check('no query asks Search nothing; the navbar magnifier offers /search', async () => {const n = asked.length;const r = await t.get('/search');assert.strictEqual(r.status, 200);assert.strictEqual(asked.length, n);-- assert.ok(r.text.includes('"href":"/search"'));++ assert.ok(r.text.includes('"search":{"page":"/search"'), 'the navbar\'s magnifier offers this search page first');});await check('Search not answering: 503, said plainly, with the paste filter', async () => {@@@ -46,7 +46,10 @@ const { boot, check, done } = require('./helpers/app');// Navbar/footer init payload matches the shared-chrome contract.const cfg = JSON.parse(r.text.match(/window\.__OV_PAGE = (.*);\n/)[1]);assert.strictEqual(cfg.navbar.service, 'community');-- assert.deepStrictEqual(cfg.navbar.links.map((l) => l.href), ['/pastes', '/s', '/pulse', '/search', '/new']);++ // The bar (2026-10-28): the forum first, every place with an icon (the phone app bar); search is the magnifier,++ // which offers this site's own search page first.++ assert.deepStrictEqual(cfg.navbar.links.map((l) => l.href), ['/s', '/pastes', '/pulse', '/new']);++ assert.ok(cfg.navbar.links.every((l) => l.icon) && cfg.navbar.appBar === true && cfg.navbar.search && cfg.navbar.search.page === '/search');assert.strictEqual(cfg.navbar.menu.after[0].href, '/my');assert.strictEqual(cfg.navbar.history.type, 'page');assert.strictEqual(cfg.navbar.silentLogin, 'https://openvibe.community/auth/login?silent=1&next={url}');
@@ -60,12 +60,15 @@ function navbarInit(opts) {
@@ -60,12 +60,15 @@ function navbarInit(opts) {
service: 'community',
service: 'community',
apiBase: NETWORK_URL,
apiBase: NETWORK_URL,
links: [
links: [
- { label: 'Pastes', href: '/pastes', active: opts.active === 'pastes' },
- { label: 'Forum', href: '/s', active: opts.active === 'spaces' },
- { label: 'Pulse', href: '/pulse', active: opts.active === 'pulse' },
- { label: 'Search', href: '/search', icon: 'fa-magnifying-glass', active: opts.active === 'search' },
+ // The product's own places: the main ones carry an icon (phones get them as the bottom tab bar), the rest fold
+ // into the navbar's More (Shared 4.22). Search is the navbar's magnifier; What shipped is the footer's.
+ { label: 'Forum', href: '/s', icon: 'fa-comments', active: opts.active === 'spaces' },
+ { label: 'Pastes', href: '/pastes', icon: 'fa-paste', active: opts.active === 'pastes' },
+ { label: 'Pulse', href: '/pulse', icon: 'fa-bolt', active: opts.active === 'pulse' },
{ label: 'New paste', href: '/new', icon: 'fa-plus', active: opts.active === 'new' },
{ label: 'New paste', href: '/new', icon: 'fa-plus', active: opts.active === 'new' },
],
],
+ appBar: true, // phones: the four places as the bottom tab bar (Shared 4.20)
+ search: { page: '/search', label: 'OpenVibe.Community' }, // the magnifier offers this site's own search first
menu: { after: [{ label: 'My pastes', href: '/my', icon: 'fa-paste' }] },
menu: { after: [{ label: 'My pastes', href: '/my', icon: 'fa-paste' }] },
history: { type: opts.historyType || 'page', title: opts.historyTitle || opts.title },
history: { type: opts.historyType || 'page', title: opts.historyTitle || opts.title },
silentLogin: `${config.baseUrl}/auth/login?silent=1&next={url}`,
silentLogin: `${config.baseUrl}/auth/login?silent=1&next={url}`,
@@ -41,12 +41,12 @@ const { createSearchQuery, SearchUnavailable } = require('../server/search/query
@@ -41,12 +41,12 @@ const { createSearchQuery, SearchUnavailable } = require('../server/search/query
assert.ok(r.text.includes('noindex,follow'));
assert.ok(r.text.includes('noindex,follow'));
});
});
- await check('no query asks Search nothing; the navbar links to /search', async () => {
+ await check('no query asks Search nothing; the navbar magnifier offers /search', async () => {
const n = asked.length;
const n = asked.length;
const r = await t.get('/search');
const r = await t.get('/search');
assert.strictEqual(r.status, 200);
assert.strictEqual(r.status, 200);
assert.strictEqual(asked.length, n);
assert.strictEqual(asked.length, n);
- assert.ok(r.text.includes('"href":"/search"'));
+ assert.ok(r.text.includes('"search":{"page":"/search"'), 'the navbar\'s magnifier offers this search page first');
});
});
await check('Search not answering: 503, said plainly, with the paste filter', async () => {
await check('Search not answering: 503, said plainly, with the paste filter', async () => {
@@ -46,7 +46,10 @@ const { boot, check, done } = require('./helpers/app');
@@ -46,7 +46,10 @@ const { boot, check, done } = require('./helpers/app');
// Navbar/footer init payload matches the shared-chrome contract.
// Navbar/footer init payload matches the shared-chrome contract.
const cfg = JSON.parse(r.text.match(/window\.__OV_PAGE = (.*);\n/)[1]);
const cfg = JSON.parse(r.text.match(/window\.__OV_PAGE = (.*);\n/)[1]);
assert.strictEqual(cfg.navbar.service, 'community');
assert.strictEqual(cfg.navbar.service, 'community');
- assert.deepStrictEqual(cfg.navbar.links.map((l) => l.href), ['/pastes', '/s', '/pulse', '/search', '/new']);
+ // The bar (2026-10-28): the forum first, every place with an icon (the phone app bar); search is the magnifier,
+ // which offers this site's own search page first.
+ assert.deepStrictEqual(cfg.navbar.links.map((l) => l.href), ['/s', '/pastes', '/pulse', '/new']);
+ assert.ok(cfg.navbar.links.every((l) => l.icon) && cfg.navbar.appBar === true && cfg.navbar.search && cfg.navbar.search.page === '/search');
assert.strictEqual(cfg.navbar.menu.after[0].href, '/my');
assert.strictEqual(cfg.navbar.menu.after[0].href, '/my');
assert.strictEqual(cfg.navbar.history.type, 'page');
assert.strictEqual(cfg.navbar.history.type, 'page');
assert.strictEqual(cfg.navbar.silentLogin, 'https://openvibe.community/auth/login?silent=1&next={url}');
assert.strictEqual(cfg.navbar.silentLogin, 'https://openvibe.community/auth/login?silent=1&next={url}');