mirror of
https://github.com/aljazceru/notedeck.git
synced 2026-01-06 18:04:20 +01:00
ui: add banners to profile previews
profile previews still need lots of work, but this was a challenge to get an aspectRatio: fill mechanism for images which the banner takes advantage of. Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
@@ -139,6 +139,7 @@ fn render_note_contents(
|
||||
if let Some(rec) = profile.as_ref() {
|
||||
resp.on_hover_ui_at_pointer(|ui| {
|
||||
egui::Frame::default().show(ui, |ui| {
|
||||
ui.set_max_width(300.0);
|
||||
ui.add(ui::ProfilePreview::new(rec));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,25 +1,82 @@
|
||||
use crate::app_style::NotedeckTextStyle;
|
||||
use crate::images;
|
||||
use egui::load::TexturePoll;
|
||||
use egui::{RichText, Sense};
|
||||
use egui_extras::Size;
|
||||
use nostrdb::ProfileRecord;
|
||||
|
||||
pub struct ProfilePreview<'a> {
|
||||
profile: &'a ProfileRecord<'a>,
|
||||
banner_height: Size,
|
||||
}
|
||||
|
||||
impl<'a> ProfilePreview<'a> {
|
||||
pub fn new(profile: &'a ProfileRecord<'a>) -> Self {
|
||||
ProfilePreview { profile }
|
||||
let banner_height = Size::exact(80.0);
|
||||
ProfilePreview {
|
||||
profile,
|
||||
banner_height,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn banner_height(&mut self, size: Size) {
|
||||
self.banner_height = size;
|
||||
}
|
||||
|
||||
fn banner_texture(
|
||||
ui: &mut egui::Ui,
|
||||
profile: &ProfileRecord<'_>,
|
||||
) -> Option<egui::load::SizedTexture> {
|
||||
// TODO: cache banner
|
||||
let banner = profile.record().profile().and_then(|p| p.banner());
|
||||
|
||||
if let Some(banner) = banner {
|
||||
let texture_load_res =
|
||||
egui::Image::new(banner).load_for_size(ui.ctx(), ui.available_size());
|
||||
if let Ok(texture_poll) = texture_load_res {
|
||||
match texture_poll {
|
||||
TexturePoll::Pending { .. } => {}
|
||||
TexturePoll::Ready { texture, .. } => return Some(texture),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn banner(ui: &mut egui::Ui, profile: &ProfileRecord<'_>) -> egui::Response {
|
||||
if let Some(texture) = Self::banner_texture(ui, profile) {
|
||||
images::aspect_fill(
|
||||
ui,
|
||||
Sense::hover(),
|
||||
texture.id,
|
||||
texture.size.x / texture.size.y,
|
||||
)
|
||||
} else {
|
||||
// TODO: default banner texture
|
||||
ui.label("")
|
||||
}
|
||||
}
|
||||
|
||||
fn body(ui: &mut egui::Ui, profile: &ProfileRecord<'_>) -> egui::Response {
|
||||
let name = if let Some(name) = crate::profile::get_profile_name(profile) {
|
||||
name
|
||||
} else {
|
||||
"nostrich"
|
||||
};
|
||||
|
||||
ui.label(RichText::new(name).text_style(NotedeckTextStyle::Heading3.text_style()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> egui::Widget for ProfilePreview<'a> {
|
||||
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Profile");
|
||||
let name = if let Some(name) = crate::profile::get_profile_name(self.profile) {
|
||||
name
|
||||
} else {
|
||||
"nostrich"
|
||||
};
|
||||
ui.label(name);
|
||||
ui.vertical(|ui| {
|
||||
ui.add_sized([ui.available_size().x, 80.0], |ui: &mut egui::Ui| {
|
||||
ProfilePreview::banner(ui, self.profile)
|
||||
});
|
||||
|
||||
ProfilePreview::body(ui, self.profile);
|
||||
})
|
||||
.response
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user