feat(avatars): custom image upload — W4 Phase 3
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>
This commit is contained in:
Generated
+32
@@ -4602,11 +4602,13 @@ dependencies = [
|
||||
"bytes",
|
||||
"dirs",
|
||||
"iced",
|
||||
"image",
|
||||
"iroh",
|
||||
"iroh-gossip",
|
||||
"opus",
|
||||
"pipewire",
|
||||
"rand 0.10.1",
|
||||
"rfd",
|
||||
"ringbuf",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -4773,6 +4775,12 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pollster"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
|
||||
|
||||
[[package]]
|
||||
name = "polyval"
|
||||
version = "0.6.2"
|
||||
@@ -5275,6 +5283,30 @@ version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7"
|
||||
|
||||
[[package]]
|
||||
name = "rfd"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20dafead71c16a34e1ff357ddefc8afc11e7d51d6d2b9fbd07eaa48e3e540220"
|
||||
dependencies = [
|
||||
"block2 0.6.2",
|
||||
"dispatch2",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"log",
|
||||
"objc2 0.6.4",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"percent-encoding",
|
||||
"pollster",
|
||||
"raw-window-handle",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.53"
|
||||
|
||||
Reference in New Issue
Block a user