diff --git a/assets/icons/reply_arrow.svg b/assets/icons/reply_arrow.svg new file mode 100644 index 0000000000..78e7133319 --- /dev/null +++ b/assets/icons/reply_arrow.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/crates/collab_ui/src/chat_panel.rs b/crates/collab_ui/src/chat_panel.rs index fb945987b5..c0a8a8d2f4 100644 --- a/crates/collab_ui/src/chat_panel.rs +++ b/crates/collab_ui/src/chat_panel.rs @@ -464,19 +464,25 @@ impl ChatPanel { v_flex() .w_full() .relative() + .group("") + .when(!is_continuation_from_previous, |this| this.pt_2()) + .child( + self.render_popover_buttons(&cx, message_id, can_delete_message) + .neg_mt_2p5(), + ) .child( div() .group("") .bg(background) .rounded_md() .overflow_hidden() - .px_1() + .px_1p5() .py_0p5() .when(!self.has_open_menu(message_id), |this| { this.hover(|style| style.bg(cx.theme().colors().element_hover)) }) .when(!is_continuation_from_previous, |this| { - this.mt_2().child( + this.child( h_flex() .text_ui_sm() .child(div().absolute().child( @@ -497,19 +503,9 @@ impl ChatPanel { )) .size(LabelSize::Small) .color(Color::Muted), - ) - .map(|el| { - el.child(self.render_popover_button( - &cx, - message_id, - can_delete_message, - )) - }), + ), ) }) - .when(is_continuation_from_previous, |el| { - el.child(self.render_popover_button(&cx, message_id, can_delete_message)) - }) .when( message.reply_to_message_id.is_some() && reply_to_message.is_none(), |this| { @@ -596,7 +592,7 @@ impl ChatPanel { } } - fn render_popover_button( + fn render_popover_buttons( &self, cx: &ViewContext, message_id: Option, @@ -605,28 +601,82 @@ impl ChatPanel { div() .absolute() .z_index(1) - .right_0() - .w_6() - .bg(cx.theme().colors().element_hover) - .when(!self.has_open_menu(message_id), |el| { - el.visible_on_hover("") - }) - .when_some(message_id, |el, message_id| { - let chat_panel_view = cx.view().clone(); + .child( + div() + .absolute() + .z_index(1) + .right_8() + .w_6() + .rounded_tl_md() + .rounded_bl_md() + .border_l_1() + .border_t_1() + .border_b_1() + .border_color(cx.theme().colors().element_selected) + .bg(cx.theme().colors().element_background) + .hover(|style| style.bg(cx.theme().colors().element_hover)) + .when(!self.has_open_menu(message_id), |el| { + el.visible_on_hover("") + }) + .when_some(message_id, |el, message_id| { + el.child( + div() + .id("reply") + .child( + IconButton::new(("reply", message_id), IconName::ReplyArrow) + .on_click(cx.listener(move |this, _, cx| { + this.message_editor.update(cx, |editor, cx| { + editor.set_reply_to_message_id(message_id); + editor.focus_handle(cx).focus(cx); + }) + })), + ) + .tooltip(|cx| Tooltip::text("Reply", cx)), + ) + }), + ) + .child( + div() + .absolute() + .z_index(1) + .right_2() + .w_6() + .rounded_tr_md() + .rounded_br_md() + .border_r_1() + .border_t_1() + .border_b_1() + .border_color(cx.theme().colors().element_selected) + .bg(cx.theme().colors().element_background) + .hover(|style| style.bg(cx.theme().colors().element_hover)) + .when(!self.has_open_menu(message_id), |el| { + el.visible_on_hover("") + }) + .when_some(message_id, |el, message_id| { + let this = cx.view().clone(); - el.child( - popover_menu(("menu", message_id)) - .trigger(IconButton::new(("trigger", message_id), IconName::Ellipsis)) - .menu(move |cx| { - Some(Self::render_message_menu( - &chat_panel_view, - message_id, - can_delete_message, - cx, - )) - }), - ) - }) + el.child( + div() + .id("more") + .child( + popover_menu(("menu", message_id)) + .trigger(IconButton::new( + ("trigger", message_id), + IconName::Ellipsis, + )) + .menu(move |cx| { + Some(Self::render_message_menu( + &this, + message_id, + can_delete_message, + cx, + )) + }), + ) + .tooltip(|cx| Tooltip::text("More", cx)), + ) + }), + ) } fn render_message_menu( diff --git a/crates/ui/src/components/icon.rs b/crates/ui/src/components/icon.rs index c05544533e..b979cf490b 100644 --- a/crates/ui/src/components/icon.rs +++ b/crates/ui/src/components/icon.rs @@ -101,6 +101,7 @@ pub enum IconName { ReplaceAll, ReplaceNext, Return, + ReplyArrow, Screen, SelectAll, Shift, @@ -194,6 +195,7 @@ impl IconName { IconName::ReplaceAll => "icons/replace_all.svg", IconName::ReplaceNext => "icons/replace_next.svg", IconName::Return => "icons/return.svg", + IconName::ReplyArrow => "icons/reply_arrow.svg", IconName::Screen => "icons/desktop.svg", IconName::SelectAll => "icons/select_all.svg", IconName::Shift => "icons/shift.svg",