Style collab panel (#3638)
This PR styles the collab panel. Release Notes: - N/A --------- Co-authored-by: Nate Butler <iamnbutler@gmail.com> Co-authored-by: Marshall Bowers <1486634+maxdeviant@users.noreply.github.com>
This commit is contained in:
parent
1ad1cc1148
commit
d59de96921
4 changed files with 167 additions and 136 deletions
|
@ -176,11 +176,11 @@ use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt};
|
|||
use fuzzy::{match_strings, StringMatchCandidate};
|
||||
use gpui::{
|
||||
actions, canvas, div, img, impl_actions, overlay, point, prelude::*, px, rems, serde_json,
|
||||
size, Action, AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div,
|
||||
EventEmitter, FocusHandle, Focusable, FocusableView, Hsla, InteractiveElement, IntoElement,
|
||||
Length, Model, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Quad, Render,
|
||||
RenderOnce, ScrollHandle, SharedString, Size, Stateful, Styled, Subscription, Task, View,
|
||||
ViewContext, VisualContext, WeakView,
|
||||
size, Action, AnyElement, AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent,
|
||||
Div, EventEmitter, FocusHandle, Focusable, FocusableView, Hsla, InteractiveElement,
|
||||
IntoElement, Length, Model, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Quad,
|
||||
Render, RenderOnce, ScrollHandle, SharedString, Size, Stateful, Styled, Subscription, Task,
|
||||
View, ViewContext, VisualContext, WeakView,
|
||||
};
|
||||
use project::{Fs, Project};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
@ -402,7 +402,7 @@ impl CollabPanel {
|
|||
|
||||
let filter_editor = cx.build_view(|cx| {
|
||||
let mut editor = Editor::single_line(cx);
|
||||
editor.set_placeholder_text("Filter channels, contacts", cx);
|
||||
editor.set_placeholder_text("Filter...", cx);
|
||||
editor
|
||||
});
|
||||
|
||||
|
@ -1157,24 +1157,20 @@ impl CollabPanel {
|
|||
|
||||
ListItem::new(SharedString::from(user.github_login.clone()))
|
||||
.start_slot(Avatar::new(user.avatar_uri.clone()))
|
||||
.child(
|
||||
h_stack()
|
||||
.w_full()
|
||||
.justify_between()
|
||||
.child(Label::new(user.github_login.clone()))
|
||||
.child(if is_pending {
|
||||
Label::new("Calling").color(Color::Muted).into_any_element()
|
||||
} else if is_current_user {
|
||||
IconButton::new("leave-call", Icon::ArrowRight)
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
Self::leave_call(cx);
|
||||
}))
|
||||
.tooltip(|cx| Tooltip::text("Leave Call", cx))
|
||||
.into_any_element()
|
||||
} else {
|
||||
div().into_any_element()
|
||||
}),
|
||||
)
|
||||
.child(Label::new(user.github_login.clone()))
|
||||
.end_slot(if is_pending {
|
||||
Label::new("Calling").color(Color::Muted).into_any_element()
|
||||
} else if is_current_user {
|
||||
IconButton::new("leave-call", Icon::Exit)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
Self::leave_call(cx);
|
||||
}))
|
||||
.tooltip(|cx| Tooltip::text("Leave Call", cx))
|
||||
.into_any_element()
|
||||
} else {
|
||||
div().into_any_element()
|
||||
})
|
||||
.when_some(peer_id, |this, peer_id| {
|
||||
this.tooltip(move |cx| Tooltip::text(tooltip.clone(), cx))
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
|
@ -1212,8 +1208,12 @@ impl CollabPanel {
|
|||
.detach_and_log_err(cx);
|
||||
});
|
||||
}))
|
||||
.start_slot(render_tree_branch(is_last, cx))
|
||||
.child(IconButton::new(0, Icon::Folder))
|
||||
.start_slot(
|
||||
h_stack()
|
||||
.gap_1()
|
||||
.child(render_tree_branch(is_last, cx))
|
||||
.child(IconButton::new(0, Icon::Folder)),
|
||||
)
|
||||
.child(Label::new(project_name.clone()))
|
||||
.tooltip(move |cx| Tooltip::text(format!("Open {}", project_name), cx))
|
||||
|
||||
|
@ -1305,8 +1305,12 @@ impl CollabPanel {
|
|||
let id = peer_id.map_or(usize::MAX, |id| id.as_u64() as usize);
|
||||
|
||||
ListItem::new(("screen", id))
|
||||
.start_slot(render_tree_branch(is_last, cx))
|
||||
.child(IconButton::new(0, Icon::Screen))
|
||||
.start_slot(
|
||||
h_stack()
|
||||
.gap_1()
|
||||
.child(render_tree_branch(is_last, cx))
|
||||
.child(IconButton::new(0, Icon::Screen)),
|
||||
)
|
||||
.child(Label::new("Screen"))
|
||||
.when_some(peer_id, |this, _| {
|
||||
this.on_click(cx.listener(move |this, _, cx| {
|
||||
|
@ -1372,9 +1376,13 @@ impl CollabPanel {
|
|||
.on_click(cx.listener(move |this, _, cx| {
|
||||
this.open_channel_notes(channel_id, cx);
|
||||
}))
|
||||
.start_slot(render_tree_branch(false, cx))
|
||||
.child(IconButton::new(0, Icon::File))
|
||||
.child(Label::new("notes"))
|
||||
.start_slot(
|
||||
h_stack()
|
||||
.gap_1()
|
||||
.child(render_tree_branch(false, cx))
|
||||
.child(IconButton::new(0, Icon::File)),
|
||||
)
|
||||
.child(div().h_7().w_full().child(Label::new("notes")))
|
||||
.tooltip(move |cx| Tooltip::text("Open Channel Notes", cx))
|
||||
}
|
||||
|
||||
|
@ -1387,8 +1395,12 @@ impl CollabPanel {
|
|||
.on_click(cx.listener(move |this, _, cx| {
|
||||
this.join_channel_chat(channel_id, cx);
|
||||
}))
|
||||
.start_slot(render_tree_branch(true, cx))
|
||||
.child(IconButton::new(0, Icon::MessageBubbles))
|
||||
.start_slot(
|
||||
h_stack()
|
||||
.gap_1()
|
||||
.child(render_tree_branch(false, cx))
|
||||
.child(IconButton::new(0, Icon::MessageBubbles)),
|
||||
)
|
||||
.child(Label::new("chat"))
|
||||
.tooltip(move |cx| Tooltip::text("Open Chat", cx))
|
||||
}
|
||||
|
@ -2149,11 +2161,6 @@ impl CollabPanel {
|
|||
fn render_signed_in(&mut self, cx: &mut ViewContext<Self>) -> Div {
|
||||
v_stack()
|
||||
.size_full()
|
||||
.child(
|
||||
div()
|
||||
.p_2()
|
||||
.child(div().rounded(px(2.0)).child(self.filter_editor.clone())),
|
||||
)
|
||||
.child(
|
||||
v_stack()
|
||||
.size_full()
|
||||
|
@ -2223,6 +2230,14 @@ impl CollabPanel {
|
|||
}
|
||||
})),
|
||||
)
|
||||
.child(
|
||||
div().p_2().child(
|
||||
div()
|
||||
.border_primary(cx)
|
||||
.border_t()
|
||||
.child(self.filter_editor.clone()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn render_header(
|
||||
|
@ -2274,22 +2289,32 @@ impl CollabPanel {
|
|||
let button = match section {
|
||||
Section::ActiveCall => channel_link.map(|channel_link| {
|
||||
let channel_link_copy = channel_link.clone();
|
||||
IconButton::new("channel-link", Icon::Copy)
|
||||
.on_click(move |_, cx| {
|
||||
let item = ClipboardItem::new(channel_link_copy.clone());
|
||||
cx.write_to_clipboard(item)
|
||||
})
|
||||
.tooltip(|cx| Tooltip::text("Copy channel link", cx))
|
||||
div()
|
||||
.invisible()
|
||||
.group_hover("section-header", |this| this.visible())
|
||||
.child(
|
||||
IconButton::new("channel-link", Icon::Copy)
|
||||
.icon_size(IconSize::Small)
|
||||
.size(ButtonSize::None)
|
||||
.on_click(move |_, cx| {
|
||||
let item = ClipboardItem::new(channel_link_copy.clone());
|
||||
cx.write_to_clipboard(item)
|
||||
})
|
||||
.tooltip(|cx| Tooltip::text("Copy channel link", cx)),
|
||||
)
|
||||
.into_any_element()
|
||||
}),
|
||||
Section::Contacts => Some(
|
||||
IconButton::new("add-contact", Icon::Plus)
|
||||
.on_click(cx.listener(|this, _, cx| this.toggle_contact_finder(cx)))
|
||||
.tooltip(|cx| Tooltip::text("Search for new contact", cx)),
|
||||
.tooltip(|cx| Tooltip::text("Search for new contact", cx))
|
||||
.into_any_element(),
|
||||
),
|
||||
Section::Channels => Some(
|
||||
IconButton::new("add-channel", Icon::Plus)
|
||||
.on_click(cx.listener(|this, _, cx| this.new_root_channel(cx)))
|
||||
.tooltip(|cx| Tooltip::text("Create a channel", cx)),
|
||||
.tooltip(|cx| Tooltip::text("Create a channel", cx))
|
||||
.into_any_element(),
|
||||
),
|
||||
_ => None,
|
||||
};
|
||||
|
@ -2304,25 +2329,18 @@ impl CollabPanel {
|
|||
|
||||
h_stack()
|
||||
.w_full()
|
||||
.map(|el| {
|
||||
if can_collapse {
|
||||
el.child(
|
||||
ListItem::new(text.clone())
|
||||
.child(div().w_full().child(Label::new(text)))
|
||||
.selected(is_selected)
|
||||
.toggle(Some(!is_collapsed))
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
this.toggle_section_expanded(section, cx)
|
||||
})),
|
||||
)
|
||||
} else {
|
||||
el.child(
|
||||
ListHeader::new(text)
|
||||
.when_some(button, |el, button| el.end_slot(button))
|
||||
.selected(is_selected),
|
||||
)
|
||||
}
|
||||
})
|
||||
.group("section-header")
|
||||
.child(
|
||||
ListHeader::new(text)
|
||||
.toggle(if can_collapse {
|
||||
Some(!is_collapsed)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.inset(true)
|
||||
.end_slot::<AnyElement>(button)
|
||||
.selected(is_selected),
|
||||
)
|
||||
.when(section == Section::Channels, |el| {
|
||||
el.drag_over::<DraggedChannelView>(|style| {
|
||||
style.bg(cx.theme().colors().ghost_element_hover)
|
||||
|
@ -2460,7 +2478,7 @@ impl CollabPanel {
|
|||
.child(Label::new(github_login.clone()))
|
||||
.child(h_stack().children(controls)),
|
||||
)
|
||||
.start_slot::<Avatar>(user.avatar_uri.clone().map(|avatar| Avatar::new(avatar)))
|
||||
.start_slot(Avatar::new(user.avatar_uri.clone()))
|
||||
}
|
||||
|
||||
fn render_contact_placeholder(
|
||||
|
@ -2541,6 +2559,8 @@ impl CollabPanel {
|
|||
div()
|
||||
.id(channel_id as usize)
|
||||
.group("")
|
||||
.flex()
|
||||
.w_full()
|
||||
.on_drag({
|
||||
let channel = channel.clone();
|
||||
move |cx| {
|
||||
|
@ -2566,71 +2586,10 @@ impl CollabPanel {
|
|||
)
|
||||
.child(
|
||||
ListItem::new(channel_id as usize)
|
||||
.indent_level(depth)
|
||||
// Offset the indent depth by one to give us room to show the disclosure.
|
||||
.indent_level(depth + 1)
|
||||
.indent_step_size(cx.rem_size() * 14.0 / 16.0) // @todo()! @nate this is to step over the disclosure toggle
|
||||
.start_slot(
|
||||
IconElement::new(if is_public { Icon::Public } else { Icon::Hash })
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.selected(is_selected || is_active)
|
||||
.child(
|
||||
h_stack()
|
||||
.w_full()
|
||||
.justify_between()
|
||||
.child(
|
||||
h_stack()
|
||||
.id(channel_id as usize)
|
||||
.child(Label::new(channel.name.clone()))
|
||||
.children(face_pile.map(|face_pile| face_pile.render(cx))),
|
||||
)
|
||||
.child(
|
||||
h_stack()
|
||||
.child(
|
||||
div()
|
||||
.id("channel_chat")
|
||||
.when(!has_messages_notification, |el| el.invisible())
|
||||
.group_hover("", |style| style.visible())
|
||||
.child(
|
||||
IconButton::new(
|
||||
"channel_chat",
|
||||
Icon::MessageBubbles,
|
||||
)
|
||||
.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)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.id("channel_notes")
|
||||
.when(!has_notes_notification, |el| el.invisible())
|
||||
.group_hover("", |style| style.visible())
|
||||
.child(
|
||||
IconButton::new("channel_notes", Icon::File)
|
||||
.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)
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toggle(disclosed)
|
||||
.on_toggle(
|
||||
cx.listener(move |this, _, cx| {
|
||||
|
@ -2650,7 +2609,57 @@ impl CollabPanel {
|
|||
move |this, event: &MouseDownEvent, cx| {
|
||||
this.deploy_channel_context_menu(event.position, channel_id, ix, cx)
|
||||
},
|
||||
)),
|
||||
))
|
||||
.start_slot(
|
||||
IconElement::new(if is_public { Icon::Public } else { Icon::Hash })
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(
|
||||
h_stack()
|
||||
.id(channel_id as usize)
|
||||
.child(Label::new(channel.name.clone()))
|
||||
.children(face_pile.map(|face_pile| face_pile.render(cx))),
|
||||
)
|
||||
.end_slot(
|
||||
h_stack()
|
||||
.child(
|
||||
div()
|
||||
.id("channel_chat")
|
||||
.when(!has_messages_notification, |el| el.invisible())
|
||||
.group_hover("", |style| style.visible())
|
||||
.child(
|
||||
IconButton::new("channel_chat", Icon::MessageBubbles)
|
||||
.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)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.id("channel_notes")
|
||||
.when(!has_notes_notification, |el| el.invisible())
|
||||
.group_hover("", |style| style.visible())
|
||||
.child(
|
||||
IconButton::new("channel_notes", Icon::File)
|
||||
.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)),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.tooltip(|cx| Tooltip::text("Join channel", cx))
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{prelude::*, Color, Icon, IconButton, IconSize};
|
||||
use gpui::ClickEvent;
|
||||
|
||||
use crate::{prelude::*, Color, Icon, IconButton, IconSize};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct Disclosure {
|
||||
is_open: bool,
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use crate::{prelude::*, Disclosure};
|
||||
use gpui::{
|
||||
px, AnyElement, AnyView, ClickEvent, Div, MouseButton, MouseDownEvent, Pixels, Stateful,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{prelude::*, Disclosure};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct ListItem {
|
||||
id: ElementId,
|
||||
|
@ -192,10 +193,15 @@ impl RenderOnce for ListItem {
|
|||
this.ml(self.indent_level as f32 * self.indent_step_size)
|
||||
}
|
||||
})
|
||||
.children(
|
||||
self.toggle
|
||||
.map(|is_open| Disclosure::new(is_open).on_toggle(self.on_toggle)),
|
||||
)
|
||||
.children(self.toggle.map(|is_open| {
|
||||
div()
|
||||
.flex()
|
||||
.absolute()
|
||||
.left(rems(-1.))
|
||||
.invisible()
|
||||
.group_hover("", |style| style.visible())
|
||||
.child(Disclosure::new(is_open).on_toggle(self.on_toggle))
|
||||
}))
|
||||
.child(
|
||||
h_stack()
|
||||
.flex_1()
|
||||
|
|
15
script/storybook
Executable file
15
script/storybook
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
# This script takes a single text input and replaces 'list_item' with the input in a cargo run command
|
||||
|
||||
# Check if an argument is provided
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <component_name>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Assign the argument to a variable
|
||||
COMPONENT_NAME="$1"
|
||||
|
||||
# Run the cargo command with the provided component name
|
||||
cargo run -p storybook2 -- components/"$COMPONENT_NAME"
|
Loading…
Add table
Add a link
Reference in a new issue