generated using code2prompt + claude 3.7 sonnet Signed-off-by: William Casarin <jb55@jb55.com>
8.3 KiB
NoteDeck UI Component Guide
This guide provides detailed documentation for the major UI components in the NoteDeck UI library.
Table of Contents
Notes
NoteView
The NoteView component is the main container for displaying Nostr notes, handling the layout of profile pictures, author information, content, and interactive elements.
Usage
let mut note_view = NoteView::new(
note_context, // NoteContext with DB, cache, etc.
current_acc, // Current user account (Option<KeypairUnowned>)
¬e, // Reference to Note
options // NoteOptions (display configuration)
);
// Configure display options
note_view
.actionbar(true) // Show/hide action bar
.small_pfp(false) // Use small profile picture
.medium_pfp(true) // Use medium profile picture
.wide(false) // Use wide layout
.frame(true) // Display with a frame
.note_previews(true) // Enable embedded note previews
.selectable_text(true); // Allow text selection
// Render the note view
let note_response = note_view.show(ui);
// Handle user actions
if let Some(action) = note_response.action {
match action {
NoteAction::Note(note_id) => { /* Note was clicked */ },
NoteAction::Profile(pubkey) => { /* Profile was clicked */ },
NoteAction::Reply(note_id) => { /* User clicked reply */ },
NoteAction::Quote(note_id) => { /* User clicked quote */ },
NoteAction::Zap(zap_action) => { /* User initiated zap */ },
NoteAction::Hashtag(tag) => { /* Hashtag was clicked */ },
NoteAction::Context(ctx_selection) => { /* Context menu option selected */ },
}
}
Layouts
NoteView supports two main layouts:
- Standard Layout - Default compact display
- Wide Layout - More spacious layout with profile picture on the left
Use the .wide(true) option to enable the wide layout.
Preview Style
For displaying note previews (e.g., when a note is referenced in another note), use the preview style:
let mut note_view = NoteView::new(note_context, current_acc, ¬e, options)
.preview_style(); // Applies preset options for preview display
NoteContents
NoteContents handles rendering the actual content of a note, including text, mentions, hashtags, URLs, and embedded media.
let mut contents = NoteContents::new(
note_context,
current_acc,
transaction,
note,
note_options
);
ui.add(&mut contents);
// Check for content interactions
if let Some(action) = contents.action() {
// Handle content action (e.g., clicked mention/hashtag)
}
NoteOptions
NoteOptions is a bitflag-based configuration system for controlling how notes are displayed:
// Create with default options
let mut options = NoteOptions::default();
// Or customize from scratch
let mut options = NoteOptions::new(is_universe_timeline);
// Configure options
options.set_actionbar(true); // Show action buttons
options.set_small_pfp(true); // Use small profile picture
options.set_medium_pfp(false); // Don't use medium profile picture
options.set_note_previews(true); // Enable note previews
options.set_wide(false); // Use compact layout
options.set_selectable_text(true); // Allow text selection
options.set_textmode(false); // Don't use text-only mode
options.set_options_button(true); // Show options button
options.set_hide_media(false); // Show media content
options.set_scramble_text(false); // Don't scramble text
options.set_is_preview(false); // This is not a preview
Profiles
ProfilePic
ProfilePic displays a circular profile picture with optional border and configurable size.
// Basic usage
ui.add(ProfilePic::new(img_cache, profile_url));
// Customized
ui.add(
ProfilePic::new(img_cache, profile_url)
.size(48.0)
.border(Stroke::new(2.0, Color32::WHITE))
);
// From profile record
if let Some(profile_pic) = ProfilePic::from_profile(img_cache, profile) {
ui.add(profile_pic);
}
Standard sizes:
ProfilePic::default_size()- 38pxProfilePic::medium_size()- 32pxProfilePic::small_size()- 24px
ProfilePreview
ProfilePreview shows a detailed profile card with banner, profile picture, display name, username, and about text.
// Full preview
ui.add(ProfilePreview::new(profile, img_cache));
// Simple preview
ui.add(SimpleProfilePreview::new(
Some(profile), // Option<&ProfileRecord>
img_cache,
is_nsec // Whether this is a full keypair
));
Mentions
The Mention component renders a clickable @username reference with hover preview.
let mention_response = Mention::new(ndb, img_cache, txn, pubkey)
.size(16.0) // Text size
.selectable(false) // Disable text selection
.show(ui);
// Handle mention click
if let Some(action) = mention_response.inner {
// Usually NoteAction::Profile
}
Media Handling
Images
Images are managed through the render_images function, which handles loading, caching, and displaying images:
render_images(
ui,
img_cache,
url,
ImageType::Content, // Or ImageType::Profile(size)
MediaCacheType::Image,
|ui| {
// Show while loading
ui.spinner();
},
|ui, error| {
// Show on error
ui.label(format!("Error: {}", error));
},
|ui, url, img, gifs| {
// Show successful image
let texture = handle_repaint(ui, retrieve_latest_texture(url, gifs, img));
ui.image(texture);
}
);
For profile images, use ImageType::Profile(size) to automatically crop, resize, and round the image.
GIF Animation
GIFs are supported through the animation system. The process for displaying GIFs is:
- Load and decode GIF in background thread
- Send frames to UI thread through channels
- Render frames with timing control
// Display a GIF
render_images(
ui,
img_cache,
gif_url,
ImageType::Content,
MediaCacheType::Gif,
/* callbacks as above */
);
// Get the current frame texture
let texture = handle_repaint(
ui,
retrieve_latest_texture(url, gifs, renderable_media)
);
Widgets & Utilities
Username
Displays a user's name with options for abbreviation and color:
ui.add(
Username::new(profile, pubkey)
.pk_colored(true) // Color based on pubkey
.abbreviated(16) // Max length before abbreviation
);
Animations
Use animation helpers for interactive elements:
// Basic hover animation
let (rect, size, response) = hover_expand(
ui,
id, // Unique ID for the animation
base_size, // Base size
expand_size, // Amount to expand by
anim_speed // Animation speed
);
// Small hover expand (common pattern)
let (rect, size, response) = hover_expand_small(ui, id);
// Advanced helper
let helper = AnimationHelper::new(ui, "animation_name", max_size);
let current_size = helper.scale_1d_pos(min_size);
Pulsing Effects
For elements that need attention:
// Create pulsing image
let pulsing_image = ImagePulseTint::new(
&ctx, // EGUI Context
id, // Animation ID
image, // Base image
&[255, 183, 87], // Tint color
alpha_min, // Minimum alpha
alpha_max // Maximum alpha
)
.with_speed(0.35) // Animation speed
.animate(); // Apply animation
ui.add(pulsing_image);
Context Menus
Create menus for additional actions:
// Add context menu to any response
response.context_menu(|ui| {
if ui.button("Copy Link").clicked() {
ui.ctx().copy_text(url.to_owned());
ui.close_menu();
}
});
The NoteContextButton component provides a standard context menu for notes:
let resp = ui.add(NoteContextButton::new(note_key));
if let Some(action) = NoteContextButton::menu(ui, resp) {
// Handle context action
}