From 893fd582dcba072cf6b305700a7bad94db82d145 Mon Sep 17 00:00:00 2001 From: William Casarin Date: Sun, 21 Apr 2024 15:55:47 -0700 Subject: [PATCH] profiles: introduce DisplayNames This is exactly the same as the DisplayName enum in Damus iOS. Due to the various inconsistencies in `name` and `display_name` between clients, we have to generalize DisplayName into two variants: one name or two names. If we have two names, we treat it in the standard way of display_name is the real name, and `name` is the username. If only one is set, then it is considered both the username and "real name". Signed-off-by: William Casarin --- src/lib.rs | 1 + src/profile.rs | 48 ++++++++++++++++++++++++++++----------- src/ui/note/contents.rs | 10 ++++---- src/ui/profile/preview.rs | 22 +++++++++++++++--- 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b1e2058..325b0a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,7 @@ mod test_utils; pub use app::Damus; pub use error::Error; +pub use profile::DisplayName; #[cfg(target_os = "android")] use winit::platform::android::EventLoopBuilderExtAndroid; diff --git a/src/profile.rs b/src/profile.rs index 803d7e7..9da7026 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -1,17 +1,39 @@ use nostrdb::ProfileRecord; -pub fn get_profile_name<'a>(record: &'a ProfileRecord) -> Option<&'a str> { - let profile = record.record().profile()?; - let display_name = profile.display_name(); - let name = profile.name(); +pub enum DisplayName<'a> { + One(&'a str), - if display_name.is_some() && display_name.unwrap() != "" { - return display_name; - } - - if name.is_some() && name.unwrap() != "" { - return name; - } - - None + Both { + username: &'a str, + display_name: &'a str, + }, +} + +impl<'a> DisplayName<'a> { + pub fn username(&self) -> &'a str { + match self { + Self::One(n) => n, + Self::Both { username, .. } => username, + } + } +} + +fn is_empty(s: &str) -> bool { + s.chars().all(|c| c.is_whitespace()) +} + +pub fn get_profile_name<'a>(record: &'a ProfileRecord) -> Option> { + let profile = record.record().profile()?; + let display_name = profile.display_name().filter(|n| !is_empty(n)); + let name = profile.name().filter(|n| !is_empty(n)); + + match (display_name, name) { + (None, None) => None, + (Some(disp), None) => Some(DisplayName::One(disp)), + (None, Some(username)) => Some(DisplayName::One(username)), + (Some(display_name), Some(username)) => Some(DisplayName::Both { + display_name, + username, + }), + } } diff --git a/src/ui/note/contents.rs b/src/ui/note/contents.rs index 59ef58c..994da97 100644 --- a/src/ui/note/contents.rs +++ b/src/ui/note/contents.rs @@ -129,19 +129,17 @@ fn render_note_contents( let name: String = if let Some(name) = profile.as_ref().and_then(crate::profile::get_profile_name) { - format!("@{}", name) + format!("@{}", name.username()) } else { - "@nostrich".to_string() + "??".to_string() }; let resp = ui.colored_label(colors::PURPLE, &name); 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)); - }); + ui.set_max_width(300.0); + ui.add(ui::ProfilePreview::new(rec)); }); } }); diff --git a/src/ui/profile/preview.rs b/src/ui/profile/preview.rs index 060e52e..d9a81ae 100644 --- a/src/ui/profile/preview.rs +++ b/src/ui/profile/preview.rs @@ -1,5 +1,6 @@ use crate::app_style::NotedeckTextStyle; use crate::images; +use crate::DisplayName; use egui::load::TexturePoll; use egui::{RichText, Sense}; use egui_extras::Size; @@ -58,14 +59,29 @@ impl<'a> ProfilePreview<'a> { } } - fn body(ui: &mut egui::Ui, profile: &ProfileRecord<'_>) -> egui::Response { + fn body(ui: &mut egui::Ui, profile: &ProfileRecord<'_>) { let name = if let Some(name) = crate::profile::get_profile_name(profile) { name } else { - "nostrich" + DisplayName::One("??") }; - ui.label(RichText::new(name).text_style(NotedeckTextStyle::Heading3.text_style())) + match name { + DisplayName::One(n) => { + ui.label(RichText::new(n).text_style(NotedeckTextStyle::Heading3.text_style())); + } + + DisplayName::Both { + display_name, + username, + } => { + ui.label( + RichText::new(display_name) + .text_style(NotedeckTextStyle::Heading3.text_style()), + ); + ui.label(RichText::new(format!("@{}", username))); + } + } } }