feat(note-view): show note client

This commit is contained in:
Fernando López Guevara
2025-07-01 13:44:56 -03:00
parent cb5bd75236
commit 4bf75c95de
14 changed files with 113 additions and 53 deletions

View File

@@ -1,5 +1,5 @@
use eframe::icon_data::from_png_bytes;
use egui::{include_image, IconData, Image};
use egui::{include_image, Color32, IconData, Image};
pub fn app_icon() -> IconData {
from_png_bytes(include_bytes!("../../../assets/damus-app-icon.png")).expect("icon")
@@ -113,12 +113,12 @@ pub fn help_light_image() -> Image<'static> {
))
}
pub fn home_dark_image() -> Image<'static> {
Image::new(include_image!("../../../assets/icons/home-toolbar.png"))
pub fn home_light_image() -> Image<'static> {
home_dark_image().tint(Color32::BLACK)
}
pub fn home_light_image() -> Image<'static> {
home_dark_image().tint(egui::Color32::BLACK)
pub fn home_dark_image() -> Image<'static> {
Image::new(include_image!("../../../assets/icons/home-toolbar.png"))
}
pub fn home_image() -> Image<'static> {
@@ -131,10 +131,14 @@ pub fn key_image() -> Image<'static> {
Image::new(include_image!("../../../assets/icons/key_4x.png"))
}
pub fn link_image() -> Image<'static> {
pub fn link_dark_image() -> Image<'static> {
Image::new(include_image!("../../../assets/icons/links_4x.png"))
}
pub fn link_light_image() -> Image<'static> {
link_dark_image().tint(Color32::BLACK)
}
pub fn new_message_image() -> Image<'static> {
Image::new(include_image!("../../../assets/icons/newmessage_64.png"))
}
@@ -153,15 +157,16 @@ pub fn notifications_image(dark_mode: bool) -> Image<'static> {
}
}
pub fn notifications_light_image() -> Image<'static> {
notifications_dark_image().tint(Color32::BLACK)
}
pub fn notifications_dark_image() -> Image<'static> {
Image::new(include_image!(
"../../../assets/icons/notifications_dark_4x.png"
))
}
pub fn notifications_light_image() -> Image<'static> {
notifications_dark_image().tint(egui::Color32::BLACK)
}
pub fn repost_dark_image() -> Image<'static> {
Image::new(include_image!("../../../assets/icons/repost_icon_4x.png"))
}
@@ -208,10 +213,22 @@ pub fn media_upload_dark_image() -> Image<'static> {
))
}
pub fn wallet_image() -> Image<'static> {
pub fn media_upload_light_image() -> Image<'static> {
media_upload_dark_image().tint(Color32::BLACK)
}
pub fn wallet_dark_image() -> Image<'static> {
Image::new(include_image!("../../../assets/icons/wallet-icon.svg"))
}
pub fn zap_image() -> Image<'static> {
pub fn wallet_light_image() -> Image<'static> {
wallet_dark_image().tint(Color32::BLACK)
}
pub fn zap_dark_image() -> Image<'static> {
Image::new(include_image!("../../../assets/icons/zap_4x.png"))
}
pub fn zap_light_image() -> Image<'static> {
zap_dark_image().tint(Color32::BLACK)
}

View File

@@ -21,7 +21,7 @@ pub use note::{NoteContents, NoteOptions, NoteView};
pub use profile::{ProfilePic, ProfilePreview};
pub use username::Username;
use egui::Margin;
use egui::{Label, Margin, RichText};
/// This is kind of like the Widget trait but is meant for larger top-level
/// views that are typically stateful.
@@ -58,3 +58,8 @@ pub fn hline_with_width(ui: &egui::Ui, range: egui::Rangef) {
let stroke = ui.style().visuals.widgets.noninteractive.bg_stroke;
ui.painter().hline(range, resize_y, stroke);
}
pub fn secondary_label(ui: &mut egui::Ui, s: impl Into<String>) {
let color = ui.style().visuals.noninteractive().fg_stroke.color;
ui.add(Label::new(RichText::new(s).size(10.0).color(color)).selectable(false));
}

View File

@@ -4,13 +4,14 @@ use crate::{
blur::imeta_blurhashes,
jobs::JobsCache,
note::{NoteAction, NoteOptions, NoteResponse, NoteView},
secondary_label,
};
use egui::{Color32, Hyperlink, RichText};
use nostrdb::{BlockType, Mention, Note, NoteKey, Transaction};
use tracing::warn;
use notedeck::{IsFollowing, NoteContext};
use notedeck::{IsFollowing, NoteCache, NoteContext};
use super::media::{find_renderable_media, image_carousel, RenderableMedia};
@@ -53,11 +54,28 @@ impl egui::Widget for &mut NoteContents<'_, '_> {
self.options,
self.jobs,
);
if self.options.contains(NoteOptions::ShowNoteClient) {
render_client(ui, self.note_context.note_cache, self.note);
}
self.action = result.action;
result.response
}
}
#[profiling::function]
fn render_client(ui: &mut egui::Ui, note_cache: &mut NoteCache, note: &Note) {
let cached_note = note_cache.cached_note_or_insert_mut(note.key().unwrap(), note);
match cached_note.client.as_deref() {
Some(client) if !client.is_empty() => {
ui.horizontal(|ui| {
secondary_label(ui, format!("via {}", client));
});
}
_ => return,
}
}
/// Render an inline note preview with a border. These are used when
/// notes are references within a note
#[allow(clippy::too_many_arguments)]

View File

@@ -4,8 +4,8 @@ pub mod media;
pub mod options;
pub mod reply_description;
use crate::app_images;
use crate::jobs::JobsCache;
use crate::{app_images, secondary_label};
use crate::{
profile::name::one_line_display_name_widget, widgets::x_button, ProfilePic, ProfilePreview,
PulseAlpha, Username,
@@ -21,7 +21,7 @@ pub use options::NoteOptions;
pub use reply_description::reply_desc;
use egui::emath::{pos2, Vec2};
use egui::{Id, Label, Pos2, Rect, Response, RichText, Sense};
use egui::{Id, Pos2, Rect, Response, RichText, Sense};
use enostr::{KeypairUnowned, NoteId, Pubkey};
use nostrdb::{Ndb, Note, NoteKey, ProfileRecord, Transaction};
use notedeck::{
@@ -534,6 +534,7 @@ impl<'a, 'd> NoteView<'a, 'd> {
cur_acc: cur_acc.keypair(),
})
};
if self.options().contains(NoteOptions::ActionBar) {
note_action = render_note_actionbar(
ui,
@@ -828,11 +829,6 @@ fn render_note_actionbar(
})
}
fn secondary_label(ui: &mut egui::Ui, s: impl Into<String>) {
let color = ui.style().visuals.noninteractive().fg_stroke.color;
ui.add(Label::new(RichText::new(s).size(10.0).color(color)));
}
#[profiling::function]
fn render_reltime(
ui: &mut egui::Ui,
@@ -902,14 +898,14 @@ fn zap_button(state: AnyZapState, noteid: &[u8; 32]) -> impl egui::Widget + use<
move |ui: &mut egui::Ui| -> egui::Response {
let (rect, size, resp) = crate::anim::hover_expand_small(ui, ui.id().with("zap"));
let mut img = app_images::zap_image().max_width(size);
let mut img = app_images::zap_dark_image().max_width(size);
let id = ui.id().with(("pulse", noteid));
let ctx = ui.ctx().clone();
match state {
AnyZapState::None => {
if !ui.visuals().dark_mode {
img = img.tint(egui::Color32::BLACK);
img = app_images::zap_light_image();
}
}
AnyZapState::Pending => {

View File

@@ -22,6 +22,8 @@ bitflags! {
/// Is the content truncated? If the length is over a certain size it
/// will end with a ... and a "Show more" button.
const Truncate = 1 << 11;
/// Show note's client in the note header
const ShowNoteClient = 1 << 12;
}
}