f029a30ea7c8f5ac4a87509d209d09e3bf4d6f4c
Completes W4: users can upload a custom avatar image. - `Avatar::Custom(String)` carries a base64 PNG. `process_upload` decodes an arbitrary png/jpeg, downscales so the longest side is 128px (aspect kept), re-encodes PNG, base64s, and rejects anything over a hard cap. - Settings "Avatar" gains an "Upload image…" button (native picker via rfd's xdg-portal backend, off-thread through Task::perform) and shows the current custom avatar as a selected tile. - Untrusted peer avatars are validated at gossip ingest (`sanitize_incoming`): a custom image must be within the byte cap and decode as a PNG within bounds (image-crate decode limits guard against decompression bombs) or it's downgraded to a monogram. - Raised the gossip max message size to 64 KB so a capped custom avatar fits inline on the presence plane (all peers already need a matching build). - Deps: image (png/jpeg only), rfd (xdg-portal, no GTK); only `rfd`+`pollster` are actually new in the lockfile (rest were already transitive). cargo audit clean (0 vulns; the 2 unmaintained warnings are pre-existing S7). - `Controller::send` now returns bool (was a Result carrying the now-larger CoreCommand by value, which tripped result_large_err). - +5 avatar unit tests (upload resize/round-trip, reject non-image, ingest accept/reject). 227 lib tests green, clippy clean. Manual check: Settings → Avatar → Upload; confirm the picker opens and the image shows for you and (after redeploy) for a peer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Releases
10
Languages
Rust
98.8%
Shell
0.4%
Nix
0.4%
Python
0.2%
Inno Setup
0.2%