aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-10 12:35:15 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-10 12:35:15 +0200
commit044c585f73cfd548e300859e89eaf5dcb40d3d3c (patch)
tree89d90fa844c4a453c84a228f541b84040c9f782d /packages/meshbay-hub/src/meshbay_hub
parent0ead6a321fbe3cf97e22f6fee348f68b09bd53a8 (diff)
downloadmeshbay-044c585f73cfd548e300859e89eaf5dcb40d3d3c.tar.gz
feat(hub): photo backup moves to its own Android Sync page
A Phone section of the side menu leads to it, on the Android application only; Settings no longer holds it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/android-sync-page.js16
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/app.js16
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/icon.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/de.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/en.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/es.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/it.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/photo-sync-settings.js5
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/settings-page.js8
15 files changed, 57 insertions, 10 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/android-sync-page.js b/packages/meshbay-hub/src/meshbay_hub/static/android-sync-page.js
new file mode 100644
index 0000000..6285b3c
--- /dev/null
+++ b/packages/meshbay-hub/src/meshbay_hub/static/android-sync-page.js
@@ -0,0 +1,16 @@
+// The Android Sync page: what this phone sends to its groups, on the Android
+// application only (docs/MESHBAY_DESIGN.md §9.12). Loaded on demand, like the
+// sections it holds: no other client has it.
+
+import { html } from './vendor/htm-preact.js';
+import { t } from './i18n.js';
+import { PhotoSyncSection } from './photo-sync-settings.js';
+
+export function AndroidSyncPage({ user, groups }) {
+ return html`
+ <div>
+ <h2>${t('androidsync.title')}</h2>
+ <${PhotoSyncSection} user=${user} groups=${groups || []} />
+ </div>
+ `;
+}
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/app.js b/packages/meshbay-hub/src/meshbay_hub/static/app.js
index 41a608f..973729e 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/app.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/app.js
@@ -463,6 +463,13 @@ function Sidebar({ groups, presence, indexProgressPct, route, menuOpen, role, sh
href="#/create-group"><${Icon} name="plus" /> ${t('sidebar.create_group')}</a>
</div>
`}
+ ${platform.photoSync.available && html`
+ <div class="sidebar-section">
+ <div class="sidebar-heading">${t('sidebar.phone')}</div>
+ <a class="sidebar-item ${route === '/android-sync' ? 'active' : ''}"
+ href="#/android-sync"><${Icon} name="phone" /> ${t('androidsync.title')}</a>
+ </div>
+ `}
<div class="sidebar-section">
<div class="sidebar-heading">${t('sidebar.my_groups')}</div>
${groups.length === 0
@@ -706,6 +713,13 @@ function SetupWelcome({ onDismiss }) {
const SearchPage = lazy(() => import('./search-page.js'), 'SearchPage',
html`<div class="page-content"><p class="page-message"><span class="spinner"></span></p></div>`);
+// ── Lazy-loaded Android Sync page ────────────────────────────────────────────
+//
+// The Android application's photo backup (docs/MESHBAY_DESIGN.md §9.12): no
+// browser or desktop ever fetches it.
+const AndroidSyncPage = lazy(() => import('./android-sync-page.js'), 'AndroidSyncPage',
+ html`<div class="page-content"><p class="page-message"><span class="spinner"></span></p></div>`);
+
// ── Lazy-loaded Create Group page ────────────────────────────────────────────
let _CreateGroupPage = null;
@@ -1427,6 +1441,8 @@ function App() {
allowPublicGroups=${allowPublicGroups}
token=${user.token} onGroupsChanged=${reloadGroups}
onMarkRead=${markRead} onPurge=${purgeNotifications} />`;
+ } else if (route === '/android-sync' && platform.photoSync.available) {
+ page = html`<${AndroidSyncPage} user=${user} groups=${groups} />`;
} else if (route === '/settings') {
page = html`<${SettingsPage} user=${user} theme=${theme}
onThemeChange=${setTheme} groups=${groups}
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/icon.js b/packages/meshbay-hub/src/meshbay_hub/static/icon.js
index 4d549f1..36db0fe 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/icon.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/icon.js
@@ -87,6 +87,8 @@ const ICON_PATHS = {
server: ['M4 6.5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-2z',
'M4 15.5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-2z',
'M8 7.5h.01', 'M8 16.5h.01'],
+ phone: ['M8 2.5h8a1.5 1.5 0 0 1 1.5 1.5v16a1.5 1.5 0 0 1-1.5 1.5H8A1.5 1.5 0 0 1 6.5 20V4A1.5 1.5 0 0 1 8 2.5z',
+ 'M11 18h2'],
cast: ['M2 16.1A5 5 0 0 1 6.9 21', 'M2 12.05A9 9 0 0 1 12.95 21',
'M2 8V6a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6',
'M2 21h.01'],
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 1fc734c..9149f21 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
@@ -920,6 +920,8 @@ export default {
'lazy.reload': 'Seite neu laden',
// Sidebar
+ 'sidebar.phone': 'Telefon',
+ 'androidsync.title': 'Android Sync',
'sidebar.node': 'Node',
// Node admin
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 6f3be87..259d728 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
@@ -1021,6 +1021,8 @@ export default {
'usermenu.profile': 'Profile',
// Node management (D5)
+ 'sidebar.phone': 'Phone',
+ 'androidsync.title': 'Android Sync',
'sidebar.node': 'Node',
'node.title': 'Node',
'node.service_checking': 'Checking node service…',
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 47490d4..b1b1328 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
@@ -914,6 +914,8 @@ export default {
'lazy.reload': 'Recargar la página',
// Sidebar
+ 'sidebar.phone': 'Teléfono',
+ 'androidsync.title': 'Android Sync',
'sidebar.node': 'Node',
// Node admin
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 54588b0..01b028b 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
@@ -917,6 +917,8 @@ export default {
'lazy.reload': 'Recharger la page',
// Sidebar
+ 'sidebar.phone': 'Téléphone',
+ 'androidsync.title': 'Android Sync',
'sidebar.node': 'Node',
// Node admin
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 5d438a9..19e0c6d 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
@@ -916,6 +916,8 @@ export default {
'lazy.reload': 'Ricarica la pagina',
// Sidebar
+ 'sidebar.phone': 'Telefono',
+ 'androidsync.title': 'Android Sync',
'sidebar.node': 'Node',
// Node admin
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 1505026..07dcac4 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
@@ -904,6 +904,8 @@ export default {
'lazy.reload': 'ページを再読み込み',
// Sidebar
+ 'sidebar.phone': 'スマートフォン',
+ 'androidsync.title': 'Android Sync',
'sidebar.node': 'Node',
// Node admin
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 858acbf..ab7abbd 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
@@ -918,6 +918,8 @@ export default {
'lazy.reload': 'Pagina opnieuw laden',
// Sidebar
+ 'sidebar.phone': 'Telefoon',
+ 'androidsync.title': 'Android Sync',
'sidebar.node': 'Node',
// Node admin
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 57b4b8a..6539e0d 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
@@ -936,6 +936,8 @@ export default {
'lazy.reload': 'Wczytaj stronę ponownie',
// Sidebar (supplementary)
+ 'sidebar.phone': 'Telefon',
+ 'androidsync.title': 'Android Sync',
'sidebar.node': 'Node',
// Node admin
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 23045fb..ac122c0 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
@@ -915,6 +915,8 @@ export default {
'lazy.reload': 'Recarregar a página',
// Sidebar
+ 'sidebar.phone': 'Celular',
+ 'androidsync.title': 'Android Sync',
'sidebar.node': 'Node',
// Node admin
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 8070b5f..14664c4 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
@@ -892,6 +892,8 @@ export default {
'lazy.reload': '重新加载页面',
// Sidebar
+ 'sidebar.phone': '手机',
+ 'androidsync.title': 'Android Sync',
'sidebar.node': 'Node',
// Node admin
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/photo-sync-settings.js b/packages/meshbay-hub/src/meshbay_hub/static/photo-sync-settings.js
index 1ec68d3..b5e9a30 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/photo-sync-settings.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/photo-sync-settings.js
@@ -1,5 +1,6 @@
-// The "Photo backup" section of Settings, on the Android application only
-// (docs/MESHBAY_DESIGN.md §9.12). Loaded on demand: no other client has it.
+// The "Photo backup" section of the Android Sync page, on the Android
+// application only (docs/MESHBAY_DESIGN.md §9.12). Loaded on demand: no other
+// client has it.
import { html, useState, useEffect, useCallback } from './vendor/htm-preact.js';
import { t } from './i18n.js';
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/settings-page.js b/packages/meshbay-hub/src/meshbay_hub/static/settings-page.js
index 8826520..985b219 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/settings-page.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/settings-page.js
@@ -7,15 +7,10 @@ import * as platform from './platform.js';
import { hubFetch } from './hub-client.js';
import { syncPush, enablePush, disablePush } from './push.js';
import { APPS } from './apps.js';
-import { lazy } from './lazy.js';
import {
PAGE_SIZE_PREF, PAGE_SIZE_DEFAULT, PAGE_SIZE_STEP, PAGE_SIZE_MAX, pageSizeFrom,
} from './pager.js';
-// Photo backup exists on the Android application only, so its module is
-// fetched there and nowhere else (docs/MESHBAY_DESIGN.md §9.12).
-const PhotoSyncSection = lazy(() => import('./photo-sync-settings.js'), 'PhotoSyncSection', null);
-
const PAGE_SIZES = Array.from(
{ length: PAGE_SIZE_MAX / PAGE_SIZE_STEP }, (_, i) => (i + 1) * PAGE_SIZE_STEP);
@@ -301,9 +296,6 @@ export function SettingsPage({ user, theme, onThemeChange, groups, onPrefsChange
`}
</div>
- ${platform.photoSync.available && html`
- <${PhotoSyncSection} user=${user} groups=${groups || []} />`}
-
<div class="settings-section">
<h3 class="settings-heading">${t('settings.defaults')}</h3>
<div class="settings-row">