Start work on rendering channel participants in collab panel
Co-authored-by: mikayla <mikayla@zed.dev>
This commit is contained in:
parent
a9de73739a
commit
fca8cdcb8e
9 changed files with 192 additions and 60 deletions
|
@ -7,34 +7,34 @@ use gpui::{
|
|||
},
|
||||
json::ToJson,
|
||||
serde_json::{self, json},
|
||||
AnyElement, Axis, Element, LayoutContext, SceneBuilder, ViewContext,
|
||||
AnyElement, Axis, Element, LayoutContext, SceneBuilder, View, ViewContext,
|
||||
};
|
||||
|
||||
use crate::CollabTitlebarItem;
|
||||
|
||||
pub(crate) struct FacePile {
|
||||
pub(crate) struct FacePile<V: View> {
|
||||
overlap: f32,
|
||||
faces: Vec<AnyElement<CollabTitlebarItem>>,
|
||||
faces: Vec<AnyElement<V>>,
|
||||
}
|
||||
|
||||
impl FacePile {
|
||||
pub fn new(overlap: f32) -> FacePile {
|
||||
FacePile {
|
||||
impl<V: View> FacePile<V> {
|
||||
pub fn new(overlap: f32) -> Self {
|
||||
Self {
|
||||
overlap,
|
||||
faces: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Element<CollabTitlebarItem> for FacePile {
|
||||
impl<V: View> Element<V> for FacePile<V> {
|
||||
type LayoutState = ();
|
||||
type PaintState = ();
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: gpui::SizeConstraint,
|
||||
view: &mut CollabTitlebarItem,
|
||||
cx: &mut LayoutContext<CollabTitlebarItem>,
|
||||
view: &mut V,
|
||||
cx: &mut LayoutContext<V>,
|
||||
) -> (Vector2F, Self::LayoutState) {
|
||||
debug_assert!(constraint.max_along(Axis::Horizontal) == f32::INFINITY);
|
||||
|
||||
|
@ -53,8 +53,8 @@ impl Element<CollabTitlebarItem> for FacePile {
|
|||
bounds: RectF,
|
||||
visible_bounds: RectF,
|
||||
_layout: &mut Self::LayoutState,
|
||||
view: &mut CollabTitlebarItem,
|
||||
cx: &mut ViewContext<CollabTitlebarItem>,
|
||||
view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Self::PaintState {
|
||||
let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
|
||||
|
||||
|
@ -80,8 +80,8 @@ impl Element<CollabTitlebarItem> for FacePile {
|
|||
_: RectF,
|
||||
_: &Self::LayoutState,
|
||||
_: &Self::PaintState,
|
||||
_: &CollabTitlebarItem,
|
||||
_: &ViewContext<CollabTitlebarItem>,
|
||||
_: &V,
|
||||
_: &ViewContext<V>,
|
||||
) -> Option<RectF> {
|
||||
None
|
||||
}
|
||||
|
@ -91,8 +91,8 @@ impl Element<CollabTitlebarItem> for FacePile {
|
|||
bounds: RectF,
|
||||
_: &Self::LayoutState,
|
||||
_: &Self::PaintState,
|
||||
_: &CollabTitlebarItem,
|
||||
_: &ViewContext<CollabTitlebarItem>,
|
||||
_: &V,
|
||||
_: &ViewContext<V>,
|
||||
) -> serde_json::Value {
|
||||
json!({
|
||||
"type": "FacePile",
|
||||
|
@ -101,8 +101,8 @@ impl Element<CollabTitlebarItem> for FacePile {
|
|||
}
|
||||
}
|
||||
|
||||
impl Extend<AnyElement<CollabTitlebarItem>> for FacePile {
|
||||
fn extend<T: IntoIterator<Item = AnyElement<CollabTitlebarItem>>>(&mut self, children: T) {
|
||||
impl<V: View> Extend<AnyElement<V>> for FacePile<V> {
|
||||
fn extend<T: IntoIterator<Item = AnyElement<V>>>(&mut self, children: T) {
|
||||
self.faces.extend(children);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,8 @@ use workspace::{
|
|||
Workspace,
|
||||
};
|
||||
|
||||
use crate::face_pile::FacePile;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
struct RemoveChannel {
|
||||
channel_id: u64,
|
||||
|
@ -253,7 +255,7 @@ impl CollabPanel {
|
|||
)
|
||||
}
|
||||
ListEntry::Channel(channel) => {
|
||||
Self::render_channel(&*channel, &theme.collab_panel, is_selected, cx)
|
||||
this.render_channel(&*channel, &theme.collab_panel, is_selected, cx)
|
||||
}
|
||||
ListEntry::ChannelInvite(channel) => Self::render_channel_invite(
|
||||
channel.clone(),
|
||||
|
@ -1265,20 +1267,16 @@ impl CollabPanel {
|
|||
}
|
||||
|
||||
fn render_channel(
|
||||
&self,
|
||||
channel: &Channel,
|
||||
theme: &theme::CollabPanel,
|
||||
is_selected: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> AnyElement<Self> {
|
||||
let channel_id = channel.id;
|
||||
MouseEventHandler::<Channel, Self>::new(channel.id as usize, cx, |state, _cx| {
|
||||
MouseEventHandler::<Channel, Self>::new(channel.id as usize, cx, |state, cx| {
|
||||
Flex::row()
|
||||
.with_child({
|
||||
Svg::new("icons/file_icons/hash.svg")
|
||||
// .with_style(theme.contact_avatar)
|
||||
.aligned()
|
||||
.left()
|
||||
})
|
||||
.with_child({ Svg::new("icons/file_icons/hash.svg").aligned().left() })
|
||||
.with_child(
|
||||
Label::new(channel.name.clone(), theme.contact_username.text.clone())
|
||||
.contained()
|
||||
|
@ -1287,6 +1285,20 @@ impl CollabPanel {
|
|||
.left()
|
||||
.flex(1., true),
|
||||
)
|
||||
.with_child(
|
||||
FacePile::new(theme.face_overlap).with_children(
|
||||
self.channel_store
|
||||
.read(cx)
|
||||
.channel_participants(channel_id)
|
||||
.iter()
|
||||
.filter_map(|user| {
|
||||
Some(
|
||||
Image::from_data(user.avatar.clone()?)
|
||||
.with_style(theme.contact_avatar),
|
||||
)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.constrained()
|
||||
.with_height(theme.row_height)
|
||||
.contained()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue