#Amethyst v1.21.0: NApplets in Notes, drss.io Listening, WebXDC, and Pico 8
Highlights:
- **Runs napplets inside their notes**, on Android 11+ and on desktop, and
plays **webxdc apps** attached to posts in a sandbox with no network.
- **Hosts napplets and nSites on desktop** in a bundled Chromium, at parity
with Android.
- **Plays Pico-8** posted as `.p8.png` images, full screen, with
touch, keyboard and gamepad controls.
- **Listens with drss.io**: episodes resume where you stopped, a listen
queue, history, chapters, clips and speed, and drss lists that stay in sync.
- Adds a **Post Layout** setting: Indented, Full Width or Borderless notes.
- **Downloads every Home content type from your follows**, and adds forum
threads, calendar events, code snippets and git to Home.
- Offers **web of trust from a card on Home**, with the provider's relay
adopted in one step.
- Shows **HDR video in HDR** in the fullscreen viewer, and keeps HDR when
compressing with H.265.
- **Plays chess over Nostr** in every build: a Chess feed with your games
and the lobbies of your lists, draw offers, abandonment claims and end
screens, interoperable with Jester and nostr.blue.
- **Redesigns the poll composer** in New Post, and puts the drawing button in
every composer.
- Hardens napplets, nSites and webxdc after a security review: decrypting
needs its own grant, cookies and WebRTC stay out of every frame, and site
cards prefetch within a budget.
- Fixes memory leaks across view models, navigation and app-wide caches, and
uploads that failed with "Stream Closed".
## New Features
### Napplets, nSites and webxdc
- Runs a napplet in place inside its note: Run here, a bar with Open and
Stop, and the last frame left behind when it stops. The feed never prompts:
anything that would ask you is refused and offered as Open instead.
- Runs webxdc apps (`.xdc` attachments and kind-1063 files) from an app card
with Start, in their own storage per account and app, with no network, no
WebRTC and no access to your keys. Shows a progress bar while the archive
downloads, and opens a newer archive of the same app instead of the old one.
- Plays webxdc apps inside their notes, like napplets.
- Adds NAP-OUTBOX: napplets read and publish through people's own relays,
with bounded routing and consent per read or signed kind.
- Follows the current NIP-5D manifests and NAP contracts: single-artifact
manifests, verified icons and kind-aware storage. Napplets published with
the old path-aggregate manifest must be republished.
- Takes WebRTC away from napplets, and from Tor sites on Android.
- Closes the router's local-network and DNS leaks, keeps each site's cached
files to itself per account, and keeps a napplet's game saves when the app
is killed.
- Tells you when Android can't open an nSite.
- Adds NAP-FS: a napplet opens and saves files you pick in the system file
dialog, on Android and desktop, so apps like PhotoHop open. An app inside
a note never opens a picker, and repeated dismissals back off.
- Adds NAP-INC, so napplets like Relay Browser, Blobbi and Emoji Pack
Creator launch and talk to each other, scoped to the account they run as.
- Adds NAP-UPLOAD, which uploads through your Blossom servers, and
NAP-COMMON: profiles, follows, NIP-19 codes, and follow, react and report
under the same prompts as publishing.
- Adds NAP-INTENT: a napplet hands a task to another, and your favorites,
in their order, choose which app handles it.
- Names the capabilities Amethyst doesn't support on a napplet's card
instead of hiding Open.
- Delivers any file type a napplet loads (3D models, archives) except SVG,
HTML and XML, which would run with the napplet's grants.
- Keeps desktop favorites across restarts, and loads their manifests at
start on desktop as on Android.
- Hardens the hosts after a security review:
- Relay reads decrypt DMs, gift wraps and private lists only with a
decrypt grant, and never against a peer the app chose; only events with a
valid signature reach an app.
- `signEvent` needs the signer capability, which only websites hold.
- A declined prompt backs off before it can ask again, Block denies every
capability, and each app has one storage quota across its instances.
- Inline launches run the newest version of an app seen on the device, so
an old signed version can't run with today's grants.
- Cookies and WebRTC are taken from every frame an app makes, the in-app
browser follows the page's Tor route for WebRTC, and desktop turns off
Chromium's network prediction.
- `window.nostr` is offered only on https, .onion and the device itself, and
the file chooser hands pages only other apps' files and fresh captures.
- Site cards prefetch within one shared budget, only from public https
servers, and not when the media setting wouldn't load images.
- Deletes the unpacked webxdc apps opened longest ago once they pass 1 GB,
and caps a Concord channel's webxdc signals at 4 MB.
### Game Cartridges
- Adds a Play button to images that are fantasy-console carts (a 160x205
`.p8.png`), opening a full-screen player on Android and desktop.
- Reads only the first 24 bytes of a candidate image to detect a cart, through
the Tor-aware image client, and only when images may load.
- Plays with a sliding direction pad and O/X buttons that a thumb rolls
between, a haptic tick per press, keyboard and gamepad keys, and sound.
- Opens the game's pause menu on Back instead of closing the player, keeps
the screen on and hides the system bars in landscape.
- Keeps game saves when the app is killed, each cart's saves its own (by the
hash of the cart), and only the two latest games in memory.
- Stops re-encoding a PNG cart on upload, which destroyed the game in its
pixels.
### Chess
- Moves Chess into the navigation catalog as a feed, in release builds too:
listed under Feeds in the drawer and menus, and pinnable to the bottom bar.
- Shows one feed driven by the top-bar list: "Mine" is the games you started,
were challenged to or moved in; any other list is a lobby of its people's
games, and Global every open challenge.
- Plays like a chess site: tap or drag a piece, last-move and check
highlights, and the board always from your own side.
- Adds draw offers that ride on your next move, and a Claim win when the
opponent has been silent for three days.
- Replays only the validated main line, so a player can't rewrite earlier
moves, and refuses illegal moves.
- Shows end screens with the result and the score by player, move notes with
their board, and the games a user ended on their profile's Notes tab.
- Redesigns the new-game dialog and the NIP-64 game viewer.
### drss.io
- Draws drss.io records as cards: shows, episodes, folders and feed lists.
- Resumes a long-form episode from where drss.io says you stopped, and
marks episodes you have heard. Amethyst reads drss's listening progress
(kind 30078) but never writes it.
- Adds a Listen screen with the episodes you are part way through, then the
unfinished ones from your river, in one player that moves on by itself.
- Adds a listening History by day with a Feeds heard chart.
- Adds -15s/+30s, chapters from the show notes, per-feed speed, and clips
saved as NIP-84 highlights of the episode.
- Reads a drss folder or feed list as a feed, from the Home picker or "Read
as feed" on its card.
- Adds a drss lists organizer that sets the read and write lists, and renames,
moves, merges and deletes lists and folders, with list pictures.
- Lets a show's owner edit its settings and on-air status.
- Keeps drss's reader records, like playback progress, out of feeds.
### Post Layout
- Adds a Post Layout setting with three modes: Indented (the author picture
in a column beside the post, as before), Full Width (the author on top, the
post across the width) and Borderless (Full Width with images, videos,
Markdown media and link cards running out to the screen edges).
- Heads a full-width repost with both authors' rows beside their pictures.
### Home
- Requests every content type Home can show from your follows, so music,
podcasts, fundraisers and attestations no longer appear only after another
screen loaded them.
- Adds forum threads, calendar events, zap goals, code snippets, stream clips,
git repositories, issues and pull requests, publications and torrent
comments to Home, with new toggles in Settings › Home.
- Loads bursty catalog kinds (ebooks, magazines, music, podcasts, git repos)
on their own subscription so one album upload can't crowd notes out.
- Keeps git repository announcements off Home.
### Web of Trust
- Shows a circle card on Home to accounts that follow 10 or more people and
have no trust provider, and turns web of trust on from there.
- Sends your profile, follows, mutes and relay list to the provider before
sign-up, so the first scores start from your current graph.
- Adopts the provider's relay into your trusted, search, indexer and favorite
relays, and moves feeds set to Global onto it.
- Redesigns the card with animated rings, a typical circle size and an
Activate button; the provider stays a visible choice, and after Activate the
card explains that the first scores take about 10 minutes, then closes.
### Polls
- Redesigns the New Post poll composer on the group poll's design: options
drawn as the rows a voter taps, an empty row that takes the next option,
Enter and Tab to move between rows, and duplicates flagged.
- Takes @ mentions, :emoji: and image links in poll options.
- Gathers the settings in one card: Vote with zaps, Multiple answers, the
zap range and Close after.
### Publications and Payments
- Renders PressStr ebooks (kind 33953), magazines (34609) and magazine
issues (39731) as cards, opening PDFs in the in-app reader.
- Translates and crops kind-30041 publication sections like notes, with
Copy Translated.
- Shows a one-line "Lightning Invoice · 50 sats" or "LNURL" label where
previews are off, instead of a wall of bech32.
- Says when an invoice expires.
### Media
- Shows HLG and PQ video in HDR in the fullscreen viewer.
- Compresses video with LightCompressor-enhanced 2.3.0: HDR video stays
10-bit HDR with H.265 where the encoder can keep it, and is tone mapped to
proper SDR everywhere else. iPhone Dolby Vision recordings compress instead
of failing.
- Tells you under the H.265 switch whether a picked HDR video stays HDR or is
converted to SDR, and why.
- Names the picked video's own resolution on the Android quality slider.
- Stops the video encode when you cancel a post.
- Adds the drawing button to every composer: comments, public messages,
articles, listings, group DMs, edits and git issues.
## Improvements and Bug fixes
- Stops uploading to NIP-95, which is deprecated. NIP-95 files still display.
- Fixes uploads that failed with "Stream Closed" when OkHttp retried a
Blossom or NIP-96 upload over a dropped connection.
- Encrypts each file of a multi-file NIP-17 DM under its own key and nonce,
instead of crashing on the second file.
- Retries only the files that failed, reports errors uploaders return
silently, and leaves files removed mid-upload out of the result.
- Stops downloading translation models for blocked languages (Hebrew,
Indonesian and Norwegian slipped through), deletes the models of blocked
languages, and translates Filipino notes.
- Adds a Translation Models setting: Always, Wi-Fi only or Never.
- Fixes memory leaks: view models scoped to their item, eager collectors
added per recomposition, app-wide watchers pinning notes, chess polling
after leaving chess, and caches that only grew.
- Bounds each Concord channel's message buffer and prunes Concord channels
under memory pressure.
- Keeps other people's local relays (localhost, LAN, tailnet) out of the
dialer while keeping your own, and exempts only your own from Tor.
- Stops signer rejections from crashing the app, and handles a refusal in
each flow instead of dropping it.
- Doesn't crash when a gift wrap or seal opens to something that isn't an
event.
- Serializes a NIP-46 signer's reloads of the paired apps' relays.
- Dedupes Blossom servers so the media servers list can't crash.
- Shows zaps to the host of service-signed live streams in the chat.
- Closes the media viewer into the thumbnail of the media on screen.
- Keeps the emoji panel open while searching.
- Seeds the profile-zap notification card from the decrypt cache.
- Centers the hidden-note warning inside reposts.
- Deletes an addressable's current version even after a cleanup.
- Keeps a saved account saved across a transient login of it.
- Clears a screen's view models when navigation hands it new arguments.
- Switches tabs from the drawer's Navigate rows when the drawer stands in for
the bottom bar.
- Paints the theme background under navigation, so going back on a light
window no longer flashes dark.
- Makes Namecoin resolution errors selectable, and replaces the dead ElectrumX
default server.
- Offers member removal in Marmot groups to admins only.
- Fixes a crash when replacing one mention with another while editing a
post on Samsung Keyboard, and stops composers restarting the keyboard
session on every recomposition.
- Renders the descriptions of Shorts, Longs and Stories as rich text, with
mentions, clickable links and translation, and drops a description that
only repeats the title.
- Keeps a cashu token, invoice or NIP-19 link whole when Show More shortens
a long note, so its card renders before the note is expanded.
## Desktop
- Opens napplets and nSites in Chromium through JCEF, downloaded on first
use, each in its own window with the main window's macOS title bar.
- Puts a napplet window's toolbar in the macOS title bar row beside the
traffic lights, drops its Close button for the window's own, and opens
the shield's access sheet as a popover without a title bar.
- Fixes crashes on macOS when closing a napplet window and when clicking
while Chromium starts for the first time.
- Stops a focus loop with Chromium that overflowed the stack each time a
napplet inside a note was clicked.
- Runs napplets inside notes with off-screen Chromium.
- Plays videos the native engine can't decode, like WebM on macOS, in
Chromium, plus WebM and Ogg audio, through the same Tor-aware media relay.
- Plays GIFs of any length by decoding frames as they show.
- Filters OS notifications by the Notifications top-nav filter.
- Keeps each card's video its own when posts share one file.
- Opens links on Windows through the shell's own process.
- Reads relay sockets on virtual threads, so mass dials no longer queue
behind thread start.
- Starts logged in or with a new account through `AMETHYST_LOGIN` and
`AMETHYST_SIGNUP`, and adds local relays through `AMETHYST_LOCAL_RELAYS`,
for test runs.
- Loads feed videos far faster, most of all on slow hosts: a scroll no longer
starts every video it passes, the video you stop on gets the bandwidth while
it starts, and videos scrolled past stop downloading at once.
- Plays hour-long episodes whose index is several MB by fetching the index to
disk before the player opens the file, and tries a video natively once more
before giving it to Chromium.
- Plays AV1 videos in Chromium on Macs without AV1 hardware (M1 and M2),
which played only their sound under a blurred picture.
- Fixes a crash on macOS while playing videos: the app ships its own build of
the video library's macOS player, without the audio tap that crashed.
- Falls back through your other Blossom servers when one refuses an upload,
as Android does, and counts an upload as done when the server already
holds the exact file.
## Cli
- Backdates the seal and the wrap in `amy gift wrap`; `--no-backdate` opts
out.
- Sends Content-Digest when mirroring a release APK to Blossom.
- Adds `amy cordn migrate resume`, and `migrate export` stands the old home
down.
- Reads relay sockets on virtual threads.
- Adds `amy chess challenge|show|move|resign|play`, with draw offers and
claims, and a minimax bot to play the app end to end over Nostr.
## Quartz
- Moves to Quartz 2.13.0, which drops Jackson for Kite everywhere, adds
the drss.io (with kind-30078 listening progress), PressStr and NIP-5D
classes, and validates a chess game's main line.
- Moves cordn's protocol code to cordn-kmp 1.2.1, and Marmot's leave,
permissions, timeline, edit, poll and emoji rules to marmot-kmp 2.2.1.
- Plays carts with kiko-kmp 0.2.3, a new library for the fantasy-console
runtime, through its kiko-player and kiko-compose modules.
- Builds on crypto-kmp 2.1.0, mls-kmp 1.3.0 and quic-kmp 1.2.0.
## Build & Documentation
- Bumps `LightCompressor-enhanced` to 2.3.0.
- Bumps the Android Gradle Plugin to 9.5.0, Ktor to 3.6.1 and Lucene to
10.6.0.
- Builds every module and target with no compiler or Gradle warnings.
- Adds a desktop video timeline log (`-Damethyst.videoTimeline=true`) that
shows where a video's start time goes.
- Runs Android lint in the pre-push hook.
- Moves hardcoded strings from the shared UI, commons and desktop into
Compose resources, with plurals for counted strings.
- Makes a thrashing Kotlin daemon exit instead of grinding.
- Runs the pre-push build without parallel tasks, which ran the Kotlin
daemon out of memory.
- Disables the automatic Crowdin sync while the project is suspended.
## Contributors
- @nprofile…vhl6
- @nprofile…kcfw
- @nprofile…znmg
- @nprofile…pzjr
- Kaio Rabelo
## Translations
- Czech, German, Swedish, and Portuguese by @nprofile…kcfw
- Portuguese by Kaio Rabelo
- Dutch by @nprofile…ge6h
- Hindi by @nprofile…z0lu
- Hungarian by @nprofile…ns2l
- Polish by @nprofile…8c53
- Slovenian by @nprofile…3gag
- Uzbek by fiddleway