From 044c585f73cfd548e300859e89eaf5dcb40d3d3c Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Sat, 10 Oct 2026 12:35:15 +0200 Subject: 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 --- .../kotlin/org/meshbay/client/photos/PhotoChannels.kt | 2 +- .../src/meshbay_hub/static/android-sync-page.js | 16 ++++++++++++++++ packages/meshbay-hub/src/meshbay_hub/static/app.js | 16 ++++++++++++++++ packages/meshbay-hub/src/meshbay_hub/static/icon.js | 2 ++ .../meshbay-hub/src/meshbay_hub/static/locales/de.js | 2 ++ .../meshbay-hub/src/meshbay_hub/static/locales/en.js | 2 ++ .../meshbay-hub/src/meshbay_hub/static/locales/es.js | 2 ++ .../meshbay-hub/src/meshbay_hub/static/locales/fr.js | 2 ++ .../meshbay-hub/src/meshbay_hub/static/locales/it.js | 2 ++ .../meshbay-hub/src/meshbay_hub/static/locales/ja.js | 2 ++ .../meshbay-hub/src/meshbay_hub/static/locales/nl.js | 2 ++ .../meshbay-hub/src/meshbay_hub/static/locales/pl.js | 2 ++ .../meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js | 2 ++ .../meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js | 2 ++ .../src/meshbay_hub/static/photo-sync-settings.js | 5 +++-- .../meshbay-hub/src/meshbay_hub/static/settings-page.js | 8 -------- packages/meshbay-hub/tests/harness/photo_sync_probe.py | 7 ++++--- packages/meshbay-hub/tests/test_first_load_is_lean.py | 2 +- packages/meshbay-hub/tests/test_hook_ordering.py | 4 ++-- packages/meshbay-hub/tests/test_photo_sync_ui.py | 2 +- 20 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 packages/meshbay-hub/src/meshbay_hub/static/android-sync-page.js (limited to 'packages') diff --git a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/photos/PhotoChannels.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/photos/PhotoChannels.kt index 874f5f3..ee14984 100644 --- a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/photos/PhotoChannels.kt +++ b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/photos/PhotoChannels.kt @@ -256,7 +256,7 @@ class PhotoChannels( ensureChannel(activity) val open = Intent(activity, MainActivity::class.java).setAction(Intent.ACTION_VIEW) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP) - .putExtra(Notifier.EXTRA_LINK, "#/settings") + .putExtra(Notifier.EXTRA_LINK, "#/android-sync") val pending = PendingIntent.getActivity(activity, NOTIFY_ID, open, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT) nm.notify(NOTIFY_ID, Notification.Builder(activity, CHANNEL) 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` +
+

${t('androidsync.title')}

+ <${PhotoSyncSection} user=${user} groups=${groups || []} /> +
+ `; +} 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')} `} + ${platform.photoSync.available && html` + + `} - ${platform.photoSync.available && html` - <${PhotoSyncSection} user=${user} groups=${groups || []} />`} -

${t('settings.defaults')}

diff --git a/packages/meshbay-hub/tests/harness/photo_sync_probe.py b/packages/meshbay-hub/tests/harness/photo_sync_probe.py index 48d9270..08c21b9 100644 --- a/packages/meshbay-hub/tests/harness/photo_sync_probe.py +++ b/packages/meshbay-hub/tests/harness/photo_sync_probe.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 """ The phone's photo backup section (photo-sync-settings.js), rendered in Chrome -at phone widths with names nobody would choose for a fixture. +on its page (android-sync-page.js) at phone widths with names nobody would +choose for a fixture. Only the Android application has this section, and its engine is Chromium, so one engine is the whole of it. The bridge is a stand-in that answers the way @@ -89,12 +90,12 @@ window.meshbay = { import { html, render } from './vendor/htm-preact.js'; import { initLocale } from './i18n.js'; import { startPhotoSync } from './photo-sync.js'; -import { PhotoSyncSection } from './photo-sync-settings.js'; +import { AndroidSyncPage } from './android-sync-page.js'; await initLocale(); startPhotoSync({ hub: '', getUser: () => ({ username: 'bob', token: 't' }), getBundleKey: async () => '' }); const groups = [{ id: 'g1', name: '__GROUP__', owner_username: '__OWNER__' }]; -render(html`<${PhotoSyncSection} user=${{ username: 'bob', token: 't' }} groups=${groups} />`, +render(html`<${AndroidSyncPage} user=${{ username: 'bob', token: 't' }} groups=${groups} />`, document.getElementById('root')); setTimeout(() => { if (MODE === 'configured') return; diff --git a/packages/meshbay-hub/tests/test_first_load_is_lean.py b/packages/meshbay-hub/tests/test_first_load_is_lean.py index 25638ca..324ba0c 100644 --- a/packages/meshbay-hub/tests/test_first_load_is_lean.py +++ b/packages/meshbay-hub/tests/test_first_load_is_lean.py @@ -25,7 +25,7 @@ ON_DEMAND = { "photos-app-settings.js", "helloworld-app-settings.js", "video-player.js", "group-settings.js", "search-page.js", # The Android application's photo backup: no browser or desktop has it. - "photo-sync.js", "photo-sync-settings.js", + "photo-sync.js", "photo-sync-settings.js", "android-sync-page.js", } diff --git a/packages/meshbay-hub/tests/test_hook_ordering.py b/packages/meshbay-hub/tests/test_hook_ordering.py index 73bac38..124bfb8 100644 --- a/packages/meshbay-hub/tests/test_hook_ordering.py +++ b/packages/meshbay-hub/tests/test_hook_ordering.py @@ -54,8 +54,8 @@ STATIC_FILES = [ "menu.js", "playlist-menu.js", # The page's own confirm/alert, mounted outside the app tree. "ask.js", - # The Android application's photo backup, loaded by Settings on demand. - "settings-page.js", "photo-sync-settings.js", + # The Android application's photo backup, on its own page loaded on demand. + "settings-page.js", "android-sync-page.js", "photo-sync-settings.js", ] pytestmark = pytest.mark.skipif(not APP.exists(), reason="SPA sources unavailable") diff --git a/packages/meshbay-hub/tests/test_photo_sync_ui.py b/packages/meshbay-hub/tests/test_photo_sync_ui.py index bd512c1..6222b26 100644 --- a/packages/meshbay-hub/tests/test_photo_sync_ui.py +++ b/packages/meshbay-hub/tests/test_photo_sync_ui.py @@ -1,5 +1,5 @@ """ -The photo backup section in Settings, measured in Chrome at phone widths +The photo backup section of the Android Sync page, measured in Chrome at phone widths (harness/photo_sync_probe.py). Android's WebView is the only engine that ever shows it. -- cgit v1.2.3