dave: add new chat button

This commit is contained in:
William Casarin
2025-04-21 17:10:03 -07:00
parent 9ec5f1efa2
commit d4681801e8
2 changed files with 64 additions and 4 deletions

View File

@@ -157,6 +157,11 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
DaveUi::new(&self.chat, &mut self.input).ui(app_ctx, ui) DaveUi::new(&self.chat, &mut self.input).ui(app_ctx, ui)
} }
fn handle_new_chat(&mut self) {
self.chat = vec![];
self.input.clear();
}
/// Handle a user send action triggered by the ui /// Handle a user send action triggered by the ui
fn handle_user_send(&mut self, app_ctx: &AppContext, ui: &egui::Ui) { fn handle_user_send(&mut self, app_ctx: &AppContext, ui: &egui::Ui) {
self.chat.push(Message::User(self.input.clone())); self.chat.push(Message::User(self.input.clone()));
@@ -296,6 +301,9 @@ impl notedeck::App for Dave {
let should_send = self.process_events(ctx); let should_send = self.process_events(ctx);
if let Some(action) = self.ui(ctx, ui).action { if let Some(action) = self.ui(ctx, ui).action {
match action { match action {
DaveAction::NewChat => {
self.handle_new_chat();
}
DaveAction::Send => { DaveAction::Send => {
self.handle_user_send(ctx, ui); self.handle_user_send(ctx, ui);
} }

View File

@@ -21,11 +21,21 @@ pub struct DaveResponse {
} }
impl DaveResponse { impl DaveResponse {
fn new(action: DaveAction) -> Self {
DaveResponse {
action: Some(action),
}
}
fn or(self, r: DaveResponse) -> DaveResponse {
DaveResponse {
action: self.action.or(r.action),
}
}
/// Generate a send response to the controller /// Generate a send response to the controller
fn send() -> Self { fn send() -> Self {
DaveResponse { Self::new(DaveAction::Send)
action: Some(DaveAction::Send),
}
} }
fn none() -> Self { fn none() -> Self {
@@ -40,6 +50,7 @@ impl DaveResponse {
pub enum DaveAction { pub enum DaveAction {
/// The action generated when the user sends a message to dave /// The action generated when the user sends a message to dave
Send, Send,
NewChat,
} }
impl<'a> DaveUi<'a> { impl<'a> DaveUi<'a> {
@@ -67,7 +78,22 @@ impl<'a> DaveUi<'a> {
/// The main render function. Call this to render Dave /// The main render function. Call this to render Dave
pub fn ui(&mut self, app_ctx: &mut AppContext, ui: &mut egui::Ui) -> DaveResponse { pub fn ui(&mut self, app_ctx: &mut AppContext, ui: &mut egui::Ui) -> DaveResponse {
let mut action: Option<DaveAction> = None;
// Scroll area for chat messages // Scroll area for chat messages
let new_resp = {
let mut rect = ui.available_rect_before_wrap();
rect = rect.translate(egui::vec2(20.0, 20.0));
rect.set_width(32.0);
rect.set_height(32.0);
ui.put(rect, new_chat_button())
};
if new_resp.clicked() {
action = Some(DaveAction::NewChat);
} else if new_resp.hovered() {
notedeck_ui::show_pointer(ui);
}
egui::Frame::NONE egui::Frame::NONE
.show(ui, |ui| { .show(ui, |ui| {
ui.with_layout(Layout::bottom_up(Align::Min), |ui| { ui.with_layout(Layout::bottom_up(Align::Min), |ui| {
@@ -82,7 +108,6 @@ impl<'a> DaveUi<'a> {
}) })
.inner_margin(egui::Margin::same(8)) .inner_margin(egui::Margin::same(8))
.fill(ui.visuals().extreme_bg_color) .fill(ui.visuals().extreme_bg_color)
//.stroke(stroke)
.corner_radius(12.0) .corner_radius(12.0)
.show(ui, |ui| self.inputbox(ui)) .show(ui, |ui| self.inputbox(ui))
.inner; .inner;
@@ -103,6 +128,7 @@ impl<'a> DaveUi<'a> {
.inner .inner
}) })
.inner .inner
.or(DaveResponse { action })
} }
/// Render a chat message (user, assistant, tool call/response, etc) /// Render a chat message (user, assistant, tool call/response, etc)
@@ -251,3 +277,29 @@ impl<'a> DaveUi<'a> {
}); });
} }
} }
fn new_chat_button() -> impl egui::Widget {
move |ui: &mut egui::Ui| {
let img_size = 24.0;
let max_size = 32.0;
let img_data = egui::include_image!("../../../../assets/icons/newmessage_64.png");
let img = egui::Image::new(img_data).max_width(img_size);
let helper = notedeck_ui::anim::AnimationHelper::new(
ui,
"new-chat-button",
egui::vec2(max_size, max_size),
);
let cur_img_size = helper.scale_1d_pos(img_size);
img.paint_at(
ui,
helper
.get_animation_rect()
.shrink((max_size - cur_img_size) / 2.0),
);
helper.take_animation_response()
}
}