From 059e9de8e3c63a11df2d274347393ac3540264dd Mon Sep 17 00:00:00 2001 From: Jorge Bejar Date: Fri, 11 Oct 2024 18:17:30 -0300 Subject: [PATCH] Make sure models and agent list selector is refresh when models are deleted --- src/app.rs | 2 + src/chat/chat_panel.rs | 65 +++++++++++++++-------------- src/chat/model_selector_list.rs | 19 +++++++++ src/my_models/delete_model_modal.rs | 7 ++-- 4 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/app.rs b/src/app.rs index 175eea5d..84e9874b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,5 @@ use crate::chat::chat_panel::ChatPanelAction; +use crate::chat::model_selector_list::ModelSelectorListAction; use crate::data::downloads::DownloadPendingNotification; use crate::data::store::*; use crate::landing::model_files_item::ModelFileItemAction; @@ -271,6 +272,7 @@ impl App { match notification { DownloadPendingNotification::DownloadedFile(file) => { popup.set_data(&file, DownloadResult::Success); + cx.action(ModelSelectorListAction::AddedOrDeletedModel); } DownloadPendingNotification::DownloadErrored(file) => { popup.set_data(&file, DownloadResult::Failure); diff --git a/src/chat/chat_panel.rs b/src/chat/chat_panel.rs index 9ec9c384..a1483875 100644 --- a/src/chat/chat_panel.rs +++ b/src/chat/chat_panel.rs @@ -1,11 +1,9 @@ use makepad_widgets::*; -use moly_protocol::data::FileID; use std::cell::{Ref, RefCell, RefMut}; use crate::{ chat::{ chat_line::{ChatLineAction, ChatLineWidgetRefExt}, - model_selector::ModelSelectorWidgetExt, model_selector_item::ModelSelectorAction, }, data::{ @@ -16,8 +14,8 @@ use crate::{ }; use super::{ - chat_history_card::ChatHistoryCardAction, prompt_input::PromptInputWidgetExt, - shared::ChatAgentAvatarWidgetRefExt, + chat_history_card::ChatHistoryCardAction, model_selector_list::ModelSelectorListAction, + prompt_input::PromptInputWidgetExt, shared::ChatAgentAvatarWidgetRefExt, }; live_design! { @@ -491,6 +489,10 @@ impl WidgetMatchEvent for ChatPanel { self.redraw(cx); } + if let ModelSelectorListAction::AddedOrDeletedModel = action.cast() { + self.redraw(cx); + } + match action.cast() { ChatAction::Start(handler) => match handler { ChatHandler::Model(file_id) => { @@ -568,32 +570,29 @@ impl ChatPanel { .get_current_chat() .and_then(|c| c.borrow().associated_entity.clone()); - self.state = match chat_entity { - Some(_) => { - // Model or Agent is selected - let is_loading = store.chats.model_loader.is_loading(); - - store.chats.get_current_chat().map_or( - State::ModelSelectedWithEmptyChat { is_loading }, - |chat| { - if chat.borrow().messages.is_empty() { - State::ModelSelectedWithEmptyChat { is_loading } - } else { - State::ModelSelectedWithChat { - is_loading, - sticked_to_bottom: self.portal_list_end_reached - || !matches!(self.state, State::ModelSelectedWithChat { .. }), - receiving_response: chat.borrow().is_receiving(), - was_cancelled: chat.borrow().was_cancelled(), - } + self.state = if chat_entity.is_none() && store.chats.loaded_model.is_none() { + State::NoModelSelected + } else { + // Model or Agent is selected + let is_loading = store.chats.model_loader.is_loading(); + + store.chats.get_current_chat().map_or( + State::ModelSelectedWithEmptyChat { is_loading }, + |chat| { + if chat.borrow().messages.is_empty() { + State::ModelSelectedWithEmptyChat { is_loading } + } else { + State::ModelSelectedWithChat { + is_loading, + sticked_to_bottom: self.portal_list_end_reached + || !matches!(self.state, State::ModelSelectedWithChat { .. }), + receiving_response: chat.borrow().is_receiving(), + was_cancelled: chat.borrow().was_cancelled(), } - }, - ) - } - None => { - State::NoModelSelected - } - }; + } + }, + ) + } } fn update_prompt_input(&mut self, cx: &mut Cx) { @@ -666,8 +665,12 @@ impl ChatPanel { }, ); - let send_button = self.prompt_input(id!(main_prompt_input)).button(id!(prompt_send_button)); - let stop_button = self.prompt_input(id!(main_prompt_input)).button(id!(prompt_stop_button)); + let send_button = self + .prompt_input(id!(main_prompt_input)) + .button(id!(prompt_send_button)); + let stop_button = self + .prompt_input(id!(main_prompt_input)) + .button(id!(prompt_stop_button)); match button { PromptInputButton::Send => { // The send button is enabled or not based on the prompt input diff --git a/src/chat/model_selector_list.rs b/src/chat/model_selector_list.rs index 6bc11b3c..3dcd4511 100644 --- a/src/chat/model_selector_list.rs +++ b/src/chat/model_selector_list.rs @@ -27,6 +27,12 @@ live_design! { } } +#[derive(Clone, DefaultNone, Debug)] +pub enum ModelSelectorListAction { + AddedOrDeletedModel, + None, +} + #[derive(Live, LiveHook, Widget)] pub struct ModelSelectorList { #[redraw] @@ -64,6 +70,7 @@ impl Widget for ModelSelectorList { for (_, item) in self.items.iter_mut() { item.handle_event(cx, event, scope) } + self.widget_match_event(cx, event, scope); } fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep { @@ -80,6 +87,18 @@ impl Widget for ModelSelectorList { } } +impl WidgetMatchEvent for ModelSelectorList { + fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions, _scope: &mut Scope) { + for action in actions.iter() { + if let ModelSelectorListAction::AddedOrDeletedModel = action.cast() { + self.items.clear(); + self.total_height = None; + self.redraw(cx); + } + } + } +} + impl ModelSelectorList { fn draw_items(&mut self, cx: &mut Cx2d, store: &Store) { let mut models = store.downloads.downloaded_files.clone(); diff --git a/src/my_models/delete_model_modal.rs b/src/my_models/delete_model_modal.rs index 8e356939..f09e641e 100644 --- a/src/my_models/delete_model_modal.rs +++ b/src/my_models/delete_model_modal.rs @@ -1,6 +1,6 @@ use makepad_widgets::*; -use crate::{chat::chat_panel::ChatPanelAction, data::store::Store}; +use crate::{chat::model_selector_list::ModelSelectorListAction, data::store::Store}; use super::downloaded_files_row::DownloadedFilesRowProps; @@ -173,8 +173,6 @@ impl Widget for DeleteModelModal { impl WidgetMatchEvent for DeleteModelModal { fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions, scope: &mut Scope) { - let widget_uid = self.widget_uid(); - if self.button(id!(close_button)).clicked(actions) { cx.action(DeleteModelModalAction::ModalDismissed); } @@ -184,11 +182,12 @@ impl WidgetMatchEvent for DeleteModelModal { .clicked(actions) { let store = scope.data.get_mut::().unwrap(); - store .delete_file(self.file_id.clone()) .expect("Failed to delete file"); + cx.action(DeleteModelModalAction::ModalDismissed); + cx.action(ModelSelectorListAction::AddedOrDeletedModel); } if self