update sidebar
This commit is contained in:
@@ -116,26 +116,20 @@ pub trait ButtonVariants: Sized {
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub struct Button {
|
||||
base: BaseButton,
|
||||
|
||||
icon: Option<Icon>,
|
||||
label: Option<SharedString>,
|
||||
tooltip: Option<SharedString>,
|
||||
children: Vec<AnyElement>,
|
||||
|
||||
variant: ButtonVariant,
|
||||
size: Size,
|
||||
|
||||
disabled: bool,
|
||||
loading: bool,
|
||||
|
||||
rounded: bool,
|
||||
compact: bool,
|
||||
caret: bool,
|
||||
indicator: bool,
|
||||
|
||||
on_click: Option<Rc<dyn Fn(&ClickEvent, &mut Window, &mut App)>>,
|
||||
on_hover: Option<Rc<dyn Fn(&bool, &mut Window, &mut App)>>,
|
||||
|
||||
tab_index: isize,
|
||||
tab_stop: bool,
|
||||
|
||||
|
||||
@@ -255,35 +255,40 @@ fn rows_for(tab: SidebarTab, cx: &App) -> Vec<SidebarRow> {
|
||||
}];
|
||||
}
|
||||
|
||||
let mut rows = vec![SidebarRow::Section {
|
||||
label: "Communities".into(),
|
||||
count: community_count,
|
||||
}];
|
||||
let mut rows = Vec::new();
|
||||
|
||||
rows.extend(
|
||||
communities
|
||||
.into_iter()
|
||||
.map(|community| SidebarRow::Community { community }),
|
||||
);
|
||||
rows.push(SidebarRow::Action {
|
||||
label: "Show all communities".into(),
|
||||
tab: SidebarTab::Communities,
|
||||
});
|
||||
if !communities.is_empty() {
|
||||
rows.push(SidebarRow::Section {
|
||||
label: "Communities".into(),
|
||||
count: community_count,
|
||||
});
|
||||
rows.extend(
|
||||
communities
|
||||
.into_iter()
|
||||
.map(|community| SidebarRow::Community { community }),
|
||||
);
|
||||
rows.push(SidebarRow::Action {
|
||||
label: "Show all communities".into(),
|
||||
tab: SidebarTab::Communities,
|
||||
});
|
||||
}
|
||||
|
||||
rows.push(SidebarRow::Section {
|
||||
label: "Chats".into(),
|
||||
count: rooms.len(),
|
||||
});
|
||||
rows.extend(
|
||||
rooms
|
||||
.into_iter()
|
||||
.take(5)
|
||||
.map(|room| SidebarRow::Room { room }),
|
||||
);
|
||||
rows.push(SidebarRow::Action {
|
||||
label: "Show all chats".into(),
|
||||
tab: SidebarTab::Chats,
|
||||
});
|
||||
if !rooms.is_empty() {
|
||||
rows.push(SidebarRow::Section {
|
||||
label: "Chats".into(),
|
||||
count: rooms.len(),
|
||||
});
|
||||
rows.extend(
|
||||
rooms
|
||||
.into_iter()
|
||||
.take(5)
|
||||
.map(|room| SidebarRow::Room { room }),
|
||||
);
|
||||
rows.push(SidebarRow::Action {
|
||||
label: "Show all chats".into(),
|
||||
tab: SidebarTab::Chats,
|
||||
});
|
||||
}
|
||||
|
||||
rows
|
||||
}
|
||||
@@ -400,6 +405,7 @@ fn render_rows(range: Range<usize>, rows: &[SidebarRow], cx: &Context<Sidebar>)
|
||||
TreeRowKind::Action,
|
||||
label.clone(),
|
||||
)
|
||||
.icon(IconName::ArrowRight)
|
||||
.on_click(cx.listener(move |this, _event, _window, cx| {
|
||||
this.select_tab(tab, cx);
|
||||
}))
|
||||
@@ -590,7 +596,7 @@ impl Render for Sidebar {
|
||||
this.child(
|
||||
div()
|
||||
.absolute()
|
||||
.bottom_12()
|
||||
.bottom_16()
|
||||
.left_0()
|
||||
.h_9()
|
||||
.w_full()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use gpui::prelude::FluentBuilder;
|
||||
use gpui::{App, IntoElement, ParentElement, RenderOnce, Styled, Window, div};
|
||||
use gpui::{App, InteractiveElement, IntoElement, ParentElement, RenderOnce, Styled, Window, div};
|
||||
use theme::ActiveTheme;
|
||||
use ui::button::{Button, ButtonVariants};
|
||||
use ui::{IconName, Selectable, h_flex};
|
||||
@@ -85,29 +85,37 @@ impl RenderOnce for TabBar {
|
||||
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
let Self { active, on_select } = self;
|
||||
|
||||
div().absolute().bottom_2().left_0().w_full().px_2().child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.p_1()
|
||||
.gap_1()
|
||||
.rounded(cx.theme().radius_lg)
|
||||
.bg(cx.theme().elevated_surface_background)
|
||||
.when(cx.theme().shadow, |this| this.shadow_md())
|
||||
.children(SidebarTab::ALL.into_iter().map(|tab| {
|
||||
let on_select = on_select.clone();
|
||||
div()
|
||||
.id("sidebar-tabs")
|
||||
.absolute()
|
||||
.bottom_3()
|
||||
.left_0()
|
||||
.w_full()
|
||||
.px_4()
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.p_1()
|
||||
.gap_1()
|
||||
.rounded_full()
|
||||
.bg(cx.theme().background)
|
||||
.when(cx.theme().shadow, |this| this.shadow_md())
|
||||
.children(SidebarTab::ALL.into_iter().map(|tab| {
|
||||
let on_select = on_select.clone();
|
||||
|
||||
Button::new(format!("tab-{}", tab.list_id()))
|
||||
.icon(tab.icon())
|
||||
.ghost()
|
||||
.flex_1()
|
||||
.selected(tab == active)
|
||||
.tooltip(tab.label())
|
||||
.on_click(move |_event, window, cx| {
|
||||
if let Some(on_select) = on_select.as_ref() {
|
||||
on_select(tab, window, cx);
|
||||
}
|
||||
})
|
||||
})),
|
||||
)
|
||||
Button::new(format!("tab-{}", tab.list_id()))
|
||||
.icon(tab.icon())
|
||||
.ghost()
|
||||
.flex_1()
|
||||
.rounded()
|
||||
.selected(tab == active)
|
||||
.tooltip(tab.label())
|
||||
.on_click(move |_event, window, cx| {
|
||||
if let Some(on_select) = on_select.as_ref() {
|
||||
on_select(tab, window, cx);
|
||||
}
|
||||
})
|
||||
})),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use community::Community;
|
||||
use gpui::prelude::FluentBuilder;
|
||||
use gpui::{
|
||||
App, ClickEvent, ElementId, Entity, ImageSource, InteractiveElement, IntoElement,
|
||||
ParentElement, RenderOnce, SharedString, StatefulInteractiveElement, Styled, Window, div,
|
||||
ParentElement, RenderOnce, SharedString, StatefulInteractiveElement, Styled, Window, div, px,
|
||||
};
|
||||
use settings::AppSettings;
|
||||
use theme::ActiveTheme;
|
||||
@@ -50,6 +50,7 @@ pub struct TreeRow {
|
||||
label: SharedString,
|
||||
avatar: Option<SharedString>,
|
||||
picture: Option<ImageSource>,
|
||||
icon: Option<IconName>,
|
||||
count: Option<usize>,
|
||||
created_at: Option<SharedString>,
|
||||
selected: bool,
|
||||
@@ -69,6 +70,7 @@ impl TreeRow {
|
||||
label: label.into(),
|
||||
avatar: None,
|
||||
picture: None,
|
||||
icon: None,
|
||||
count: None,
|
||||
created_at: None,
|
||||
selected: false,
|
||||
@@ -88,6 +90,12 @@ impl TreeRow {
|
||||
self
|
||||
}
|
||||
|
||||
/// Shows `icon` in the avatar slot when the row has no avatar or picture.
|
||||
pub fn icon(mut self, icon: IconName) -> Self {
|
||||
self.icon = Some(icon);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn count(mut self, count: usize) -> Self {
|
||||
self.count = Some(count);
|
||||
self
|
||||
@@ -150,6 +158,18 @@ impl RenderOnce for TreeRow {
|
||||
}
|
||||
};
|
||||
|
||||
let avatar = avatar.or_else(|| {
|
||||
self.icon.map(|icon| {
|
||||
h_flex()
|
||||
.flex_shrink_0()
|
||||
.w(px(20.))
|
||||
.justify_center()
|
||||
.text_color(cx.theme().icon_muted)
|
||||
.child(Icon::new(icon).small())
|
||||
.into_any_element()
|
||||
})
|
||||
});
|
||||
|
||||
h_flex()
|
||||
.id(self.id)
|
||||
.h_8()
|
||||
@@ -159,14 +179,12 @@ impl RenderOnce for TreeRow {
|
||||
.rounded(cx.theme().radius)
|
||||
.when(is_section, |this| {
|
||||
this.text_xs()
|
||||
.text_color(cx.theme().text_muted)
|
||||
.text_color(cx.theme().text_placeholder)
|
||||
.font_semibold()
|
||||
})
|
||||
.when(is_room || is_community, |this| this.text_sm())
|
||||
.when(is_action, |this| {
|
||||
this.text_sm()
|
||||
.font_medium()
|
||||
.text_color(cx.theme().text_accent)
|
||||
this.text_sm().text_color(cx.theme().text_muted)
|
||||
})
|
||||
.when(is_hint, |this| {
|
||||
this.text_xs()
|
||||
@@ -197,11 +215,11 @@ impl RenderOnce for TreeRow {
|
||||
this.child(div().flex_shrink_0().font_normal().child(count.to_string()))
|
||||
})
|
||||
.when_some(self.created_at, |this, created_at| {
|
||||
this.child(
|
||||
this.child(div().flex_1()).child(
|
||||
div()
|
||||
.flex_shrink_0()
|
||||
.text_xs()
|
||||
.text_color(cx.theme().text_placeholder)
|
||||
.text_xs()
|
||||
.child(created_at),
|
||||
)
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user