1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -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",
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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 }
|
||||||
|
|||||||
@@ -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));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
crates/notedeck_ui/src/icons.rs
Normal file
27
crates/notedeck_ui/src/icons.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user