This commit is contained in:
Antonio Scandurra 2023-06-21 11:44:32 +02:00
parent 9217224fa6
commit 06701e78aa
3 changed files with 59 additions and 13 deletions

View file

@ -34,7 +34,7 @@ struct SavedConversation {
struct SavedConversationMetadata { struct SavedConversationMetadata {
title: String, title: String,
path: PathBuf, path: PathBuf,
mtime: SystemTime, mtime: chrono::DateTime<chrono::Local>,
} }
impl SavedConversationMetadata { impl SavedConversationMetadata {
@ -59,7 +59,7 @@ impl SavedConversationMetadata {
conversations.push(Self { conversations.push(Self {
title: title.into_owned(), title: title.into_owned(),
path, path,
mtime: metadata.mtime, mtime: metadata.mtime.into(),
}); });
} }
} }

View file

@ -104,9 +104,10 @@ pub enum AssistantPanelEvent {
pub struct AssistantPanel { pub struct AssistantPanel {
width: Option<f32>, width: Option<f32>,
height: Option<f32>, height: Option<f32>,
active_conversation_index: usize, active_conversation_index: Option<usize>,
conversation_editors: Vec<ViewHandle<ConversationEditor>>, conversation_editors: Vec<ViewHandle<ConversationEditor>>,
saved_conversations: Vec<SavedConversationMetadata>, saved_conversations: Vec<SavedConversationMetadata>,
saved_conversations_list_state: UniformListState,
zoomed: bool, zoomed: bool,
has_focus: bool, has_focus: bool,
api_key: Rc<RefCell<Option<String>>>, api_key: Rc<RefCell<Option<String>>>,
@ -153,9 +154,10 @@ impl AssistantPanel {
}); });
let mut this = Self { let mut this = Self {
active_conversation_index: 0, active_conversation_index: Default::default(),
conversation_editors: Default::default(), conversation_editors: Default::default(),
saved_conversations, saved_conversations,
saved_conversations_list_state: Default::default(),
zoomed: false, zoomed: false,
has_focus: false, has_focus: false,
api_key: Rc::new(RefCell::new(None)), api_key: Rc::new(RefCell::new(None)),
@ -202,7 +204,7 @@ impl AssistantPanel {
self.subscriptions self.subscriptions
.push(cx.subscribe(&editor, Self::handle_conversation_editor_event)); .push(cx.subscribe(&editor, Self::handle_conversation_editor_event));
self.active_conversation_index = self.conversation_editors.len(); self.active_conversation_index = Some(self.conversation_editors.len());
self.conversation_editors.push(editor.clone()); self.conversation_editors.push(editor.clone());
cx.notify(); cx.notify();
@ -258,18 +260,43 @@ impl AssistantPanel {
fn active_conversation_editor(&self) -> Option<&ViewHandle<ConversationEditor>> { fn active_conversation_editor(&self) -> Option<&ViewHandle<ConversationEditor>> {
self.conversation_editors self.conversation_editors
.get(self.active_conversation_index) .get(self.active_conversation_index?)
} }
fn render_hamburger_button( fn render_hamburger_button(style: &IconStyle) -> impl Element<Self> {
&self,
style: &IconStyle,
cx: &ViewContext<Self>,
) -> impl Element<Self> {
Svg::for_style(style.icon.clone()) Svg::for_style(style.icon.clone())
.contained() .contained()
.with_style(style.container) .with_style(style.container)
} }
fn render_saved_conversation(
&mut self,
index: usize,
cx: &mut ViewContext<Self>,
) -> impl Element<Self> {
MouseEventHandler::<SavedConversationMetadata, _>::new(index, cx, move |state, cx| {
let style = &theme::current(cx).assistant.saved_conversation;
let conversation = &self.saved_conversations[index];
Flex::row()
.with_child(
Label::new(
conversation.mtime.format("%c").to_string(),
style.saved_at.text.clone(),
)
.contained()
.with_style(style.saved_at.container),
)
.with_child(
Label::new(conversation.title.clone(), style.title.text.clone())
.contained()
.with_style(style.title.container),
)
.contained()
.with_style(*style.container.style_for(state, false))
})
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, |_, this, cx| {})
}
} }
fn build_api_key_editor(cx: &mut ViewContext<AssistantPanel>) -> ViewHandle<Editor> { fn build_api_key_editor(cx: &mut ViewContext<AssistantPanel>) -> ViewHandle<Editor> {
@ -318,7 +345,7 @@ impl View for AssistantPanel {
Flex::column() Flex::column()
.with_child( .with_child(
Flex::row() Flex::row()
.with_child(self.render_hamburger_button(&style.hamburger_button, cx)) .with_child(Self::render_hamburger_button(&style.hamburger_button))
.contained() .contained()
.with_style(theme.workspace.tab_bar.container) .with_style(theme.workspace.tab_bar.container)
.constrained() .constrained()
@ -327,7 +354,17 @@ impl View for AssistantPanel {
.with_child(ChildView::new(editor, cx).flex(1., true)) .with_child(ChildView::new(editor, cx).flex(1., true))
.into_any() .into_any()
} else { } else {
Empty::new().into_any() UniformList::new(
self.saved_conversations_list_state.clone(),
self.saved_conversations.len(),
cx,
|this, range, items, cx| {
for ix in range {
items.push(this.render_saved_conversation(ix, cx).into_any());
}
},
)
.into_any()
} }
} }

View file

@ -1007,6 +1007,15 @@ pub struct AssistantStyle {
pub error_icon: Icon, pub error_icon: Icon,
pub api_key_editor: FieldEditor, pub api_key_editor: FieldEditor,
pub api_key_prompt: ContainedText, pub api_key_prompt: ContainedText,
pub saved_conversation: SavedConversation,
}
#[derive(Clone, Deserialize, Default)]
pub struct SavedConversation {
#[serde(flatten)]
pub container: Interactive<ContainerStyle>,
pub saved_at: ContainedText,
pub title: ContainedText,
} }
#[derive(Clone, Deserialize, Default)] #[derive(Clone, Deserialize, Default)]