Add CollabPanel
component
This commit is contained in:
parent
8814ea8241
commit
4eeed14d34
6 changed files with 271 additions and 3 deletions
|
@ -2,6 +2,7 @@ pub mod assistant_panel;
|
||||||
pub mod breadcrumb;
|
pub mod breadcrumb;
|
||||||
pub mod buffer;
|
pub mod buffer;
|
||||||
pub mod chat_panel;
|
pub mod chat_panel;
|
||||||
|
pub mod collab_panel;
|
||||||
pub mod facepile;
|
pub mod facepile;
|
||||||
pub mod panel;
|
pub mod panel;
|
||||||
pub mod project_panel;
|
pub mod project_panel;
|
||||||
|
|
26
crates/storybook2/src/stories/components/collab_panel.rs
Normal file
26
crates/storybook2/src/stories/components/collab_panel.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use ui::prelude::*;
|
||||||
|
use ui::CollabPanel;
|
||||||
|
|
||||||
|
use crate::story::Story;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct CollabPanelStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> CollabPanelStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, CollabPanel<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(CollabPanel::new(ScrollState::default()))
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,7 @@ pub enum ComponentStory {
|
||||||
Breadcrumb,
|
Breadcrumb,
|
||||||
Buffer,
|
Buffer,
|
||||||
ChatPanel,
|
ChatPanel,
|
||||||
|
CollabPanel,
|
||||||
Facepile,
|
Facepile,
|
||||||
Panel,
|
Panel,
|
||||||
ProjectPanel,
|
ProjectPanel,
|
||||||
|
@ -63,6 +64,7 @@ impl ComponentStory {
|
||||||
Self::Buffer => components::buffer::BufferStory::new().into_any(),
|
Self::Buffer => components::buffer::BufferStory::new().into_any(),
|
||||||
Self::Breadcrumb => components::breadcrumb::BreadcrumbStory::new().into_any(),
|
Self::Breadcrumb => components::breadcrumb::BreadcrumbStory::new().into_any(),
|
||||||
Self::ChatPanel => components::chat_panel::ChatPanelStory::new().into_any(),
|
Self::ChatPanel => components::chat_panel::ChatPanelStory::new().into_any(),
|
||||||
|
Self::CollabPanel => components::collab_panel::CollabPanelStory::new().into_any(),
|
||||||
Self::Facepile => components::facepile::FacepileStory::new().into_any(),
|
Self::Facepile => components::facepile::FacepileStory::new().into_any(),
|
||||||
Self::Panel => components::panel::PanelStory::new().into_any(),
|
Self::Panel => components::panel::PanelStory::new().into_any(),
|
||||||
Self::ProjectPanel => components::project_panel::ProjectPanelStory::new().into_any(),
|
Self::ProjectPanel => components::project_panel::ProjectPanelStory::new().into_any(),
|
||||||
|
|
|
@ -2,6 +2,7 @@ mod assistant_panel;
|
||||||
mod breadcrumb;
|
mod breadcrumb;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod chat_panel;
|
mod chat_panel;
|
||||||
|
mod collab_panel;
|
||||||
mod editor_pane;
|
mod editor_pane;
|
||||||
mod facepile;
|
mod facepile;
|
||||||
mod icon_button;
|
mod icon_button;
|
||||||
|
@ -23,6 +24,7 @@ pub use assistant_panel::*;
|
||||||
pub use breadcrumb::*;
|
pub use breadcrumb::*;
|
||||||
pub use buffer::*;
|
pub use buffer::*;
|
||||||
pub use chat_panel::*;
|
pub use chat_panel::*;
|
||||||
|
pub use collab_panel::*;
|
||||||
pub use editor_pane::*;
|
pub use editor_pane::*;
|
||||||
pub use facepile::*;
|
pub use facepile::*;
|
||||||
pub use icon_button::*;
|
pub use icon_button::*;
|
||||||
|
|
160
crates/ui2/src/components/collab_panel.rs
Normal file
160
crates/ui2/src/components/collab_panel.rs
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use gpui3::{img, svg, ArcCow};
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
use crate::theme::{theme, Theme};
|
||||||
|
use crate::{
|
||||||
|
static_collab_panel_channels, static_collab_panel_current_call, v_stack, Icon, List,
|
||||||
|
ListHeader, ToggleState,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct CollabPanel<S: 'static + Send + Sync + Clone> {
|
||||||
|
view_type: PhantomData<S>,
|
||||||
|
scroll_state: ScrollState,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> CollabPanel<S> {
|
||||||
|
pub fn new(scroll_state: ScrollState) -> Self {
|
||||||
|
Self {
|
||||||
|
view_type: PhantomData,
|
||||||
|
scroll_state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
let theme = theme(cx);
|
||||||
|
|
||||||
|
v_stack()
|
||||||
|
.w_64()
|
||||||
|
.h_full()
|
||||||
|
.fill(theme.middle.base.default.background)
|
||||||
|
.child(
|
||||||
|
v_stack()
|
||||||
|
.w_full()
|
||||||
|
.overflow_y_scroll(self.scroll_state.clone())
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.fill(theme.lowest.base.default.background)
|
||||||
|
.pb_1()
|
||||||
|
.border_color(theme.lowest.base.default.border)
|
||||||
|
.border_b()
|
||||||
|
.child(
|
||||||
|
List::new(static_collab_panel_current_call())
|
||||||
|
.header(
|
||||||
|
ListHeader::new("CRDB")
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.set_toggle(ToggleState::Toggled),
|
||||||
|
)
|
||||||
|
.set_toggle(ToggleState::Toggled),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
v_stack().py_1().child(
|
||||||
|
List::new(static_collab_panel_channels())
|
||||||
|
.header(
|
||||||
|
ListHeader::new("CHANNELS").set_toggle(ToggleState::Toggled),
|
||||||
|
)
|
||||||
|
.empty_message("No channels yet. Add a channel to get started.")
|
||||||
|
.set_toggle(ToggleState::Toggled),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
v_stack().py_1().child(
|
||||||
|
List::new(static_collab_panel_current_call())
|
||||||
|
.header(
|
||||||
|
ListHeader::new("CONTACTS – ONLINE")
|
||||||
|
.set_toggle(ToggleState::Toggled),
|
||||||
|
)
|
||||||
|
.set_toggle(ToggleState::Toggled),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
v_stack().py_1().child(
|
||||||
|
List::new(static_collab_panel_current_call())
|
||||||
|
.header(
|
||||||
|
ListHeader::new("CONTACTS – OFFLINE")
|
||||||
|
.set_toggle(ToggleState::NotToggled),
|
||||||
|
)
|
||||||
|
.set_toggle(ToggleState::NotToggled),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.h_7()
|
||||||
|
.px_2()
|
||||||
|
.border_t()
|
||||||
|
.border_color(theme.middle.variant.default.border)
|
||||||
|
.flex()
|
||||||
|
.items_center()
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.text_sm()
|
||||||
|
.text_color(theme.middle.variant.default.foreground)
|
||||||
|
.child("Find..."),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn list_section_header(
|
||||||
|
&self,
|
||||||
|
label: impl Into<ArcCow<'static, str>>,
|
||||||
|
expanded: bool,
|
||||||
|
theme: &Theme,
|
||||||
|
) -> impl Element<State = S> {
|
||||||
|
div()
|
||||||
|
.h_7()
|
||||||
|
.px_2()
|
||||||
|
.flex()
|
||||||
|
.justify_between()
|
||||||
|
.items_center()
|
||||||
|
.child(div().flex().gap_1().text_sm().child(label.into()))
|
||||||
|
.child(
|
||||||
|
div().flex().h_full().gap_1().items_center().child(
|
||||||
|
svg()
|
||||||
|
.path(if expanded {
|
||||||
|
"icons/caret_down.svg"
|
||||||
|
} else {
|
||||||
|
"icons/caret_up.svg"
|
||||||
|
})
|
||||||
|
.w_3p5()
|
||||||
|
.h_3p5()
|
||||||
|
.fill(theme.middle.variant.default.foreground),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn list_item(
|
||||||
|
&self,
|
||||||
|
avatar_uri: impl Into<ArcCow<'static, str>>,
|
||||||
|
label: impl Into<ArcCow<'static, str>>,
|
||||||
|
theme: &Theme,
|
||||||
|
) -> impl Element<State = S> {
|
||||||
|
div()
|
||||||
|
.h_7()
|
||||||
|
.px_2()
|
||||||
|
.flex()
|
||||||
|
.items_center()
|
||||||
|
// .hover()
|
||||||
|
// .fill(theme.lowest.variant.hovered.background)
|
||||||
|
// .active()
|
||||||
|
// .fill(theme.lowest.variant.pressed.background)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.flex()
|
||||||
|
.items_center()
|
||||||
|
.gap_1()
|
||||||
|
.text_sm()
|
||||||
|
.child(
|
||||||
|
img()
|
||||||
|
.uri(avatar_uri)
|
||||||
|
.size_3p5()
|
||||||
|
.rounded_full()
|
||||||
|
.fill(theme.middle.positive.default.foreground),
|
||||||
|
)
|
||||||
|
.child(label.into()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,9 +5,9 @@ use rand::Rng;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Buffer, BufferRow, BufferRows, Editor, FileSystemStatus, GitStatus, HighlightColor,
|
Buffer, BufferRow, BufferRows, Editor, FileSystemStatus, GitStatus, HighlightColor,
|
||||||
HighlightedLine, HighlightedText, Icon, Label, LabelColor, ListEntry, ListItem, Livestream,
|
HighlightedLine, HighlightedText, Icon, Label, LabelColor, ListEntry, ListEntrySize, ListItem,
|
||||||
MicStatus, Player, PlayerCallStatus, PlayerWithCallStatus, ScreenShareStatus, Symbol, Tab,
|
Livestream, MicStatus, Player, PlayerCallStatus, PlayerWithCallStatus, ScreenShareStatus,
|
||||||
Theme, ToggleState, VideoStatus,
|
Symbol, Tab, Theme, ToggleState, VideoStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn static_tabs_example<S: 'static + Send + Sync + Clone>() -> Vec<Tab<S>> {
|
pub fn static_tabs_example<S: 'static + Send + Sync + Clone>() -> Vec<Tab<S>> {
|
||||||
|
@ -464,6 +464,83 @@ pub fn static_project_panel_single_items<S: 'static + Send + Sync + Clone>() ->
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn static_collab_panel_current_call<S: 'static + Send + Sync + Clone>() -> Vec<ListItem<S>> {
|
||||||
|
vec![
|
||||||
|
ListEntry::new(Label::new("as-cii")).left_avatar("http://github.com/as-cii.png?s=50"),
|
||||||
|
ListEntry::new(Label::new("nathansobo"))
|
||||||
|
.left_avatar("http://github.com/nathansobo.png?s=50"),
|
||||||
|
ListEntry::new(Label::new("maxbrunsfeld"))
|
||||||
|
.left_avatar("http://github.com/maxbrunsfeld.png?s=50"),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.map(From::from)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn static_collab_panel_channels<S: 'static + Send + Sync + Clone>() -> Vec<ListItem<S>> {
|
||||||
|
vec![
|
||||||
|
ListEntry::new(Label::new("zed"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(0),
|
||||||
|
ListEntry::new(Label::new("community"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(1),
|
||||||
|
ListEntry::new(Label::new("dashboards"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
ListEntry::new(Label::new("feedback"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
ListEntry::new(Label::new("teams-in-channels-alpha"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
ListEntry::new(Label::new("current-projects"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(1),
|
||||||
|
ListEntry::new(Label::new("codegen"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
ListEntry::new(Label::new("gpui2"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
ListEntry::new(Label::new("livestreaming"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
ListEntry::new(Label::new("open-source"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
ListEntry::new(Label::new("replace"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
ListEntry::new(Label::new("semantic-index"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
ListEntry::new(Label::new("vim"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
ListEntry::new(Label::new("web-tech"))
|
||||||
|
.left_icon(Icon::Hash.into())
|
||||||
|
.size(ListEntrySize::Medium)
|
||||||
|
.indent_level(2),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.map(From::from)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn empty_editor_example<S: 'static + Send + Sync + Clone>() -> Editor<S> {
|
pub fn empty_editor_example<S: 'static + Send + Sync + Clone>() -> Editor<S> {
|
||||||
Editor {
|
Editor {
|
||||||
tabs: static_tabs_example(),
|
tabs: static_tabs_example(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue