Complete Estonian translation (every key in en), wired into the locale list, the message loaders, the language switcher (with an Estonian flag drawn in the Twemoji style, since Twemoji's set is not used for it) and the locale-count test.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Uploads in Files had their own card with a thick progress bar, larger
corners and a heavier shadow, so they looked unlike the toasts around
them.
Toasts can now show work in progress: the thin line at the bottom fills
with progress instead of counting down, and the toast stays until it is
updated or removed. Uploads use it, with the file and percentage below
the title and Cancel as the toast action.
A newsletter's List-Unsubscribe `mailto:` was sent from the user's own
account as written: every `to=` field became a recipient, and subject
and body were the sender's choice. The confirmation said only
"Unsubscribe from this sender?", so one click could mail
"I resign" to someone's boss and HR.
The unsubscribe now goes to the single address in the URL (a list of
addresses is refused and `to=` is ignored), the subject is kept on one
line and both subject and body are capped. Both confirmations show the
recipient, subject and body before anything is sent.
On 1.0 a vCard export sent every blob photo through the avatar download
queue, a burst of 40 and then 6 a second, two at a time: about 160 s for
1000 photos. Avatars and print (which gives up after 5 s) waited behind
it, the Export button showed nothing, and a second click started the
whole export again.
- Export fetches the blob media of all cards with Blob/get
(`data:asBase64`), asking for the sizes first and packing the requests
to about 4 MiB. `urn:ietf:params:jmap:blob` goes into `using` only
when the session advertises it; without it, or when a request is
refused, the rest is downloaded one by one behind avatars and print,
which keep half of the download burst for themselves.
- The export buttons in the settings, the bulk bar, the context menu and
the detail menu show that an export is running and ignore clicks until
it is done.
- When the photo changes, the form rebuilds `media` on the card as the
server has it now. A logo or sound blobId from the list's older copy
made 1.0 refuse the whole update ("The following blobIds do not exist
or are not accessible").
- A new photo takes the key, place, `pref`, `label` and `contexts` of the
one it replaces, so it stays the photo shown on cards with several.
Removing the photo removes every photo the card had instead of only the
shown one, which brought up the next; logos and sounds stay.
- A card whose login has no client downloads nothing, instead of asking
the active login's server and remembering the refusal for two minutes.
- Photo downloads run at half the server's `maxConcurrentRequests`
instead of a fixed two.
- `invalidProperties` naming `media/...` also counts as a refused blobId
in media, not only `media` itself.
Stalwart 1.0 returns every photo, logo and sound in a contact card as a
blobId without a uri, including every photo Bulwark saved as a data:
URI. Bulwark read only `uri`, so avatars, the contact list and detail,
print, vCard export and the "has photo" filter showed nothing, and the
form sent `media` without the photo on every save, so editing a phone
number deleted the photo on the server.
- `ContactMedia` carries `blobId`, `label`, `pref` and `contexts`; `uri`
is optional, and `getContactPhotoRef`/`hasContactPhoto` read both.
- Blob photos are downloaded once each, at most two at a time and at a
paced rate, only while on screen, into an LRU of object URLs revoked
on eviction, account switch and logout. They share Stalwart's
per-account budget of 4 concurrent requests and 1000 a minute.
- Avatars look senders up in an index built once per contact list.
- The form leaves `media` out unless the photo changed, and otherwise
passes the other entries through as the server returned them.
- A new photo is uploaded into the user's own account and sent as a
blobId where the blob capability lists ContactCard (1.0). 0.16 refuses
blobIds in media and keeps getting a data: URI; a refusal at runtime
falls back the same way for the rest of the session.
- Print and vCard export download blob media first; duplicate and
cross-account move send the bytes instead of the source's blobIds.
- vCard export also writes photos whose data: URI names no media type
(`data:;base64,`, `data:base64,`), which it dropped before.