@@ -25,7 +25,7 @@ use enostr::{NoteId, Pubkey};
|
|||||||
use nostrdb::{Ndb, Note, NoteKey, Transaction};
|
use nostrdb::{Ndb, Note, NoteKey, Transaction};
|
||||||
use notedeck::{CachedNote, ImageCache, NoteCache, NotedeckTextStyle};
|
use notedeck::{CachedNote, ImageCache, NoteCache, NotedeckTextStyle};
|
||||||
|
|
||||||
use super::profile::preview::{get_display_name, one_line_display_name_widget};
|
use super::profile::{get_display_name, preview::one_line_display_name_widget};
|
||||||
|
|
||||||
pub struct NoteView<'a> {
|
pub struct NoteView<'a> {
|
||||||
ndb: &'a Ndb,
|
ndb: &'a Ndb,
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
pub mod picture;
|
pub mod picture;
|
||||||
pub mod preview;
|
pub mod preview;
|
||||||
|
|
||||||
use crate::notes_holder::NotesHolder;
|
|
||||||
use crate::ui::note::NoteOptions;
|
use crate::ui::note::NoteOptions;
|
||||||
use egui::{ScrollArea, Widget};
|
use crate::{colors, images};
|
||||||
|
use crate::{notes_holder::NotesHolder, DisplayName};
|
||||||
|
use egui::load::TexturePoll;
|
||||||
|
use egui::{Label, RichText, ScrollArea, Sense, Widget};
|
||||||
use enostr::Pubkey;
|
use enostr::Pubkey;
|
||||||
use nostrdb::{Ndb, Transaction};
|
use nostrdb::{Ndb, ProfileRecord, Transaction};
|
||||||
pub use picture::ProfilePic;
|
pub use picture::ProfilePic;
|
||||||
pub use preview::ProfilePreview;
|
pub use preview::ProfilePreview;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
@@ -13,7 +15,7 @@ use tracing::error;
|
|||||||
use crate::{actionbar::NoteAction, notes_holder::NotesHolderStorage, profile::Profile};
|
use crate::{actionbar::NoteAction, notes_holder::NotesHolderStorage, profile::Profile};
|
||||||
|
|
||||||
use super::timeline::{tabs_ui, TimelineTabView};
|
use super::timeline::{tabs_ui, TimelineTabView};
|
||||||
use notedeck::{ImageCache, MuteFun, NoteCache};
|
use notedeck::{ImageCache, MuteFun, NoteCache, NotedeckTextStyle};
|
||||||
|
|
||||||
pub struct ProfileView<'a> {
|
pub struct ProfileView<'a> {
|
||||||
pubkey: &'a Pubkey,
|
pubkey: &'a Pubkey,
|
||||||
@@ -91,3 +93,108 @@ impl<'a> ProfileView<'a> {
|
|||||||
.inner
|
.inner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn display_name_widget(
|
||||||
|
display_name: DisplayName<'_>,
|
||||||
|
add_placeholder_space: bool,
|
||||||
|
) -> impl egui::Widget + '_ {
|
||||||
|
move |ui: &mut egui::Ui| match display_name {
|
||||||
|
DisplayName::One(n) => {
|
||||||
|
let name_response = ui.add(
|
||||||
|
Label::new(RichText::new(n).text_style(NotedeckTextStyle::Heading3.text_style()))
|
||||||
|
.selectable(false),
|
||||||
|
);
|
||||||
|
if add_placeholder_space {
|
||||||
|
ui.add_space(16.0);
|
||||||
|
}
|
||||||
|
name_response
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayName::Both {
|
||||||
|
display_name,
|
||||||
|
username,
|
||||||
|
} => {
|
||||||
|
ui.add(
|
||||||
|
Label::new(
|
||||||
|
RichText::new(display_name)
|
||||||
|
.text_style(NotedeckTextStyle::Heading3.text_style()),
|
||||||
|
)
|
||||||
|
.selectable(false),
|
||||||
|
);
|
||||||
|
|
||||||
|
ui.add(
|
||||||
|
Label::new(
|
||||||
|
RichText::new(format!("@{}", username))
|
||||||
|
.size(12.0)
|
||||||
|
.color(colors::MID_GRAY),
|
||||||
|
)
|
||||||
|
.selectable(false),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_profile_url<'a>(profile: Option<&ProfileRecord<'a>>) -> &'a str {
|
||||||
|
if let Some(url) = profile.and_then(|pr| pr.record().profile().and_then(|p| p.picture())) {
|
||||||
|
url
|
||||||
|
} else {
|
||||||
|
ProfilePic::no_pfp_url()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_display_name<'a>(profile: Option<&ProfileRecord<'a>>) -> DisplayName<'a> {
|
||||||
|
if let Some(name) = profile.and_then(|p| crate::profile::get_profile_name(p)) {
|
||||||
|
name
|
||||||
|
} else {
|
||||||
|
DisplayName::One("??")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn about_section_widget<'a, 'b>(profile: &'b ProfileRecord<'a>) -> impl egui::Widget + 'b
|
||||||
|
where
|
||||||
|
'b: 'a,
|
||||||
|
{
|
||||||
|
move |ui: &mut egui::Ui| {
|
||||||
|
if let Some(about) = profile.record().profile().and_then(|p| p.about()) {
|
||||||
|
ui.label(about)
|
||||||
|
} else {
|
||||||
|
// need any Response so we dont need an Option
|
||||||
|
ui.allocate_response(egui::Vec2::ZERO, egui::Sense::hover())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) = 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("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
use crate::ui::ProfilePic;
|
use crate::ui::ProfilePic;
|
||||||
use crate::{colors, images, DisplayName};
|
use crate::DisplayName;
|
||||||
use egui::load::TexturePoll;
|
use egui::{Frame, Label, RichText, Widget};
|
||||||
use egui::{Frame, Label, RichText, Sense, Widget};
|
|
||||||
use egui_extras::Size;
|
use egui_extras::Size;
|
||||||
use enostr::{NoteId, Pubkey};
|
use enostr::{NoteId, Pubkey};
|
||||||
use nostrdb::{Ndb, ProfileRecord, Transaction};
|
use nostrdb::{Ndb, ProfileRecord, Transaction};
|
||||||
|
|
||||||
use notedeck::{ImageCache, NotedeckTextStyle, UserAccount};
|
use notedeck::{ImageCache, NotedeckTextStyle, UserAccount};
|
||||||
|
|
||||||
|
use super::{about_section_widget, banner, display_name_widget, get_display_name, get_profile_url};
|
||||||
|
|
||||||
pub struct ProfilePreview<'a, 'cache> {
|
pub struct ProfilePreview<'a, 'cache> {
|
||||||
profile: &'a ProfileRecord<'a>,
|
profile: &'a ProfileRecord<'a>,
|
||||||
cache: &'cache mut ImageCache,
|
cache: &'cache mut ImageCache,
|
||||||
@@ -28,41 +29,6 @@ impl<'a, 'cache> ProfilePreview<'a, 'cache> {
|
|||||||
self.banner_height = 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(self, ui: &mut egui::Ui) {
|
fn body(self, ui: &mut egui::Ui) {
|
||||||
let padding = 12.0;
|
let padding = 12.0;
|
||||||
crate::ui::padding(padding, ui, |ui| {
|
crate::ui::padding(padding, ui, |ui| {
|
||||||
@@ -89,7 +55,7 @@ impl egui::Widget for ProfilePreview<'_, '_> {
|
|||||||
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
|
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
ui.add_sized([ui.available_size().x, 80.0], |ui: &mut egui::Ui| {
|
ui.add_sized([ui.available_size().x, 80.0], |ui: &mut egui::Ui| {
|
||||||
ProfilePreview::banner(ui, self.profile)
|
banner(ui, self.profile)
|
||||||
});
|
});
|
||||||
|
|
||||||
self.body(ui);
|
self.body(ui);
|
||||||
@@ -183,22 +149,6 @@ mod previews {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_display_name<'a>(profile: Option<&ProfileRecord<'a>>) -> DisplayName<'a> {
|
|
||||||
if let Some(name) = profile.and_then(|p| crate::profile::get_profile_name(p)) {
|
|
||||||
name
|
|
||||||
} else {
|
|
||||||
DisplayName::One("??")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_profile_url<'a>(profile: Option<&ProfileRecord<'a>>) -> &'a str {
|
|
||||||
if let Some(url) = profile.and_then(|pr| pr.record().profile().and_then(|p| p.picture())) {
|
|
||||||
url
|
|
||||||
} else {
|
|
||||||
ProfilePic::no_pfp_url()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_profile_url_owned(profile: Option<ProfileRecord<'_>>) -> &str {
|
pub fn get_profile_url_owned(profile: Option<ProfileRecord<'_>>) -> &str {
|
||||||
if let Some(url) = profile.and_then(|pr| pr.record().profile().and_then(|p| p.picture())) {
|
if let Some(url) = profile.and_then(|pr| pr.record().profile().and_then(|p| p.picture())) {
|
||||||
url
|
url
|
||||||
@@ -223,46 +173,6 @@ pub fn get_account_url<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_name_widget(
|
|
||||||
display_name: DisplayName<'_>,
|
|
||||||
add_placeholder_space: bool,
|
|
||||||
) -> impl egui::Widget + '_ {
|
|
||||||
move |ui: &mut egui::Ui| match display_name {
|
|
||||||
DisplayName::One(n) => {
|
|
||||||
let name_response = ui.add(
|
|
||||||
Label::new(RichText::new(n).text_style(NotedeckTextStyle::Heading3.text_style()))
|
|
||||||
.selectable(false),
|
|
||||||
);
|
|
||||||
if add_placeholder_space {
|
|
||||||
ui.add_space(16.0);
|
|
||||||
}
|
|
||||||
name_response
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayName::Both {
|
|
||||||
display_name,
|
|
||||||
username,
|
|
||||||
} => {
|
|
||||||
ui.add(
|
|
||||||
Label::new(
|
|
||||||
RichText::new(display_name)
|
|
||||||
.text_style(NotedeckTextStyle::Heading3.text_style()),
|
|
||||||
)
|
|
||||||
.selectable(false),
|
|
||||||
);
|
|
||||||
|
|
||||||
ui.add(
|
|
||||||
Label::new(
|
|
||||||
RichText::new(format!("@{}", username))
|
|
||||||
.size(12.0)
|
|
||||||
.color(colors::MID_GRAY),
|
|
||||||
)
|
|
||||||
.selectable(false),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn one_line_display_name_widget<'a>(
|
pub fn one_line_display_name_widget<'a>(
|
||||||
visuals: &egui::Visuals,
|
visuals: &egui::Visuals,
|
||||||
display_name: DisplayName<'a>,
|
display_name: DisplayName<'a>,
|
||||||
@@ -285,20 +195,6 @@ pub fn one_line_display_name_widget<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn about_section_widget<'a, 'b>(profile: &'b ProfileRecord<'a>) -> impl egui::Widget + 'b
|
|
||||||
where
|
|
||||||
'b: 'a,
|
|
||||||
{
|
|
||||||
move |ui: &mut egui::Ui| {
|
|
||||||
if let Some(about) = profile.record().profile().and_then(|p| p.about()) {
|
|
||||||
ui.label(about)
|
|
||||||
} else {
|
|
||||||
// need any Response so we dont need an Option
|
|
||||||
ui.allocate_response(egui::Vec2::ZERO, egui::Sense::hover())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_display_name_as_string<'a>(profile: Option<&ProfileRecord<'a>>) -> &'a str {
|
fn get_display_name_as_string<'a>(profile: Option<&ProfileRecord<'a>>) -> &'a str {
|
||||||
let display_name = get_display_name(profile);
|
let display_name = get_display_name(profile);
|
||||||
match display_name {
|
match display_name {
|
||||||
|
|||||||
Reference in New Issue
Block a user