dave: improve design

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2025-03-26 16:54:28 -07:00
parent f412b1ac7b
commit c6a7a50f81
7 changed files with 56 additions and 38 deletions

1
Cargo.lock generated
View File

@@ -3231,6 +3231,7 @@ dependencies = [
"hex", "hex",
"nostrdb", "nostrdb",
"notedeck", "notedeck",
"notedeck_ui",
"rand 0.9.0", "rand 0.9.0",
"serde", "serde",
"serde_json", "serde_json",

View File

@@ -82,7 +82,7 @@ pub fn light_color_theme() -> ColorTheme {
// INACTIVE WIDGET // INACTIVE WIDGET
inactive_bg_stroke_color: EVEN_DARKER_GRAY, inactive_bg_stroke_color: EVEN_DARKER_GRAY,
inactive_bg_fill: LIGHTER_GRAY, inactive_bg_fill: LIGHTER_GRAY,
inactive_weak_bg_fill: EVEN_DARKER_GRAY, inactive_weak_bg_fill: LIGHTER_GRAY,
} }
} }

View File

@@ -9,6 +9,7 @@ use crate::{
use egui_winit::clipboard::Clipboard; use egui_winit::clipboard::Clipboard;
use nostrdb::{Filter, Transaction}; use nostrdb::{Filter, Transaction};
use notedeck::{MuteFun, NoteRef}; use notedeck::{MuteFun, NoteRef};
use notedeck_ui::icons::search_icon;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use tracing::{error, info, warn}; use tracing::{error, info, warn};
@@ -220,29 +221,3 @@ fn search_box(query: &mut SearchQueryState, ui: &mut egui::Ui, clipboard: &mut C
}) })
.inner .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
}
}

View File

@@ -7,6 +7,7 @@ version.workspace = true
async-openai = "0.28.0" async-openai = "0.28.0"
egui = { workspace = true } egui = { workspace = true }
notedeck = { workspace = true } notedeck = { workspace = true }
notedeck_ui = { workspace = true }
eframe = { workspace = true } eframe = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
tracing = { workspace = true } tracing = { workspace = true }

View File

@@ -14,6 +14,7 @@ use async_openai::{
use futures::StreamExt; use futures::StreamExt;
use nostrdb::{Ndb, NoteKey, Transaction}; use nostrdb::{Ndb, NoteKey, Transaction};
use notedeck::AppContext; use notedeck::AppContext;
use notedeck_ui::icons::search_icon;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{json, Value}; use serde_json::{json, Value};
use std::collections::HashMap; use std::collections::HashMap;
@@ -378,11 +379,12 @@ impl Dave {
// Scroll area for chat messages // Scroll area for chat messages
egui::Frame::new() egui::Frame::new()
.outer_margin(egui::Margin { .inner_margin(egui::Margin {
top: 100, left: 50,
..Default::default() right: 50,
top: 50,
bottom: 50,
}) })
.inner_margin(10.0)
.show(ui, |ui| { .show(ui, |ui| {
egui::ScrollArea::vertical() egui::ScrollArea::vertical()
.stick_to_bottom(true) .stick_to_bottom(true)
@@ -439,13 +441,24 @@ impl Dave {
match &call.typ { match &call.typ {
ToolCalls::Search(search_call) => { ToolCalls::Search(search_call) => {
ui.horizontal(|ui| { ui.horizontal(|ui| {
let context = match search_call.context { egui::Frame::new()
SearchContext::Profile => "profile ", .inner_margin(10.0)
SearchContext::Any => " ", .corner_radius(10.0)
SearchContext::Home => "home ", .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)); 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) { fn assistant_chat(&self, msg: &str, ui: &mut egui::Ui) {
ui.horizontal_wrapped(|ui| { ui.horizontal_wrapped(|ui| {
ui.label(msg); ui.add(egui::Label::new(msg).wrap_mode(egui::TextWrapMode::Wrap));
}); });
} }

View File

@@ -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
}
}

View File

@@ -3,6 +3,7 @@ pub mod colors;
pub mod gif; pub mod gif;
pub mod images; pub mod images;
pub mod profile; pub mod profile;
pub mod icons;
pub use anim::AnimationHelper; pub use anim::AnimationHelper;
pub use profile::ProfilePic; pub use profile::ProfilePic;