mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 00:16:59 +00:00
Completes the favorites system: a favorited nsite/napplet can now be pinned to the bottom bar and render as an embedded, swap-in-place tab — no longer only a full-screen activity launch. New sandbox surface (:napplet, keyless), mirroring the browser embed: - NappletHostService hosts the verified-blob WebView (same content server, shell bridge, and single launch-token broker path as NappletHostActivity) and ships it as a SandboxedUiAdapter surface, so applet JS still runs only in the keyless process — never where the keys live. - NappletHostUiAdapter / NappletEmbedContract are the SurfaceControlViewHost adapter and the Messenger contract; the create-session bundle reuses NappletHostContract's EXTRA_* keys, so the embedded and full-screen host paths launch from identical, main-process-minted parameters. Main process: - NappletLauncher.buildLaunchParams extracts the verified param/token minting so both the activity intent and the embedded session share it. - EmbeddedNappletController binds the service and attaches the surface (mirror of EmbeddedBrowserController). - FavoriteNappletScreen draws the TRUSTED CHROME (sandbox shield, app name, "what it can access") in the main process around the surface — the sandbox must never draw chrome the user is meant to trust — plus a pop-out to the full-screen host. Capability consent still flows through the existing main-process broker + consent activity, unchanged and host-agnostic. Security parity with the full-screen host: - The applet's JS + timers are paused while the app is backgrounded (lifecycle ON_STOP/ON_START → MSG_PAUSE/MSG_RESUME), so an "allow always" napplet can't act on the user's behalf when they aren't looking. - Granted sensitive ops (publish/upload/pay) surface a notice toast. Both favorite kinds are now pinnable; the bottom bar routes WebUrl → FavoriteWebApp and NostrApp → FavoriteNostrApp, each embedding in place. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgMpRcWj6y82LxLiwcuzmN