Merge branch 'main' into completion-menu-detail-layout

This commit is contained in:
Marshall Bowers 2024-01-03 11:44:29 -05:00
commit c4f7dedd63
3 changed files with 95 additions and 59 deletions

View file

@ -2110,6 +2110,47 @@ impl CollabPanel {
None None
}; };
let button_container = |cx: &mut ViewContext<Self>| {
h_stack()
.absolute()
// We're using a negative coordinate for the right anchor to
// counteract the padding of the `ListItem`.
//
// This prevents a gap from showing up between the background
// of this element and the edge of the collab panel.
.right(rems(-0.5))
// HACK: Without this the channel name clips on top of the icons, but I'm not sure why.
.z_index(10)
.bg(cx.theme().colors().panel_background)
.when(is_selected || is_active, |this| {
this.bg(cx.theme().colors().ghost_element_selected)
})
};
let messages_button = |cx: &mut ViewContext<Self>| {
IconButton::new("channel_chat", Icon::MessageBubbles)
.icon_size(IconSize::Small)
.icon_color(if has_messages_notification {
Color::Default
} else {
Color::Muted
})
.on_click(cx.listener(move |this, _, cx| this.join_channel_chat(channel_id, cx)))
.tooltip(|cx| Tooltip::text("Open channel chat", cx))
};
let notes_button = |cx: &mut ViewContext<Self>| {
IconButton::new("channel_notes", Icon::File)
.icon_size(IconSize::Small)
.icon_color(if has_notes_notification {
Color::Default
} else {
Color::Muted
})
.on_click(cx.listener(move |this, _, cx| this.open_channel_notes(channel_id, cx)))
.tooltip(|cx| Tooltip::text("Open channel notes", cx))
};
let width = self.width.unwrap_or(px(240.)); let width = self.width.unwrap_or(px(240.));
div() div()
@ -2172,63 +2213,49 @@ impl CollabPanel {
.child(Label::new(channel.name.clone())) .child(Label::new(channel.name.clone()))
.children(face_pile.map(|face_pile| face_pile.render(cx))), .children(face_pile.map(|face_pile| face_pile.render(cx))),
) )
.end_slot( .end_slot::<Div>(
h_stack() // If we have a notification for either button, we want to show the corresponding
.absolute() // button(s) as indicators.
// We're using a negative coordinate for the right anchor to if has_messages_notification || has_notes_notification {
// counteract the padding of the `ListItem`. Some(
// button_container(cx).child(
// This prevents a gap from showing up between the background h_stack()
// of this element and the edge of the collab panel. .px_1()
.right(rems(-0.5)) .children(
// HACK: Without this the channel name clips on top of the icons, but I'm not sure why. // We only want to render the messages button if there are unseen messages.
.z_index(10) // This way we don't take up any space that might overlap the channel name
.bg(cx.theme().colors().panel_background) // when there are no notifications.
.when(is_selected || is_active, |this| { has_messages_notification.then(|| messages_button(cx)),
this.bg(cx.theme().colors().ghost_element_selected) )
}) .child(
.child( // We always want the notes button to take up space to prevent layout
h_stack() // shift when hovering over the channel.
.px_1() // However, if there are is no notes notification we just show an empty slot.
// The element hover background has a slight transparency to it, so we notes_button(cx)
// need to apply it to the inner element so that it blends with the solid .when(!has_notes_notification, |this| {
// background color of the absolutely-positioned element. this.visible_on_hover("")
.group_hover("", |style| { }),
style.bg(cx.theme().colors().ghost_element_hover) ),
}) ),
.child( )
IconButton::new("channel_chat", Icon::MessageBubbles) } else {
.icon_size(IconSize::Small) None
.icon_color(if has_messages_notification { },
Color::Default )
} else { .end_hover_slot(
Color::Muted // When we hover the channel entry we want to always show both buttons.
}) button_container(cx).child(
.when(!has_messages_notification, |this| { h_stack()
this.visible_on_hover("") .px_1()
}) // The element hover background has a slight transparency to it, so we
.on_click(cx.listener(move |this, _, cx| { // need to apply it to the inner element so that it blends with the solid
this.join_channel_chat(channel_id, cx) // background color of the absolutely-positioned element.
})) .group_hover("", |style| {
.tooltip(|cx| Tooltip::text("Open channel chat", cx)), style.bg(cx.theme().colors().ghost_element_hover)
) })
.child( .child(messages_button(cx))
IconButton::new("channel_notes", Icon::File) .child(notes_button(cx)),
.icon_size(IconSize::Small) ),
.icon_color(if has_notes_notification {
Color::Default
} else {
Color::Muted
})
.when(!has_notes_notification, |this| {
this.visible_on_hover("")
})
.on_click(cx.listener(move |this, _, cx| {
this.open_channel_notes(channel_id, cx)
}))
.tooltip(|cx| Tooltip::text("Open channel notes", cx)),
),
),
), ),
) )
.tooltip(|cx| Tooltip::text("Join channel", cx)) .tooltip(|cx| Tooltip::text("Join channel", cx))

View file

@ -7,7 +7,7 @@ use crate::{
ToggleCaseSensitive, ToggleReplace, ToggleWholeWord, ToggleCaseSensitive, ToggleReplace, ToggleWholeWord,
}; };
use collections::HashMap; use collections::HashMap;
use editor::{Editor, EditorElement, EditorStyle}; use editor::{Editor, EditorElement, EditorStyle, Tab};
use futures::channel::oneshot; use futures::channel::oneshot;
use gpui::{ use gpui::{
actions, div, impl_actions, Action, AppContext, ClickEvent, EventEmitter, FocusableView, actions, div, impl_actions, Action, AppContext, ClickEvent, EventEmitter, FocusableView,
@ -190,6 +190,7 @@ impl Render for BufferSearchBar {
.w_full() .w_full()
.gap_2() .gap_2()
.key_context(key_context) .key_context(key_context)
.capture_action(cx.listener(Self::tab))
.on_action(cx.listener(Self::previous_history_query)) .on_action(cx.listener(Self::previous_history_query))
.on_action(cx.listener(Self::next_history_query)) .on_action(cx.listener(Self::next_history_query))
.on_action(cx.listener(Self::dismiss)) .on_action(cx.listener(Self::dismiss))
@ -932,6 +933,14 @@ impl BufferSearchBar {
} }
} }
fn tab(&mut self, _: &Tab, cx: &mut ViewContext<Self>) {
if let Some(item) = self.active_searchable_item.as_ref() {
let focus_handle = item.focus_handle(cx);
cx.focus(&focus_handle);
cx.stop_propagation();
}
}
fn next_history_query(&mut self, _: &NextHistoryQuery, cx: &mut ViewContext<Self>) { fn next_history_query(&mut self, _: &NextHistoryQuery, cx: &mut ViewContext<Self>) {
if let Some(new_query) = self.search_history.next().map(str::to_string) { if let Some(new_query) = self.search_history.next().map(str::to_string) {
let _ = self.search(&new_query, Some(self.search_options), cx); let _ = self.search(&new_query, Some(self.search_options), cx);

View file

@ -1687,7 +1687,7 @@ impl Pane {
), ),
) )
}) })
.when(self.has_focus(cx), |tab_bar| { .when(self.was_focused || self.has_focus(cx), |tab_bar| {
tab_bar.end_child({ tab_bar.end_child({
let render_tab_buttons = self.render_tab_bar_buttons.clone(); let render_tab_buttons = self.render_tab_bar_buttons.clone();
render_tab_buttons(self, cx) render_tab_buttons(self, cx)