aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/platform.js
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-10 15:50:39 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-10 15:50:39 +0200
commit1c97ffb91bb4928022e995709d7e55b19cfd18eb (patch)
treeaaa05d17adcd6db4256c01ba79b27dfc7ec96d70 /packages/meshbay-hub/src/meshbay_hub/static/platform.js
parent1521cc1ac0cca7ee8786056f84fa399d5cc268f9 (diff)
downloadmeshbay-1c97ffb91bb4928022e995709d7e55b19cfd18eb.tar.gz
feat(android): back up the files of folders the person chooses
A Files section takes folders through the system picker (no storage permission), refuses DCIM, Pictures and Movies, skips what the photo backup sends, and runs on the photo backup's own runner into <folder>/<account>-drive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/platform.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/platform.js62
1 files changed, 42 insertions, 20 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/platform.js b/packages/meshbay-hub/src/meshbay_hub/static/platform.js
index 8effc21..04e26e6 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/platform.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/platform.js
@@ -247,26 +247,48 @@ export const photoSync = {
completed() { return bridge.photoSync.completed(); },
failed(code, text) { return bridge.photoSync.failed(code, text); },
keepAlive(on, text) { return bridge.photoSync.keepAlive(on, text); },
- /**
- * A photo or video the last plan issued, as what an upload reads (`name`,
- * `size`, `slice(a, b).arrayBuffer()`): each slice is fetched from the phone
- * when it is read, so a video of gigabytes is never whole in this page.
- */
- file(token, name, size) {
- const url = `/photosync/${encodeURIComponent(token)}`;
- const part = (start, end) => ({
- async arrayBuffer() {
- if (end <= start) return new ArrayBuffer(0);
- const r = await fetch(url, { cache: 'no-store', headers: { Range: `bytes=${start}-${end - 1}` } });
- if (r.status !== 206) throw new Error('This photo is no longer on the phone');
- return r.arrayBuffer();
- },
- });
- return {
- name, size,
- slice: (a = 0, b = size) => part(Math.max(0, a), Math.min(b, size)),
- };
- },
+ file: (token, name, size) => rangedFile('/photosync/', token, name, size),
+};
+
+/**
+ * A file the phone issued under `token`, as what an upload reads (`name`,
+ * `size`, `slice(a, b).arrayBuffer()`): each slice is fetched from the phone
+ * when it is read, so a video of gigabytes is never whole in this page.
+ */
+function rangedFile(prefix, token, name, size) {
+ const url = `${prefix}${encodeURIComponent(token)}`;
+ const part = (start, end) => ({
+ async arrayBuffer() {
+ if (end <= start) return new ArrayBuffer(0);
+ const r = await fetch(url, { cache: 'no-store', headers: { Range: `bytes=${start}-${end - 1}` } });
+ if (r.status !== 206) throw new Error('This file is no longer on the phone');
+ return r.arrayBuffer();
+ },
+ });
+ return {
+ name, size,
+ slice: (a = 0, b = size) => part(Math.max(0, a), Math.min(b, size)),
+ };
+}
+
+/**
+ * Backing up folders the person chose through the system's picker
+ * (docs/MESHBAY_DESIGN.md §9.13), to the destination every kind shares.
+ * Android only, like `photoSync`. See drive-sync.js.
+ */
+const driveBridge = bridge && bridge.driveSync;
+export const driveSync = {
+ available: Boolean(driveBridge),
+ status() { return driveBridge.status(); },
+ addFolder() { return driveBridge.addFolder(); },
+ removeFolder(id) { return driveBridge.removeFolder(id); },
+ configure(settings) { return driveBridge.configure(settings); },
+ plan() { return driveBridge.plan(); },
+ sent(token, dir, name) { return driveBridge.sent(token, dir, name); },
+ completed() { return driveBridge.completed(); },
+ failed(code, text) { return driveBridge.failed(code, text); },
+ keepAlive(on, text) { return driveBridge.keepAlive(on, text); },
+ file: (token, name, size) => rangedFile('/drivesync/', token, name, size),
};
/**