From 4b74ff3fc54f35fbc41d9c0f7d2b4ec89475154a Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Fri, 11 Sep 2026 13:57:34 +0200 Subject: feat(hub): legal information link at the foot of the sidebar A small link to the hub's legal pages, pinned to the bottom of the sidebar once signed in. It opens in a new tab: the desktop application refuses to navigate away from its interface and hands a new window to the system browser, and in a browser it keeps the session on screen. The address comes from hubBase(), so it is the legal pages of the hub in use. The sidebar now sticks under the navigation bar at the window's height; otherwise, on a long file list, the link would sit at the bottom of the page. The music bar, pinned to the bottom of the window as well, publishes its height through useStickyBand as --music-bar-h and the sidebar stops above it. On a phone the slide-out panel does the same. test_sidebar_legal_measured.py measures the real stylesheet: the link at the bottom of the window on a 3000px page, and above the music bar, at phone and desktop widths. Checked signed in on a local hub in Chrome and Firefox 155. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01D9MCBBWSm9GhBESmqzJxNy --- packages/meshbay-hub/src/meshbay_hub/static/app.js | 10 +++++++++ .../src/meshbay_hub/static/locales/de.js | 1 + .../src/meshbay_hub/static/locales/en.js | 1 + .../src/meshbay_hub/static/locales/es.js | 1 + .../src/meshbay_hub/static/locales/fr.js | 1 + .../src/meshbay_hub/static/locales/it.js | 1 + .../src/meshbay_hub/static/locales/ja.js | 1 + .../src/meshbay_hub/static/locales/nl.js | 1 + .../src/meshbay_hub/static/locales/pl.js | 1 + .../src/meshbay_hub/static/locales/pt-BR.js | 1 + .../src/meshbay_hub/static/locales/zh-CN.js | 1 + .../src/meshbay_hub/static/music-player.js | 6 +++++- .../meshbay-hub/src/meshbay_hub/static/style.css | 24 ++++++++++++++++++++-- 13 files changed, 47 insertions(+), 3 deletions(-) (limited to 'packages/meshbay-hub/src/meshbay_hub/static') diff --git a/packages/meshbay-hub/src/meshbay_hub/static/app.js b/packages/meshbay-hub/src/meshbay_hub/static/app.js index dfd0aeb..ba24822 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/app.js @@ -474,10 +474,20 @@ function Sidebar({ groups, presence, indexProgressPct, route, menuOpen, role, ha }) } + + ${t('sidebar.legal')} `; } +// The legal pages of the hub in use: the page's own origin in a browser, the +// configured hub in the application. A new tab either way: the application +// refuses to navigate away from its interface and hands a new window to the +// system browser instead, and in a browser it keeps the session on screen. +function legalUrl() { + return `${platform.hubBase().replace(/\/$/, '')}/legal/`; +} + // ── Home Page ──────────────────────────────────────────────────────────────── function NotificationFeed({ notifications, onMarkRead, onPurge }) { diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js index 116bbe9..7eed742 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js @@ -23,6 +23,7 @@ export default { // Sidebar 'sidebar.my_groups': 'Meine Gruppen', 'sidebar.no_groups': 'Noch keine Gruppen', + 'sidebar.legal': 'Rechtliche Hinweise', 'sidebar.discover': 'Entdecken', 'sidebar.public_groups': 'Öffentliche Gruppen', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js index 80dd819..143f462 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js @@ -26,6 +26,7 @@ export default { // Sidebar 'sidebar.my_groups': 'My Groups', 'sidebar.no_groups': 'No groups yet', + 'sidebar.legal': 'Legal information', 'sidebar.discover': 'Discover', 'sidebar.public_groups': 'Public groups', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js index 9f8b60e..f35d05d 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js @@ -22,6 +22,7 @@ export default { // Sidebar 'sidebar.my_groups': 'Mis grupos', 'sidebar.no_groups': 'Aún no hay grupos', + 'sidebar.legal': 'Información legal', 'sidebar.discover': 'Descubrir', 'sidebar.public_groups': 'Grupos públicos', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js index d928f52..e8ac577 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js @@ -22,6 +22,7 @@ export default { // Sidebar 'sidebar.my_groups': 'Mes groupes', 'sidebar.no_groups': 'Aucun groupe pour le moment', + 'sidebar.legal': 'Informations légales', 'sidebar.discover': 'Découvrir', 'sidebar.public_groups': 'Groupes publics', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js index 58e2389..76caa51 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js @@ -23,6 +23,7 @@ export default { // Sidebar 'sidebar.my_groups': 'I miei gruppi', 'sidebar.no_groups': 'Ancora nessun gruppo', + 'sidebar.legal': 'Note legali', 'sidebar.discover': 'Esplora', 'sidebar.public_groups': 'Gruppi pubblici', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js index 234b238..a6c39ee 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js @@ -23,6 +23,7 @@ export default { // Sidebar 'sidebar.my_groups': 'マイグループ', 'sidebar.no_groups': 'グループはまだありません', + 'sidebar.legal': '法的情報', 'sidebar.discover': '見つける', 'sidebar.public_groups': '公開グループ', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js index 72511f5..e4a7914 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js @@ -23,6 +23,7 @@ export default { // Sidebar 'sidebar.my_groups': 'Mijn groepen', 'sidebar.no_groups': 'Nog geen groepen', + 'sidebar.legal': 'Juridische informatie', 'sidebar.discover': 'Ontdekken', 'sidebar.public_groups': 'Openbare groepen', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js index 12a31aa..d13e3ef 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js @@ -26,6 +26,7 @@ export default { // Sidebar 'sidebar.my_groups': 'Moje grupy', 'sidebar.no_groups': 'Nie ma jeszcze żadnych grup', + 'sidebar.legal': 'Informacje prawne', 'sidebar.discover': 'Odkrywaj', 'sidebar.public_groups': 'Grupy publiczne', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js index c5f826b..1b517bb 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js @@ -24,6 +24,7 @@ export default { // Sidebar 'sidebar.my_groups': 'Meus grupos', 'sidebar.no_groups': 'Nenhum grupo ainda', + 'sidebar.legal': 'Informações legais', 'sidebar.discover': 'Descobrir', 'sidebar.public_groups': 'Grupos públicos', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js index e06c5c6..9922a2d 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js @@ -23,6 +23,7 @@ export default { // Sidebar 'sidebar.my_groups': '我的群组', 'sidebar.no_groups': '暂无群组', + 'sidebar.legal': '法律信息', 'sidebar.discover': '发现', 'sidebar.public_groups': '公开群组', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/music-player.js b/packages/meshbay-hub/src/meshbay_hub/static/music-player.js index 2d3c002..a4a8c5c 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/music-player.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/music-player.js @@ -3,6 +3,7 @@ import { } from './vendor/htm-preact.js'; import { t } from './i18n.js'; import { Icon } from './icon.js'; +import { useStickyBand } from './sticky.js'; import { CHUNK_SIZE, pipelinedDownload } from './file-utils.js'; /** @@ -179,6 +180,9 @@ function QueuePanel({ tracks, order, pos, onSelect, onClose }) { } function MusicPlayerBar({ getConnection, queue, onClose, userPrefs }) { + // Pinned to the bottom of the window, over the bottom of the sidebar; the + // sidebar subtracts this so its last entry is not underneath. + const barBand = useStickyBand('--music-bar-h'); const audioRef = useRef(null); const blobCacheRef = useRef(new Map()); // file id -> { url, order: insertion index } const blobInsertRef = useRef(0); @@ -480,7 +484,7 @@ function MusicPlayerBar({ getConnection, queue, onClose, userPrefs }) { : repeat === 'all' ? t('music.player_repeat_all') : t('music.player_repeat_one'); return html` -
+