feat(contacts): contact avatars — custom image / Material icon / Z-T badge
Add an `avatar` field to AddressBookEntry ("" = default Z/T type badge,
"icon:<name>" = a Material wallet-icon, "img:<path>" = a custom image),
serialized additively in addressbook.json (only written when non-empty, so
existing books are untouched).
Render it in the Cards/List views via a new drawContactAvatar helper: custom
images are loaded once through a path-keyed texture cache and drawn
circular-cropped (centre-cropped UVs + a thin border ring); icons reuse the
project-icon set (incl. the special pickaxe font path) in a tinted circle;
everything else falls back to the existing Z/T badge (also the fallback when
an image fails to load or an icon name is unknown).
Seed one sweep contact with an icon avatar to exercise the icon-badge path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -54,6 +54,7 @@ bool AddressBook::load()
|
||||
// Legacy entries (no "scope") migrate to "global" so nothing disappears when
|
||||
// multi-wallet scoping lands — a contact you already had stays visible everywhere.
|
||||
e.scope = entry.value("scope", "global");
|
||||
e.avatar = entry.value("avatar", "");
|
||||
|
||||
if (!e.address.empty()) {
|
||||
entries_.push_back(e);
|
||||
@@ -86,6 +87,7 @@ bool AddressBook::save()
|
||||
e["address"] = entry.address;
|
||||
e["notes"] = entry.notes;
|
||||
e["scope"] = entry.scope.empty() ? std::string("global") : entry.scope;
|
||||
if (!entry.avatar.empty()) e["avatar"] = entry.avatar;
|
||||
j["entries"].push_back(e);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ struct AddressBookEntry {
|
||||
// (shown only when that wallet is the active one). Empty is treated as "global" so legacy
|
||||
// entries — written before multi-wallet scoping — keep showing everywhere.
|
||||
std::string scope = "global";
|
||||
// Contact avatar: "" = default type badge (Z/T), "icon:<name>" = a Material wallet-icon,
|
||||
// "img:<path>" = a custom image (copied into <config>/contact-avatars/).
|
||||
std::string avatar;
|
||||
|
||||
AddressBookEntry() = default;
|
||||
AddressBookEntry(const std::string& l, const std::string& a, const std::string& n = "",
|
||||
|
||||
Reference in New Issue
Block a user