zed2 notification panel (#3603)

Release Notes:

- N/A
This commit is contained in:
Julia 2023-12-12 18:04:47 -05:00 committed by GitHub
commit 2e00da5a79
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 874 additions and 1098 deletions

View file

@ -364,13 +364,7 @@ impl ChatPanel {
if !is_continuation {
result = result.child(
h_stack()
.children(
message
.sender
.avatar
.clone()
.map(|avatar| Avatar::data(avatar)),
)
.child(Avatar::new(message.sender.avatar_uri.clone()))
.child(Label::new(message.sender.github_login.clone()))
.child(Label::new(format_timestamp(
message.timestamp,
@ -659,7 +653,7 @@ mod tests {
timestamp: OffsetDateTime::now_utc(),
sender: Arc::new(client::User {
github_login: "fgh".into(),
avatar: None,
avatar_uri: "avatar_fgh".into(),
id: 103,
}),
nonce: 5,

View file

@ -234,7 +234,7 @@ mod tests {
user: Arc::new(User {
github_login: "a-b".into(),
id: 101,
avatar: None,
avatar_uri: "avatar_a-b".into(),
}),
kind: proto::channel_member::Kind::Member,
role: proto::ChannelRole::Member,
@ -243,7 +243,7 @@ mod tests {
user: Arc::new(User {
github_login: "C_D".into(),
id: 102,
avatar: None,
avatar_uri: "avatar_C_D".into(),
}),
kind: proto::channel_member::Kind::Member,
role: proto::ChannelRole::Member,
@ -275,7 +275,7 @@ mod tests {
cx.update(|cx| {
let http = FakeHttpClient::with_404_response();
let client = Client::new(http.clone(), cx);
let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http, cx));
let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let settings = SettingsStore::test(cx);
cx.set_global(settings);
theme::init(theme::LoadThemes::JustBase, cx);

View file

@ -19,6 +19,7 @@ mod contact_finder;
use contact_finder::ContactFinder;
use menu::{Cancel, Confirm, SelectNext, SelectPrev};
use rpc::proto::{self, PeerId};
use smallvec::SmallVec;
use theme::{ActiveTheme, ThemeSettings};
// use context_menu::{ContextMenu, ContextMenuItem};
// use db::kvp::KEY_VALUE_STORE;
@ -1155,7 +1156,7 @@ impl CollabPanel {
let tooltip = format!("Follow {}", user.github_login);
ListItem::new(SharedString::from(user.github_login.clone()))
.left_child(Avatar::data(user.avatar.clone().unwrap()))
.left_child(Avatar::new(user.avatar_uri.clone()))
.child(
h_stack()
.w_full()
@ -2349,44 +2350,45 @@ impl CollabPanel {
let busy = contact.busy || calling;
let user_id = contact.user.id;
let github_login = SharedString::from(contact.user.github_login.clone());
let mut item = ListItem::new(github_login.clone())
.on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
.child(
h_stack()
.w_full()
.justify_between()
.child(Label::new(github_login.clone()))
.when(calling, |el| {
el.child(Label::new("Calling").color(Color::Muted))
})
.when(!calling, |el| {
el.child(
div()
.id("remove_contact")
.invisible()
.group_hover("", |style| style.visible())
.child(
IconButton::new("remove_contact", Icon::Close)
.icon_color(Color::Muted)
.tooltip(|cx| Tooltip::text("Remove Contact", cx))
.on_click(cx.listener({
let github_login = github_login.clone();
move |this, _, cx| {
this.remove_contact(user_id, &github_login, cx);
}
})),
),
)
}),
)
.left_child(
// todo!() handle contacts with no avatar
Avatar::data(contact.user.avatar.clone().unwrap())
.availability_indicator(if online { Some(!busy) } else { None }),
)
.when(online && !busy, |el| {
el.on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
});
let mut item =
ListItem::new(github_login.clone())
.on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
.child(
h_stack()
.w_full()
.justify_between()
.child(Label::new(github_login.clone()))
.when(calling, |el| {
el.child(Label::new("Calling").color(Color::Muted))
})
.when(!calling, |el| {
el.child(
div()
.id("remove_contact")
.invisible()
.group_hover("", |style| style.visible())
.child(
IconButton::new("remove_contact", Icon::Close)
.icon_color(Color::Muted)
.tooltip(|cx| Tooltip::text("Remove Contact", cx))
.on_click(cx.listener({
let github_login = github_login.clone();
move |this, _, cx| {
this.remove_contact(user_id, &github_login, cx);
}
})),
),
)
}),
)
.left_child(
// todo!() handle contacts with no avatar
Avatar::new(contact.user.avatar_uri.clone())
.availability_indicator(if online { Some(!busy) } else { None }),
)
.when(online && !busy, |el| {
el.on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
});
div()
.id(github_login.clone())
@ -2458,7 +2460,7 @@ impl CollabPanel {
.child(Label::new(github_login.clone()))
.child(h_stack().children(controls)),
)
.when_some(user.avatar.clone(), |el, avatar| el.left_avatar(avatar))
.left_avatar(user.avatar_uri.clone())
}
fn render_contact_placeholder(
@ -2516,7 +2518,9 @@ impl CollabPanel {
let result = FacePile {
faces: participants
.iter()
.filter_map(|user| Some(Avatar::data(user.avatar.clone()?).into_any_element()))
.filter_map(|user| {
Some(Avatar::new(user.avatar_uri.clone()).into_any_element())
})
.take(FACEPILE_LIMIT)
.chain(if extra_count > 0 {
// todo!() @nate - this label looks wrong.
@ -2524,7 +2528,7 @@ impl CollabPanel {
} else {
None
})
.collect::<Vec<_>>(),
.collect::<SmallVec<_>>(),
};
Some(result)

View file

@ -7,7 +7,7 @@ use gpui::{
use picker::{Picker, PickerDelegate};
use std::sync::Arc;
use theme::ActiveTheme as _;
use ui::prelude::*;
use ui::{prelude::*, Avatar};
use util::{ResultExt as _, TryFutureExt};
use workspace::ModalView;
@ -187,7 +187,7 @@ impl PickerDelegate for ContactFinderDelegate {
div()
.flex_1()
.justify_between()
.children(user.avatar.clone().map(|avatar| img(avatar)))
.child(Avatar::new(user.avatar_uri.clone()))
.child(Label::new(user.github_login.clone()))
.children(icon_path.map(|icon_path| svg().path(icon_path))),
)

View file

@ -232,43 +232,41 @@ impl Render for CollabTitlebarItem {
})
.child(h_stack().px_1p5().map(|this| {
if let Some(user) = current_user {
this.when_some(user.avatar.clone(), |this, avatar| {
// TODO: Finish implementing user menu popover
//
this.child(
popover_menu("user-menu")
.menu(|cx| {
ContextMenu::build(cx, |menu, _| menu.header("ADADA"))
})
.trigger(
ButtonLike::new("user-menu")
.child(
h_stack()
.gap_0p5()
.child(Avatar::data(avatar))
.child(
IconElement::new(Icon::ChevronDown)
.color(Color::Muted),
),
)
.style(ButtonStyle::Subtle)
.tooltip(move |cx| {
Tooltip::text("Toggle User Menu", cx)
}),
)
.anchor(gpui::AnchorCorner::TopRight),
)
// this.child(
// ButtonLike::new("user-menu")
// .child(
// h_stack().gap_0p5().child(Avatar::data(avatar)).child(
// IconElement::new(Icon::ChevronDown).color(Color::Muted),
// ),
// )
// .style(ButtonStyle::Subtle)
// .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)),
// )
})
// TODO: Finish implementing user menu popover
//
this.child(
popover_menu("user-menu")
.menu(|cx| {
ContextMenu::build(cx, |menu, _| menu.header("ADADA"))
})
.trigger(
ButtonLike::new("user-menu")
.child(
h_stack()
.gap_0p5()
.child(Avatar::new(user.avatar_uri.clone()))
.child(
IconElement::new(Icon::ChevronDown)
.color(Color::Muted),
),
)
.style(ButtonStyle::Subtle)
.tooltip(move |cx| {
Tooltip::text("Toggle User Menu", cx)
}),
)
.anchor(gpui::AnchorCorner::TopRight),
)
// this.child(
// ButtonLike::new("user-menu")
// .child(
// h_stack().gap_0p5().child(Avatar::data(avatar)).child(
// IconElement::new(Icon::ChevronDown).color(Color::Muted),
// ),
// )
// .style(ButtonStyle::Subtle)
// .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)),
// )
} else {
this.child(Button::new("sign_in", "Sign in").on_click(move |_, cx| {
let client = client.clone();
@ -424,27 +422,21 @@ impl CollabTitlebarItem {
current_user: &Arc<User>,
) -> Option<FacePile> {
let followers = project_id.map_or(&[] as &[_], |id| room.followers_for(peer_id, id));
let mut pile = FacePile::default();
pile.extend(
user.avatar
.clone()
.map(|avatar| {
div()
.child(
Avatar::data(avatar.clone())
.grayscale(!is_present)
.border_color(if is_speaking {
gpui::blue()
} else if is_muted {
gpui::red()
} else {
Hsla::default()
}),
)
.into_any_element()
})
.into_iter()
.chain(followers.iter().filter_map(|follower_peer_id| {
let pile = FacePile::default().child(
div()
.child(
Avatar::new(user.avatar_uri.clone())
.grayscale(!is_present)
.border_color(if is_speaking {
gpui::blue()
} else if is_muted {
gpui::red()
} else {
Hsla::default()
}),
)
.children(followers.iter().filter_map(|follower_peer_id| {
let follower = room
.remote_participants()
.values()
@ -454,12 +446,11 @@ impl CollabTitlebarItem {
.then_some(current_user)
})?
.clone();
follower
.avatar
.clone()
.map(|avatar| div().child(Avatar::data(avatar.clone())).into_any_element())
Some(div().child(Avatar::new(follower.avatar_uri.clone())))
})),
);
Some(pile)
}

View file

@ -39,6 +39,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
collab_panel::init(cx);
channel_view::init(cx);
chat_panel::init(cx);
notification_panel::init(cx);
notifications::init(&app_state, cx);
// cx.add_global_action(toggle_screen_sharing);

View file

@ -1,11 +1,11 @@
use gpui::{
div, AnyElement, Div, ElementId, IntoElement, ParentElement as _, RenderOnce, Styled,
WindowContext,
div, AnyElement, Div, ElementId, IntoElement, ParentElement, RenderOnce, Styled, WindowContext,
};
use smallvec::SmallVec;
#[derive(Default, IntoElement)]
pub struct FacePile {
pub faces: Vec<AnyElement>,
pub faces: SmallVec<[AnyElement; 2]>,
}
impl RenderOnce for FacePile {
@ -25,8 +25,8 @@ impl RenderOnce for FacePile {
}
}
impl Extend<AnyElement> for FacePile {
fn extend<T: IntoIterator<Item = AnyElement>>(&mut self, children: T) {
self.faces.extend(children);
impl ParentElement for FacePile {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> {
&mut self.faces
}
}

File diff suppressed because it is too large Load diff

View file

@ -114,14 +114,7 @@ impl IncomingCallNotification {
}
fn render_caller(&self, cx: &mut ViewContext<Self>) -> impl Element {
h_stack()
.children(
self.state
.call
.calling_user
.avatar
.as_ref()
.map(|avatar| Avatar::data(avatar.clone())),
)
.child(Avatar::new(self.state.call.calling_user.avatar_uri.clone()))
.child(
v_stack()
.child(Label::new(format!(

View file

@ -119,12 +119,7 @@ impl ProjectSharedNotification {
fn render_owner(&self) -> impl Element {
h_stack()
.children(
self.owner
.avatar
.clone()
.map(|avatar| Avatar::data(avatar.clone())),
)
.child(Avatar::new(self.owner.avatar_uri.clone()))
.child(
v_stack()
.child(Label::new(self.owner.github_login.clone()))