commit 9d1e8ce666e0215f338a18b0f44b33f67dcf9924
parent 7ecacc69a55d8a4c2071bfb3c38bad401ccbc56a
Author: William Casarin <jb55@jb55.com>
Date: Thu, 11 Apr 2024 11:09:30 -0700
irc mode
Signed-off-by: William Casarin <jb55@jb55.com>
Diffstat:
3 files changed, 171 insertions(+), 50 deletions(-)
diff --git a/src/app.rs b/src/app.rs
@@ -10,6 +10,7 @@ use crate::notecache::NoteCache;
use crate::timeline;
use crate::ui::padding;
use crate::widgets::note::NoteContents;
+use crate::widgets::username::Username;
use crate::Result;
use egui::containers::scroll_area::ScrollBarVisibility;
@@ -84,6 +85,7 @@ pub struct Damus {
//compose: String,
note_cache: HashMap<NoteKey, NoteCache>,
pool: RelayPool,
+ irc_mode: bool,
timelines: Vec<Timeline>,
@@ -450,6 +452,7 @@ impl Damus {
img_cache: ImageCache::new(imgcache_dir),
note_cache: HashMap::new(),
timelines,
+ irc_mode: false,
ndb: Ndb::new(data_path.as_ref().to_str().expect("db path ok"), &config).expect("ndb"),
//compose: "".to_string(),
frame_history: FrameHistory::default(),
@@ -525,44 +528,6 @@ fn pfp_image<'a>(ui: &mut egui::Ui, img: &TextureHandle, size: f32) -> egui::Res
//.with_options()
}
-fn ui_abbreviate_name(ui: &mut egui::Ui, name: &str, len: usize) {
- if name.len() > len {
- let closest = abbrev::floor_char_boundary(name, len);
- ui.strong(&name[..closest]);
- ui.strong("...");
- } else {
- ui.add(Label::new(
- RichText::new(name).family(NamedFontFamily::Medium.as_family()),
- ));
- }
-}
-
-fn render_username(ui: &mut egui::Ui, profile: Option<&ProfileRecord>, _pk: &[u8; 32]) {
- #[cfg(feature = "profiling")]
- puffin::profile_function!();
-
- ui.horizontal(|ui| {
- //ui.spacing_mut().item_spacing.x = 0.0;
- if let Some(profile) = profile {
- if let Some(prof) = profile.record.profile() {
- if prof.display_name().is_some() && prof.display_name().unwrap() != "" {
- ui_abbreviate_name(ui, prof.display_name().unwrap(), 20);
- } else if let Some(name) = prof.name() {
- ui_abbreviate_name(ui, name, 20);
- }
- }
- } else {
- ui.strong("nostrich");
- }
-
- /*
- ui.label(&pk.as_ref()[0..8]);
- ui.label(":");
- ui.label(&pk.as_ref()[64 - 8..]);
- */
- });
-}
-
fn no_pfp_url() -> &'static str {
"https://damus.io/img/no-profile.svg"
}
@@ -609,17 +574,28 @@ fn render_notes_in_viewport(
}
*/
-fn render_reltime(ui: &mut egui::Ui, note_cache: &mut NoteCache) {
+fn render_reltime(
+ ui: &mut egui::Ui,
+ note_cache: &mut NoteCache,
+ before: bool,
+) -> egui::InnerResponse<()> {
#[cfg(feature = "profiling")]
puffin::profile_function!();
- let color = Color32::from_rgb(0x8A, 0x8A, 0x8A);
- ui.add(Label::new(RichText::new("⋅").size(10.0).color(color)));
- ui.add(Label::new(
- RichText::new(note_cache.reltime_str())
- .size(10.0)
- .color(color),
- ));
+ ui.horizontal(|ui| {
+ let color = Color32::from_rgb(0x8A, 0x8A, 0x8A);
+ if before {
+ ui.add(Label::new(RichText::new("⋅").size(10.0).color(color)));
+ }
+ ui.add(Label::new(
+ RichText::new(note_cache.reltime_str())
+ .size(10.0)
+ .color(color),
+ ));
+ if !before {
+ ui.add(Label::new(RichText::new("⋅").size(10.0).color(color)));
+ }
+ })
}
/*
@@ -637,6 +613,61 @@ struct NoteTimelineKey {
note_key: NoteKey,
}
+fn render_irc_note(
+ ui: &mut egui::Ui,
+ damus: &mut Damus,
+ note_key: NoteKey,
+ timeline: usize,
+) -> Result<()> {
+ let txn = Transaction::new(&damus.ndb)?;
+ let note = damus.ndb.get_note_by_key(&txn, note_key)?;
+ let id = egui::Id::new(NoteTimelineKey { note_key, timeline });
+
+ ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
+ let profile = damus.ndb.get_profile_by_pubkey(&txn, note.pubkey());
+
+ //ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
+ ui.horizontal(|ui| {
+ ui.spacing_mut().item_spacing.x = 2.0;
+
+ let note_cache = damus.get_note_cache_mut(note_key, note.created_at());
+ let (_id, rect) = ui.allocate_space(egui::vec2(50.0, 20.0));
+ ui.allocate_rect(rect, Sense::hover());
+ ui.put(rect, |ui: &mut egui::Ui| {
+ ui.set_clip_rect(rect);
+ render_reltime(ui, note_cache, false).response
+ });
+ let (_id, rect) = ui.allocate_space(egui::vec2(200.0, 20.0));
+ ui.allocate_rect(rect, Sense::hover());
+ ui.put(rect, |ui: &mut egui::Ui| {
+ ui.set_clip_rect(rect);
+ ui.add(
+ Username::new(profile.as_ref().ok(), note.pubkey())
+ .abbreviated(15)
+ .pk_colored(true),
+ )
+ });
+
+ ui.add(NoteContents::new(damus, &txn, ¬e, note_key));
+ });
+
+ //render_note_actionbar(ui);
+
+ //let header_res = ui.horizontal(|ui| {});
+ //});
+
+ //let resp = ui.interact(inner_resp.response.rect, id, Sense::hover());
+
+ //if resp.hovered() ^ collapse_state.is_open() {
+ //info!("clicked {:?}, {}", note_key, collapse_state.is_open());
+ //collapse_state.toggle(ui);
+ //collapse_state.store(ui.ctx());
+ //}
+ });
+
+ Ok(())
+}
+
fn render_note(
ui: &mut egui::Ui,
damus: &mut Damus,
@@ -671,11 +702,10 @@ fn render_note(
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 2.0;
-
- render_username(ui, profile.as_ref().ok(), note.pubkey());
+ ui.add(Username::new(profile.as_ref().ok(), note.pubkey()).abbreviated(20));
let note_cache = damus.get_note_cache_mut(note_key, note.created_at());
- render_reltime(ui, note_cache);
+ render_reltime(ui, note_cache, true);
});
ui.add(NoteContents::new(damus, &txn, ¬e, note_key));
@@ -727,8 +757,14 @@ fn render_notes(ui: &mut egui::Ui, damus: &mut Damus, timeline: usize) {
let num_notes = damus.timelines[timeline].notes.len();
+ let renderer = if damus.irc_mode {
+ render_irc_note
+ } else {
+ render_note
+ };
+
for i in 0..num_notes {
- let _ = render_note(ui, damus, damus.timelines[timeline].notes[i].key, timeline);
+ let _ = renderer(ui, damus, damus.timelines[timeline].notes[i].key, timeline);
ui.add(egui::Separator::default().spacing(0.0));
}
@@ -778,6 +814,13 @@ fn render_panel<'a>(ctx: &egui::Context, app: &'a mut Damus, timeline_ind: usize
ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
ui.visuals_mut().button_frame = false;
egui::widgets::global_dark_light_mode_switch(ui);
+ if ui
+ .add(egui::Button::new("A").frame(false))
+ .on_hover_text("IRC mode")
+ .clicked()
+ {
+ app.irc_mode = !app.irc_mode;
+ }
/*
if ui
diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs
@@ -1 +1,2 @@
pub mod note;
+pub mod username;
diff --git a/src/widgets/username.rs b/src/widgets/username.rs
@@ -0,0 +1,77 @@
+use crate::fonts::NamedFontFamily;
+use egui::{Color32, Label, RichText, Widget};
+use nostrdb::ProfileRecord;
+
+pub struct Username<'a> {
+ profile: Option<&'a ProfileRecord<'a>>,
+ pk: &'a [u8; 32],
+ pk_colored: bool,
+ abbrev: usize,
+}
+
+impl<'a> Username<'a> {
+ pub fn pk_colored(mut self, pk_colored: bool) -> Self {
+ self.pk_colored = pk_colored;
+ self
+ }
+
+ pub fn abbreviated(mut self, amount: usize) -> Self {
+ self.abbrev = amount;
+ self
+ }
+
+ pub fn new(profile: Option<&'a ProfileRecord>, pk: &'a [u8; 32]) -> Self {
+ let pk_colored = false;
+ let abbrev: usize = 1000;
+ Username {
+ profile,
+ pk,
+ pk_colored,
+ abbrev,
+ }
+ }
+}
+
+impl<'a> Widget for Username<'a> {
+ fn ui(self, ui: &mut egui::Ui) -> egui::Response {
+ ui.horizontal(|ui| {
+ //ui.spacing_mut().item_spacing.x = 0.0;
+ if let Some(profile) = self.profile {
+ if let Some(prof) = profile.record.profile() {
+ let color = if self.pk_colored {
+ Some(pk_color(self.pk))
+ } else {
+ None
+ };
+
+ if prof.display_name().is_some() && prof.display_name().unwrap() != "" {
+ ui_abbreviate_name(ui, prof.display_name().unwrap(), self.abbrev, color);
+ } else if let Some(name) = prof.name() {
+ ui_abbreviate_name(ui, name, self.abbrev, color);
+ }
+ }
+ } else {
+ ui.strong("nostrich");
+ }
+ })
+ .response
+ }
+}
+
+fn ui_abbreviate_name(ui: &mut egui::Ui, name: &str, len: usize, color: Option<Color32>) {
+ if name.len() > len {
+ let closest = crate::abbrev::floor_char_boundary(name, len);
+ ui.strong(&name[..closest]);
+ ui.strong("...");
+ } else {
+ let mut txt = RichText::new(name).family(NamedFontFamily::Medium.as_family());
+ if let Some(c) = color {
+ txt = txt.color(c);
+ }
+ ui.add(Label::new(txt));
+ }
+}
+
+fn pk_color(pk: &[u8; 32]) -> Color32 {
+ Color32::from_rgb(pk[8], pk[10], pk[12])
+}