45 lines
1.6 KiB
JavaScript
45 lines
1.6 KiB
JavaScript
|
|
// Minimal service worker: only exists to catch the POST /share-target
|
||
|
|
// request from Android's share sheet (required for Web Share Target to
|
||
|
|
// work — the browser needs an installed SW controlling the scope). Stores
|
||
|
|
// the shared files in a temporary Cache entry, then redirects to a page
|
||
|
|
// that reads them and feeds them into the send flow.
|
||
|
|
|
||
|
|
const SHARE_CACHE = 'flit-share-v1'
|
||
|
|
|
||
|
|
self.addEventListener('install', (event) => {
|
||
|
|
self.skipWaiting()
|
||
|
|
})
|
||
|
|
|
||
|
|
self.addEventListener('activate', (event) => {
|
||
|
|
event.waitUntil(self.clients.claim())
|
||
|
|
})
|
||
|
|
|
||
|
|
self.addEventListener('fetch', (event) => {
|
||
|
|
const url = new URL(event.request.url)
|
||
|
|
if (event.request.method === 'POST' && url.pathname === '/share-target') {
|
||
|
|
event.respondWith(handleShareTarget(event))
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
async function handleShareTarget(event) {
|
||
|
|
const formData = await event.request.formData()
|
||
|
|
const files = formData.getAll('files')
|
||
|
|
const cache = await caches.open(SHARE_CACHE)
|
||
|
|
await cache.put('/shared-files', new Response(await packFiles(files)))
|
||
|
|
return Response.redirect('/?shared=1', 303)
|
||
|
|
}
|
||
|
|
|
||
|
|
async function packFiles(files) {
|
||
|
|
// Pack as a multipart-ish JSON manifest + blobs isn't trivial inside a SW;
|
||
|
|
// simplest robust approach: store each file as its own cache entry keyed
|
||
|
|
// by index, plus a manifest of names/types.
|
||
|
|
const cache = await caches.open(SHARE_CACHE)
|
||
|
|
const manifest = []
|
||
|
|
for (let i = 0; i < files.length; i++) {
|
||
|
|
const f = files[i]
|
||
|
|
manifest.push({ name: f.name, type: f.type, size: f.size, key: `/shared-file-${i}` })
|
||
|
|
await cache.put(`/shared-file-${i}`, new Response(f))
|
||
|
|
}
|
||
|
|
return JSON.stringify(manifest)
|
||
|
|
}
|