feat(pwa): register as an Android share target (#155)
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
This commit is contained in:
@@ -63,10 +63,14 @@ import { UserRoomProfileRenderer } from '../components/UserRoomProfileRenderer';
|
||||
import { HomeCreateRoom } from './client/home/CreateRoom';
|
||||
import { Create } from './client/create';
|
||||
import { getFallbackSession } from '../state/sessions';
|
||||
import { SHARE_PAGE_PATH } from '../../swShare';
|
||||
|
||||
import { RouteError } from './RouteError';
|
||||
import { CallStatusRenderer } from './CallStatusRenderer';
|
||||
import { CallEmbedProvider } from '../components/CallEmbedProvider';
|
||||
|
||||
const Share = React.lazy(() => import('./client/share/Share').then((m) => ({ default: m.Share })));
|
||||
|
||||
const AuthLayout = React.lazy(() => import('./auth').then((m) => ({ default: m.AuthLayout })));
|
||||
const Login = React.lazy(() => import('./auth').then((m) => ({ default: m.Login })));
|
||||
const Register = React.lazy(() => import('./auth').then((m) => ({ default: m.Register })));
|
||||
@@ -380,6 +384,15 @@ export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize)
|
||||
</React.Suspense>
|
||||
}
|
||||
/>
|
||||
{/* [Gitea #155] PWA share-target landing page. */}
|
||||
<Route
|
||||
path={SHARE_PAGE_PATH}
|
||||
element={
|
||||
<React.Suspense fallback={null}>
|
||||
<Share />
|
||||
</React.Suspense>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path={INBOX_PATH}
|
||||
element={
|
||||
|
||||
Reference in New Issue
Block a user