1
0
forked from GRIN/grim
Files
goblin/src/gui/platform/mod.rs
T
Claude b1b9bd61af Build 13: hosted profile pictures, username release, claim/release UX
Identity overhaul (server changes deployed to goblin.st separately):

Avatars
- profile pictures hosted on goblin.st, tied to the username: tap the
  settings avatar → native image picker → 256px PNG uploaded over Tor
- letter avatars now use (background, ink) color pairs (8) keyed off the
  npub, and render the first ALPHANUMERIC char — never the '@'
- custom pictures shown everywhere self/contacts appear: settings card,
  home header, sidebar chip, peers strip, activity rows, send recipient
- AvatarTextures: disk cache (~/.goblin/cache/avatars) + background Tor
  fetch + egui textures loaded on the UI thread; a network/Tor failure
  is never cached as "no avatar" (would have stuck for 6h)
- nostr/avatar.rs mirrors the server's sniff→limits→orientation→crop→
  256→re-encode-PNG pipeline so uploads are small and previews instant

Username lifecycle
- rotating the key now RELEASES the username (and deletes its avatar
  server-side) instead of transferring; rotation aborts if release fails
- claim panel is one Claim button (checks then registers); registered
  state shows "Registered <name>" + a Release action behind an
  are-you-sure gate ("up for grabs the moment it's free")
- released names are immediately re-claimable (quarantine removed)

Other
- Tor::http_request_bytes: binary bodies + status code, for upload and
  avatar download (string http_request kept as a wrapper)
- settings reordered Identity-first, then Wallet
- sidebar node card is 3 lines: status / block height / host
- profile card shows the full npub when it fits, else head…tail

34 lib tests green. Live-verified on goblin.st: upload→serve (image/png,
nosniff, immutable)→5/day limit (6th 429)→release purges avatar; a real
picture for @fartmuncher22 fetched over Tor and rendered across surfaces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 12:22:41 -04:00

47 lines
1.6 KiB
Rust

// Copyright 2023 The Grim Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
pub use self::platform::*;
#[cfg(target_os = "android")]
#[path = "android/mod.rs"]
pub mod platform;
#[cfg(not(target_os = "android"))]
#[path = "desktop/mod.rs"]
pub mod platform;
pub trait PlatformCallbacks {
fn set_context(&mut self, ctx: &egui::Context);
fn exit(&self);
fn copy_string_to_buffer(&self, data: String);
fn get_string_from_buffer(&self) -> String;
fn start_camera(&self);
fn stop_camera(&self);
fn camera_image(&self) -> Option<(Vec<u8>, u32)>;
fn can_switch_camera(&self) -> bool;
fn switch_camera(&self);
fn share_data(&self, name: String, data: Vec<u8>) -> Result<(), std::io::Error>;
fn pick_file(&self) -> Option<String>;
/// Native picker filtered to picture files; defaults to the plain picker
/// on platforms without filter support (magic-byte sniffing protects).
fn pick_image_file(&self) -> Option<String> {
self.pick_file()
}
fn pick_folder(&self) -> Option<String>;
fn picked_file(&self) -> Option<String>;
fn request_user_attention(&self);
fn user_attention_required(&self) -> bool;
fn clear_user_attention(&self);
}