notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit c6a7a50f81c505074abe84566b3725e620a3a1fb
parent f412b1ac7b04f6894a21ea34a5cccdd06184942b
Author: William Casarin <jb55@jb55.com>
Date:   Wed, 26 Mar 2025 16:54:28 -0700

dave: improve design

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
MCargo.lock | 1+
Mcrates/notedeck_chrome/src/theme.rs | 2+-
Mcrates/notedeck_columns/src/ui/search/mod.rs | 27+--------------------------
Mcrates/notedeck_dave/Cargo.toml | 1+
Mcrates/notedeck_dave/src/lib.rs | 37+++++++++++++++++++++++++------------
Acrates/notedeck_ui/src/icons.rs | 27+++++++++++++++++++++++++++
Mcrates/notedeck_ui/src/lib.rs | 1+
7 files changed, 57 insertions(+), 39 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -3231,6 +3231,7 @@ dependencies = [ "hex", "nostrdb", "notedeck", + "notedeck_ui", "rand 0.9.0", "serde", "serde_json", diff --git a/crates/notedeck_chrome/src/theme.rs b/crates/notedeck_chrome/src/theme.rs @@ -82,7 +82,7 @@ pub fn light_color_theme() -> ColorTheme { // INACTIVE WIDGET inactive_bg_stroke_color: EVEN_DARKER_GRAY, inactive_bg_fill: LIGHTER_GRAY, - inactive_weak_bg_fill: EVEN_DARKER_GRAY, + inactive_weak_bg_fill: LIGHTER_GRAY, } } diff --git a/crates/notedeck_columns/src/ui/search/mod.rs b/crates/notedeck_columns/src/ui/search/mod.rs @@ -9,6 +9,7 @@ use crate::{ use egui_winit::clipboard::Clipboard; use nostrdb::{Filter, Transaction}; use notedeck::{MuteFun, NoteRef}; +use notedeck_ui::icons::search_icon; use std::time::{Duration, Instant}; use tracing::{error, info, warn}; @@ -220,29 +221,3 @@ fn search_box(query: &mut SearchQueryState, ui: &mut egui::Ui, clipboard: &mut C }) .inner } - -/// Creates a magnifying glass icon widget -fn search_icon(size: f32, height: f32) -> impl egui::Widget { - move |ui: &mut egui::Ui| { - // Use the provided height parameter - let desired_size = vec2(size, height); - let (rect, response) = ui.allocate_exact_size(desired_size, egui::Sense::hover()); - - // Calculate center position - this ensures the icon is centered in its allocated space - let center_pos = rect.center(); - let stroke = Stroke::new(1.5, Color32::from_rgb(150, 150, 150)); - - // Draw circle - let circle_radius = size * 0.35; - ui.painter() - .circle(center_pos, circle_radius, Color32::TRANSPARENT, stroke); - - // Draw handle - let handle_start = center_pos + vec2(circle_radius * 0.7, circle_radius * 0.7); - let handle_end = handle_start + vec2(size * 0.25, size * 0.25); - ui.painter() - .line_segment([handle_start, handle_end], stroke); - - response - } -} diff --git a/crates/notedeck_dave/Cargo.toml b/crates/notedeck_dave/Cargo.toml @@ -7,6 +7,7 @@ version.workspace = true async-openai = "0.28.0" egui = { workspace = true } notedeck = { workspace = true } +notedeck_ui = { workspace = true } eframe = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } diff --git a/crates/notedeck_dave/src/lib.rs b/crates/notedeck_dave/src/lib.rs @@ -14,6 +14,7 @@ use async_openai::{ use futures::StreamExt; use nostrdb::{Ndb, NoteKey, Transaction}; use notedeck::AppContext; +use notedeck_ui::icons::search_icon; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use std::collections::HashMap; @@ -378,11 +379,12 @@ impl Dave { // Scroll area for chat messages egui::Frame::new() - .outer_margin(egui::Margin { - top: 100, - ..Default::default() + .inner_margin(egui::Margin { + left: 50, + right: 50, + top: 50, + bottom: 50, }) - .inner_margin(10.0) .show(ui, |ui| { egui::ScrollArea::vertical() .stick_to_bottom(true) @@ -439,13 +441,24 @@ impl Dave { match &call.typ { ToolCalls::Search(search_call) => { ui.horizontal(|ui| { - let context = match search_call.context { - SearchContext::Profile => "profile ", - SearchContext::Any => " ", - SearchContext::Home => "home ", - }; - - ui.label(format!("Searching {}for '{}'", context, search_call.query)); + egui::Frame::new() + .inner_margin(10.0) + .corner_radius(10.0) + .fill(ui.visuals().widgets.inactive.weak_bg_fill) + .show(ui, |ui| { + ui.add(search_icon(16.0, 16.0)); + ui.add_space(8.0); + let context = match search_call.context { + SearchContext::Profile => "profile ", + SearchContext::Any => "", + SearchContext::Home => "home ", + }; + + ui.label(format!( + "Searching {}for '{}'", + context, search_call.query + )); + }) }); } } @@ -478,7 +491,7 @@ impl Dave { fn assistant_chat(&self, msg: &str, ui: &mut egui::Ui) { ui.horizontal_wrapped(|ui| { - ui.label(msg); + ui.add(egui::Label::new(msg).wrap_mode(egui::TextWrapMode::Wrap)); }); } diff --git a/crates/notedeck_ui/src/icons.rs b/crates/notedeck_ui/src/icons.rs @@ -0,0 +1,27 @@ +use egui::{vec2, Color32, Stroke}; + +/// Creates a magnifying glass icon widget +pub fn search_icon(size: f32, height: f32) -> impl egui::Widget { + move |ui: &mut egui::Ui| { + // Use the provided height parameter + let desired_size = vec2(size, height); + let (rect, response) = ui.allocate_exact_size(desired_size, egui::Sense::hover()); + + // Calculate center position - this ensures the icon is centered in its allocated space + let center_pos = rect.center(); + let stroke = Stroke::new(1.5, Color32::from_rgb(150, 150, 150)); + + // Draw circle + let circle_radius = size * 0.35; + ui.painter() + .circle(center_pos, circle_radius, Color32::TRANSPARENT, stroke); + + // Draw handle + let handle_start = center_pos + vec2(circle_radius * 0.7, circle_radius * 0.7); + let handle_end = handle_start + vec2(size * 0.25, size * 0.25); + ui.painter() + .line_segment([handle_start, handle_end], stroke); + + response + } +} diff --git a/crates/notedeck_ui/src/lib.rs b/crates/notedeck_ui/src/lib.rs @@ -3,6 +3,7 @@ pub mod colors; pub mod gif; pub mod images; pub mod profile; +pub mod icons; pub use anim::AnimationHelper; pub use profile::ProfilePic;