Skip to content

Render profile banners as images on the Profile tab and in contact profiles #94

Description

@asherp

Summary

Nostr profiles (kind 0 metadata) support a banner field — a wide header image URL, alongside picture (avatar). nostr-mail already lets users set a banner value, but it never renders it as an image: the banner should be displayed as a header image both on the user's own Profile tab and when viewing a contact's profile.

Current state

banner is a first-class editable profile field (kind 0): it's in the field lists and URL-validated — e.g. tauri-app/frontend/js/app.js:5092, 5170, 5356-5357 (placeholder https://example.com/banner.jpg), 5488-5493.

But on display it's treated as plain text, rendered as a clickable link, not an imageapp.js:5440-5447:

} else if ((key === 'picture' || key === 'banner' || key === 'website') && value) {
    // For URLs, show as clickable link
    const urlLink = document.createElement('a');
    urlLink.href = value;
    ...
    urlLink.textContent = value;   // ← shows the raw URL, not the image
}

So a user who set a banner just sees the URL string; viewers of their profile see nothing visual. (picture is rendered as an avatar elsewhere; banner has no equivalent.)

Proposed work

  • Render the banner as a header image at the top of the profile view (the common Nostr/Twitter-style layout: wide banner with the avatar overlapping its lower edge), on:
    • the user's own Profile tab, and
    • contact profile detail views (Contacts page).
  • Keep the existing edit field for setting/clearing the banner URL; in edit mode consider a small thumbnail preview of the current banner.
  • Graceful fallbacks: if banner is empty, invalid, or fails to load, fall back to the existing layout (e.g. a neutral/gradient placeholder) with no broken-image icon.
  • Caching & offline: cache the banner image like profile pictures are cached (the app already caches picture for offline/contacts use) so banners work offline and load progressively.
  • Theming/sizing: responsive banner that respects light/dark (and future themes, see Support more color themes (beyond light/dark) #91), with sensible aspect-ratio cropping.

Acceptance criteria

  • A profile with a banner URL shows it as a header image on the user's Profile tab.
  • Contact profile views render the contact's banner as a header image.
  • Empty/invalid/failed banner URLs degrade gracefully (placeholder, no broken-image icon).
  • Banner URL is still editable, with a preview in edit mode.
  • Banner images are cached consistent with how profile pictures are cached.
  • Layout is responsive and works in light/dark mode.

Notes / open questions

  • Banner images can be large — enforce a max display size and lazy-load; reuse the existing profile-image caching path.
  • Security: banners are remote URLs (same as picture/website today) — load with appropriate referrer/loading attributes; confirm whether we proxy/cache remote images to avoid leaking the viewer's IP to arbitrary hosts.
  • Should the avatar overlap the banner (standard social layout) or sit below it?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions