openvibers/openvibe.mediahub Commits

The bar: main places with icons and the phone app bar, the rest under More (What shipped and Search leave it) (#168)

OP OpenVibers committed 16 days ago · fb00592b66 · 3 files, +27 −11

* The bar: the main places with icons (the phone app bar), the rest under More, What shipped in the footer, Search is the magnifier

* Video's bar: Videos, Upload, Record and Your videos with icons (the phone app bar), Playlists under More, Search is the magnifier (this site's search first)

* Video's navbar check reads the tidied bar: icons, Playlists under More, Search as the magnifier

Changes

ddiff --git a/server/render/layout.js b/server/render/layout.js
iindex 858275f..d8dcc77 100644
---- a/server/render/layout.js
++++ b/server/render/layout.js
@@@ -23,12 +23,12 @@ const NETWORK_URL = 'https://openvibe.network';
const SITE_NAME = 'OpenVibe.Download';
const TAGLINE = 'Your files, shared on your terms.';
const PUBLIC_DIR = path.join(__dirname, '..', '..', 'public');
--// The product's own navigation: one entry per public page it serves.
++// 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 and What shipped is the footer's.
const NAV = [
-- { label: 'Your files', href: '/files' },
-- { label: 'Backups', href: '/sync' },
-- { label: 'Safety', href: '/safety' },
-- { label: 'What shipped', href: '/updates' },
++ { label: 'Your files', href: '/files', icon: 'fa-file-lines' },
++ { label: 'Backups', href: '/sync', icon: 'fa-clock-rotate-left' },
++ { label: 'Safety', href: '/safety', icon: 'fa-shield-halved', more: true },
];
const hashes = new Map();
@@@ -59,7 +59,8 @@ function renderPage(o) {
const nav = {
service: 'media-hub',
apiBase: NETWORK_URL,
-- links: NAV.map((l) => ({ label: l.label, href: l.href, active: pathNow === l.href || pathNow.startsWith(`${l.href}/`) })),
++ links: NAV.map((l) => ({ label: l.label, href: l.href, ...(l.icon ? { icon: l.icon } : {}), ...(l.more ? { more: true } : {}), active: pathNow === l.href || pathNow.startsWith(`${l.href}/`) })),
++ appBar: true, // phones: the places with icons as the bottom tab bar (Shared 4.20)
history: { type: 'page', title: o.title || SITE_NAME },
silentLogin: `${o.config.baseUrl}/auth/login?silent=1&next={url}`,
sessionUrl: '/auth/me',
ddiff --git a/server/video/layout.js b/server/video/layout.js
iindex 36f3b20..8f4f01c 100644
---- a/server/video/layout.js
++++ b/server/video/layout.js
@@@ -79,7 +79,9 @@ ${render(o.body)}
navbar: {
service: 'media-hub',
apiBase: NETWORK_URL,
-- links: NAV_LINKS.map((l) => ({ ...l, active: l.href === '/' ? o.path === '/' : String(o.path || '').startsWith(l.href) })),
++ links: NAV_LINKS.filter((l) => !l.noscriptOnly).map(({ noscriptOnly, ...l }) => ({ ...l, active: l.href === '/' ? o.path === '/' : String(o.path || '').startsWith(l.href) })),
++ appBar: true, // phones: the places with icons as the bottom tab bar (Shared 4.20)
++ search: { page: '/search', label: 'OpenVibe.Video' },
history: { type: 'page', title },
sessionUrl: '/auth/me',
loginUrl: '/auth/login?next={path}',
@@@ -95,7 +97,17 @@ ${render(o.body)}
}
// The site's own places in the navbar: the videos, and your playlists (signed in; the page asks you to sign in).
--const NAV_LINKS = [{ label: 'Videos', href: '/' }, { label: 'Search', href: '/search' }, { label: 'Upload', href: '/upload' }, { label: 'Record', href: '/record' }, { label: 'Your videos', href: '/me/videos' }, { label: 'Playlists', href: '/playlists' }];
++// The places: the main ones carry an icon (phones get them as the bottom tab bar), Playlists folds into the navbar's More
++// (Shared 4.22). Search is the navbar's magnifier, which offers this site's own search first; the page without
++// JavaScript keeps its Search link.
++const NAV_LINKS = [
++ { label: 'Videos', href: '/', icon: 'fa-play' },
++ { label: 'Search', href: '/search', icon: 'fa-magnifying-glass', noscriptOnly: true },
++ { label: 'Upload', href: '/upload', icon: 'fa-upload' },
++ { label: 'Record', href: '/record', icon: 'fa-video' },
++ { label: 'Your videos', href: '/me/videos', icon: 'fa-photo-film' },
++ { label: 'Playlists', href: '/playlists', icon: 'fa-list-check', more: true },
++];
// A signed-out copy is never reused without asking: Cloudflare drops `Vary` (it keeps only Accept-Encoding), so a
// browser keyed the guest copy by its URL alone and, for five minutes after a quiet sign-in, showed the signed-out page
ddiff --git a/test/video-pages.test.js b/test/video-pages.test.js
iindex 06ad5cb..28a9db4 100644
---- a/test/video-pages.test.js
++++ b/test/video-pages.test.js
@@@ -501,10 +501,13 @@ function countOccurrences(haystack, needle) {
assert.ok(none.text.includes('Nothing matched') && !none.text.includes('<script>alert(1)'), 'nothing found, and the words are escaped');
});
-- await check('the navbar names the site\'s places: Videos, Search, Upload, Record, Your videos and Playlists, the current one active', async () => {
++ // The bar (2026-10-28): the places with icons (the phone app bar), Playlists under More, Search is the magnifier
++ // (this site's search first); the page without JavaScript keeps its Search link.
++ await check('the navbar names the site\'s places: Videos, Upload, Record, Your videos, and Playlists under More; Search is the magnifier', async () => {
const home = (await getVideo('/')).text;
-- assert.match(home, /"links":\[\{"label":"Videos","href":"\/","active":true\},\{"label":"Search","href":"\/search","active":false\},\{"label":"Upload","href":"\/upload","active":false\},\{"label":"Record","href":"\/record","active":false\},\{"label":"Your videos","href":"\/me\/videos","active":false\},\{"label":"Playlists","href":"\/playlists","active":false\}\]/);
-- assert.ok(home.includes('href="/playlists"'), 'the no-JS nav links Playlists too');
++ assert.match(home, /"links":\[\{"label":"Videos","href":"\/","icon":"fa-play","active":true\},\{"label":"Upload","href":"\/upload","icon":"fa-upload","active":false\},\{"label":"Record","href":"\/record","icon":"fa-video","active":false\},\{"label":"Your videos","href":"\/me\/videos","icon":"fa-photo-film","active":false\},\{"label":"Playlists","href":"\/playlists","icon":"fa-list-check","more":true,"active":false\}\]/);
++ assert.ok(/"appBar":true/.test(home) && /"search":\{"page":"\/search","label":"OpenVibe.Video"\}/.test(home), 'the app bar, and the magnifier offers Video\'s search first');
++ assert.ok(home.includes('href="/playlists"') && home.includes('href="/search"'), 'the no-JS nav links Playlists and Search too');
});
await check('/updates: the shared update log on the video host, one heading, in the sitemap', async () => {