public/manifest.json declares share_target (POST multipart to /share-target: title/text/url + image/video/audio/pdf/text files). The service worker answers that POST itself: it stashes the form in a Cache API bucket and 303s to the in-app /share page, which lists what arrived, offers a room search, and on pick writes the files into that room's upload-board atom (encrypting first for E2EE rooms via the composer's shared filesToUploadItems) and the title/text/url into its draft, then opens the room — the user still presses Send. The stash is cleared once placed; reopening /share afterwards says so. nginx/caddy examples and the prod image config gain a 303 for /share-target so a POST that reaches the origin before the worker controls the page lands on /share instead of a 405. iOS has no share target support and ignores the manifest entry. Verified headless against the built preview: SW-controlled page → POST /share-target (two PNGs + title + text) → /share lists both files and the text → pick the DM → composer shows both files on the upload board and the text in the draft → /share reports nothing pending. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
103 lines
2.4 KiB
JSON
103 lines
2.4 KiB
JSON
{
|
|
"name": "Lotus Chat",
|
|
"short_name": "Lotus Chat",
|
|
"description": "Lotus Chat \u2014 the Lotus Guild Matrix client",
|
|
"dir": "auto",
|
|
"lang": "en-US",
|
|
"display": "standalone",
|
|
"orientation": "portrait",
|
|
"start_url": "./",
|
|
"background_color": "#0a0a0a",
|
|
"theme_color": "#980000",
|
|
"icons": [
|
|
{
|
|
"src": "./public/res/android/android-chrome-36x36.png",
|
|
"sizes": "36x36",
|
|
"type": "image/png"
|
|
},
|
|
{
|
|
"src": "./public/res/android/android-chrome-48x48.png",
|
|
"sizes": "48x48",
|
|
"type": "image/png"
|
|
},
|
|
{
|
|
"src": "./public/res/android/android-chrome-72x72.png",
|
|
"sizes": "72x72",
|
|
"type": "image/png"
|
|
},
|
|
{
|
|
"src": "./public/res/android/android-chrome-96x96.png",
|
|
"sizes": "96x96",
|
|
"type": "image/png"
|
|
},
|
|
{
|
|
"src": "./public/res/android/android-chrome-144x144.png",
|
|
"sizes": "144x144",
|
|
"type": "image/png"
|
|
},
|
|
{
|
|
"src": "./public/res/android/android-chrome-192x192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png"
|
|
},
|
|
{
|
|
"src": "./public/res/android/android-chrome-256x256.png",
|
|
"sizes": "256x256",
|
|
"type": "image/png"
|
|
},
|
|
{
|
|
"src": "./public/res/android/android-chrome-384x384.png",
|
|
"sizes": "384x384",
|
|
"type": "image/png"
|
|
},
|
|
{
|
|
"src": "./public/res/android/android-chrome-512x512.png",
|
|
"sizes": "512x512",
|
|
"type": "image/png"
|
|
},
|
|
{
|
|
"src": "./public/res/android/maskable-192x192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png",
|
|
"purpose": "maskable"
|
|
},
|
|
{
|
|
"src": "./public/res/android/maskable-512x512.png",
|
|
"sizes": "512x512",
|
|
"type": "image/png",
|
|
"purpose": "maskable"
|
|
}
|
|
],
|
|
"categories": ["social", "communication", "productivity"],
|
|
"share_target": {
|
|
"action": "./share-target",
|
|
"method": "POST",
|
|
"enctype": "multipart/form-data",
|
|
"params": {
|
|
"title": "title",
|
|
"text": "text",
|
|
"url": "url",
|
|
"files": [
|
|
{
|
|
"name": "files",
|
|
"accept": ["image/*", "video/*", "audio/*", "application/pdf", "text/plain"]
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"shortcuts": [
|
|
{
|
|
"name": "New Message",
|
|
"short_name": "DM",
|
|
"description": "Open a new direct message",
|
|
"url": "/",
|
|
"icons": [
|
|
{
|
|
"src": "public/res/android/android-chrome-96x96.png",
|
|
"sizes": "96x96"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|