41 lines
2.2 KiB
Diff
41 lines
2.2 KiB
Diff
--- a/frontend/p2p-client.js
|
|
+++ b/frontend/p2p-client.js
|
|
@@ -160,7 +160,7 @@
|
|
// Send one saved video to the server so it can hash + validate it and add its
|
|
// cid to the catalog. Uploads the whole file: only on the user's request
|
|
// ("Verify & share") or when the server asks for a copy (plan 018).
|
|
- async function contribute(videoId, { cid = null, title = '', channel = '' } = {}) {
|
|
+ async function contribute(videoId, { cid = null, title = '', channel = '', restore = false } = {}) {
|
|
const dev = await ensureDevice();
|
|
const rec = await window.DeviceDB.getFile(videoId);
|
|
const file = window.OPFS.getFileObject ? await window.OPFS.getFileObject(videoId) : null;
|
|
@@ -168,7 +168,7 @@
|
|
const h = { 'X-Device': dev.deviceId + '.' + dev.secret };
|
|
const t = await (await fetch('/api/p2p/intake', {
|
|
method: 'POST', headers: { ...h, 'Content-Type': 'application/json' },
|
|
- body: JSON.stringify({ videoId, cid: cid || (rec && rec.cid) || undefined, size: file.size, title, channel }),
|
|
+ body: JSON.stringify({ videoId, cid: cid || (rec && rec.cid) || undefined, size: file.size, title, channel, restore }),
|
|
})).json().catch(() => ({ ok: false, error: 'server unreachable' }));
|
|
if (!t.ok || t.known) { if (t.known) changed(); return t; }
|
|
const r = await (await fetch(t.url, { method: 'PUT', headers: h, body: file }))
|
|
@@ -280,6 +280,19 @@
|
|
timer = setTimeout(sync, 5000);
|
|
}
|
|
|
|
+ // Plan 018: the server lost its copy and the source is gone — it asks one
|
|
+ // holder to send the file back. Only while sharing is on, one at a time,
|
|
+ // and only for the exact cid this device holds.
|
|
+ let restoring = false;
|
|
+ onMessage('upload-request', async (m) => {
|
|
+ if (restoring || hooks.getSettings().p2pShare === false) return;
|
|
+ const rec = window.DeviceDB ? await window.DeviceDB.getFile(m.videoId) : null;
|
|
+ if (!rec || rec.cid !== m.cid) return;
|
|
+ restoring = true;
|
|
+ try { await contribute(m.videoId, { cid: m.cid, restore: true }); } catch { /* next request retries */ }
|
|
+ finally { restoring = false; }
|
|
+ });
|
|
+
|
|
function start(h) {
|
|
hooks = { ...hooks, ...(h || {}) };
|
|
const idle = window.requestIdleCallback || ((fn) => setTimeout(fn, 1));
|