refactor DisplayName -> NostrName

Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
kernelkind
2025-01-01 21:03:11 -05:00
parent df82e08041
commit a7cfe9bd37
7 changed files with 88 additions and 83 deletions

View File

@@ -42,6 +42,6 @@ pub mod storage;
pub use app::Damus; pub use app::Damus;
pub use error::Error; pub use error::Error;
pub use profile::DisplayName; pub use profile::NostrName;
pub type Result<T> = std::result::Result<T, error::Error>; pub type Result<T> = std::result::Result<T, error::Error>;

View File

@@ -9,20 +9,28 @@ use crate::{
timeline::{copy_notes_into_timeline, PubkeySource, Timeline, TimelineKind, TimelineTab}, timeline::{copy_notes_into_timeline, PubkeySource, Timeline, TimelineKind, TimelineTab},
}; };
pub enum DisplayName<'a> { pub struct NostrName<'a> {
One(&'a str), pub username: Option<&'a str>,
pub display_name: Option<&'a str>,
Both { pub nip05: Option<&'a str>,
username: &'a str,
display_name: &'a str,
},
} }
impl<'a> DisplayName<'a> { impl<'a> NostrName<'a> {
pub fn username(&self) -> &'a str { pub fn name(&self) -> &'a str {
match self { if let Some(name) = self.username {
Self::One(n) => n, name
Self::Both { username, .. } => username, } else if let Some(name) = self.display_name {
name
} else {
self.nip05.unwrap_or("??")
}
}
pub fn unknown() -> Self {
Self {
username: None,
display_name: None,
nip05: None,
} }
} }
} }
@@ -31,19 +39,35 @@ fn is_empty(s: &str) -> bool {
s.chars().all(|c| c.is_whitespace()) s.chars().all(|c| c.is_whitespace())
} }
pub fn get_profile_name<'a>(record: &ProfileRecord<'a>) -> Option<DisplayName<'a>> { pub fn get_display_name<'a>(record: Option<&ProfileRecord<'a>>) -> NostrName<'a> {
let profile = record.record().profile()?; if let Some(record) = record {
let display_name = profile.display_name().filter(|n| !is_empty(n)); if let Some(profile) = record.record().profile() {
let name = profile.name().filter(|n| !is_empty(n)); let display_name = profile.display_name().filter(|n| !is_empty(n));
let username = profile.name().filter(|n| !is_empty(n));
let nip05 = if let Some(raw_nip05) = profile.nip05() {
if let Some(at_pos) = raw_nip05.find('@') {
if raw_nip05.starts_with('_') {
raw_nip05.get(at_pos + 1..)
} else {
Some(raw_nip05)
}
} else {
None
}
} else {
None
};
match (display_name, name) { NostrName {
(None, None) => None, username,
(Some(disp), None) => Some(DisplayName::One(disp)), display_name,
(None, Some(username)) => Some(DisplayName::One(username)), nip05,
(Some(display_name), Some(username)) => Some(DisplayName::Both { }
display_name, } else {
username, NostrName::unknown()
}), }
} else {
NostrName::unknown()
} }
} }

View File

@@ -241,10 +241,9 @@ impl<'a> TitleNeedsDb<'a> {
let pubkey = pubkey_source.to_pubkey(deck_author); let pubkey = pubkey_source.to_pubkey(deck_author);
let profile = ndb.get_profile_by_pubkey(txn, pubkey); let profile = ndb.get_profile_by_pubkey(txn, pubkey);
let m_name = profile let m_name = profile
.ok()
.as_ref() .as_ref()
.and_then(|p| crate::profile::get_profile_name(p)) .ok()
.map(|display_name| display_name.username()); .map(|p| crate::profile::get_display_name(Some(p)).name());
m_name.unwrap_or("Profile") m_name.unwrap_or("Profile")
} else { } else {

View File

@@ -1,5 +1,5 @@
use crate::actionbar::NoteAction;
use crate::ui; use crate::ui;
use crate::{actionbar::NoteAction, profile::get_display_name};
use egui::Sense; use egui::Sense;
use enostr::Pubkey; use enostr::Pubkey;
use nostrdb::{Ndb, Transaction}; use nostrdb::{Ndb, Transaction};
@@ -79,12 +79,7 @@ fn mention_ui(
ui.horizontal(|ui| { ui.horizontal(|ui| {
let profile = ndb.get_profile_by_pubkey(txn, pk).ok(); let profile = ndb.get_profile_by_pubkey(txn, pk).ok();
let name: String = let name: String = format!("@{}", get_display_name(profile.as_ref()).name());
if let Some(name) = profile.as_ref().and_then(crate::profile::get_profile_name) {
format!("@{}", name.username())
} else {
"@???".to_string()
};
let resp = ui.add( let resp = ui.add(
egui::Label::new(egui::RichText::new(name).color(link_color).size(size)) egui::Label::new(egui::RichText::new(name).color(link_color).size(size))

View File

@@ -16,6 +16,7 @@ pub use reply_description::reply_desc;
use crate::{ use crate::{
actionbar::NoteAction, actionbar::NoteAction,
profile::get_display_name,
ui::{self, View}, ui::{self, View},
}; };
@@ -25,7 +26,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::{get_display_name, preview::one_line_display_name_widget}; use super::profile::preview::one_line_display_name_widget;
pub struct NoteView<'a> { pub struct NoteView<'a> {
ndb: &'a Ndb, ndb: &'a Ndb,

View File

@@ -1,9 +1,10 @@
pub mod picture; pub mod picture;
pub mod preview; pub mod preview;
use crate::profile::get_display_name;
use crate::ui::note::NoteOptions; use crate::ui::note::NoteOptions;
use crate::{colors, images}; use crate::{colors, images};
use crate::{notes_holder::NotesHolder, DisplayName}; use crate::{notes_holder::NotesHolder, NostrName};
use egui::load::TexturePoll; use egui::load::TexturePoll;
use egui::{Label, RichText, ScrollArea, Sense}; use egui::{Label, RichText, ScrollArea, Sense};
use enostr::Pubkey; use enostr::Pubkey;
@@ -131,43 +132,42 @@ impl<'a> ProfileView<'a> {
} }
} }
fn display_name_widget( fn display_name_widget(name: NostrName<'_>, add_placeholder_space: bool) -> impl egui::Widget + '_ {
display_name: DisplayName<'_>, move |ui: &mut egui::Ui| -> egui::Response {
add_placeholder_space: bool, let disp_resp = name.display_name.map(|disp_name| {
) -> 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( ui.add(
Label::new( Label::new(
RichText::new(display_name) RichText::new(disp_name).text_style(NotedeckTextStyle::Heading3.text_style()),
.text_style(NotedeckTextStyle::Heading3.text_style()),
) )
.selectable(false), .selectable(false),
); )
});
let username_resp = name.username.map(|username| {
ui.add( ui.add(
Label::new( Label::new(
RichText::new(format!("@{}", username)) RichText::new(format!("@{}", username))
.size(12.0) .size(16.0)
.color(colors::MID_GRAY), .color(colors::MID_GRAY),
) )
.selectable(false), .selectable(false),
) )
});
let resp = if let Some(disp_resp) = disp_resp {
if let Some(username_resp) = username_resp {
username_resp
} else {
disp_resp
}
} else {
ui.add(Label::new(RichText::new(name.name())))
};
if add_placeholder_space {
ui.add_space(16.0);
} }
resp
} }
} }
@@ -179,14 +179,6 @@ pub fn get_profile_url<'a>(profile: Option<&ProfileRecord<'a>>) -> &'a str {
} }
} }
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 fn about_section_widget<'a, 'b>(profile: &'b ProfileRecord<'a>) -> impl egui::Widget + 'b
where where
'b: 'a, 'b: 'a,

View File

@@ -1,9 +1,8 @@
use crate::ui::ProfilePic; use crate::ui::ProfilePic;
use crate::DisplayName; use crate::NostrName;
use egui::{Frame, Label, RichText, Widget}; use egui::{Frame, Label, RichText, Widget};
use egui_extras::Size; use egui_extras::Size;
use enostr::{NoteId, Pubkey}; use nostrdb::ProfileRecord;
use nostrdb::{Ndb, ProfileRecord, Transaction};
use notedeck::{ImageCache, NotedeckTextStyle, UserAccount}; use notedeck::{ImageCache, NotedeckTextStyle, UserAccount};
@@ -175,22 +174,17 @@ pub fn get_account_url<'a>(
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: NostrName<'a>,
style: NotedeckTextStyle, style: NotedeckTextStyle,
) -> impl egui::Widget + 'a { ) -> impl egui::Widget + 'a {
let text_style = style.text_style(); let text_style = style.text_style();
let color = visuals.noninteractive().fg_stroke.color; let color = visuals.noninteractive().fg_stroke.color;
move |ui: &mut egui::Ui| match display_name { move |ui: &mut egui::Ui| -> egui::Response {
DisplayName::One(n) => ui.label(RichText::new(n).text_style(text_style).color(color)), ui.label(
RichText::new(display_name.name())
DisplayName::Both {
display_name,
username: _,
} => ui.label(
RichText::new(display_name)
.text_style(text_style) .text_style(text_style)
.color(color), .color(color),
), )
} }
} }