Detailed changes
@@ -23,7 +23,7 @@ pub struct IncomingCall {
pub room_id: u64,
pub caller: Arc<User>,
pub participants: Vec<Arc<User>>,
- pub initial_project_id: Option<u64>,
+ pub initial_project: Option<proto::ParticipantProject>,
}
pub struct ActiveCall {
@@ -78,7 +78,7 @@ impl ActiveCall {
user_store.get_user(envelope.payload.caller_user_id, cx)
})
.await?,
- initial_project_id: envelope.payload.initial_project_id,
+ initial_project: envelope.payload.initial_project,
};
this.update(&mut cx, |this, _| {
*this.incoming_call.0.borrow_mut() = Some(call);
@@ -541,13 +541,15 @@ async fn test_share_project(
deterministic.run_until_parked();
let call = incoming_call_b.borrow().clone().unwrap();
assert_eq!(call.caller.github_login, "user_a");
- let project_id = call.initial_project_id.unwrap();
+ let initial_project = call.initial_project.unwrap();
active_call_b
.update(cx_b, |call, cx| call.accept_incoming(cx))
.await
.unwrap();
let client_b_peer_id = client_b.peer_id;
- let project_b = client_b.build_remote_project(project_id, cx_b).await;
+ let project_b = client_b
+ .build_remote_project(initial_project.id, cx_b)
+ .await;
let replica_id_b = project_b.read_with(cx_b, |project, _| project.replica_id());
deterministic.run_until_parked();
@@ -176,9 +176,9 @@ impl Store {
.iter()
.map(|participant| participant.user_id)
.collect(),
- initial_project_id: active_call
+ initial_project: active_call
.initial_project_id
- .map(|project_id| project_id.to_proto()),
+ .and_then(|id| Self::build_participant_project(id, &self.projects)),
})
}
} else {
@@ -572,7 +572,8 @@ impl Store {
.iter()
.map(|participant| participant.user_id)
.collect(),
- initial_project_id: initial_project_id.map(|project_id| project_id.to_proto()),
+ initial_project: initial_project_id
+ .and_then(|id| Self::build_participant_project(id, &self.projects)),
},
))
}
@@ -726,14 +727,6 @@ impl Store {
.iter_mut()
.find(|participant| participant.peer_id == host_connection_id.0)
.ok_or_else(|| anyhow!("no such room"))?;
- participant.projects.push(proto::ParticipantProject {
- id: project_id.to_proto(),
- worktree_root_names: worktrees
- .iter()
- .filter(|worktree| worktree.visible)
- .map(|worktree| worktree.root_name.clone())
- .collect(),
- });
connection.projects.insert(project_id);
self.projects.insert(
@@ -767,6 +760,10 @@ impl Store {
},
);
+ participant
+ .projects
+ .extend(Self::build_participant_project(project_id, &self.projects));
+
Ok(room)
}
@@ -1011,6 +1008,22 @@ impl Store {
Ok(connection_ids)
}
+ fn build_participant_project(
+ project_id: ProjectId,
+ projects: &BTreeMap<ProjectId, Project>,
+ ) -> Option<proto::ParticipantProject> {
+ Some(proto::ParticipantProject {
+ id: project_id.to_proto(),
+ worktree_root_names: projects
+ .get(&project_id)?
+ .worktrees
+ .values()
+ .filter(|worktree| worktree.visible)
+ .map(|worktree| worktree.root_name.clone())
+ .collect(),
+ })
+ }
+
pub fn project_connection_ids(
&self,
project_id: ProjectId,
@@ -1,4 +1,5 @@
use call::{ActiveCall, IncomingCall};
+use client::proto;
use futures::StreamExt;
use gpui::{
elements::*,
@@ -26,7 +27,11 @@ pub fn init(cx: &mut MutableAppContext) {
if let Some(incoming_call) = incoming_call {
const PADDING: f32 = 16.;
let screen_size = cx.platform().screen_size();
- let window_size = vec2f(274., 64.);
+
+ let window_size = cx.read(|cx| {
+ let theme = &cx.global::<Settings>().theme.incoming_call_notification;
+ vec2f(theme.window_width, theme.window_height)
+ });
let (window_id, _) = cx.add_window(
WindowOptions {
bounds: WindowBounds::Fixed(RectF::new(
@@ -66,7 +71,7 @@ impl IncomingCallNotification {
if action.accept {
let join = active_call.update(cx, |active_call, cx| active_call.accept_incoming(cx));
let caller_user_id = self.call.caller.id;
- let initial_project_id = self.call.initial_project_id;
+ let initial_project_id = self.call.initial_project.as_ref().map(|project| project.id);
cx.spawn_weak(|_, mut cx| async move {
join.await?;
if let Some(project_id) = initial_project_id {
@@ -89,6 +94,12 @@ impl IncomingCallNotification {
fn render_caller(&self, cx: &mut RenderContext<Self>) -> ElementBox {
let theme = &cx.global::<Settings>().theme.incoming_call_notification;
+ let default_project = proto::ParticipantProject::default();
+ let initial_project = self
+ .call
+ .initial_project
+ .as_ref()
+ .unwrap_or(&default_project);
Flex::row()
.with_children(self.call.caller.avatar.clone().map(|avatar| {
Image::new(avatar)
@@ -108,11 +119,34 @@ impl IncomingCallNotification {
.boxed(),
)
.with_child(
- Label::new("is calling you".into(), theme.caller_message.text.clone())
+ Label::new(
+ format!(
+ "is sharing a project in Zed{}",
+ if initial_project.worktree_root_names.is_empty() {
+ ""
+ } else {
+ ":"
+ }
+ ),
+ theme.caller_message.text.clone(),
+ )
+ .contained()
+ .with_style(theme.caller_message.container)
+ .boxed(),
+ )
+ .with_children(if initial_project.worktree_root_names.is_empty() {
+ None
+ } else {
+ Some(
+ Label::new(
+ initial_project.worktree_root_names.join(", "),
+ theme.worktree_roots.text.clone(),
+ )
.contained()
- .with_style(theme.caller_message.container)
+ .with_style(theme.worktree_roots.container)
.boxed(),
- )
+ )
+ })
.contained()
.with_style(theme.caller_metadata)
.aligned()
@@ -195,7 +195,7 @@ message IncomingCall {
uint64 room_id = 1;
uint64 caller_user_id = 2;
repeated uint64 participant_user_ids = 3;
- optional uint64 initial_project_id = 4;
+ optional ParticipantProject initial_project = 4;
}
message CallCanceled {}
@@ -488,6 +488,8 @@ pub struct ProjectSharedNotification {
#[derive(Deserialize, Default)]
pub struct IncomingCallNotification {
+ pub window_height: f32,
+ pub window_width: f32,
#[serde(default)]
pub background: Color,
pub caller_container: ContainerStyle,
@@ -495,6 +497,7 @@ pub struct IncomingCallNotification {
pub caller_metadata: ContainerStyle,
pub caller_username: ContainedText,
pub caller_message: ContainedText,
+ pub worktree_roots: ContainedText,
pub button_width: f32,
pub accept_button: ContainedText,
pub decline_button: ContainedText,
@@ -4,6 +4,8 @@ import { backgroundColor, borderColor, text } from "./components";
export default function incomingCallNotification(theme: Theme): Object {
const avatarSize = 32;
return {
+ windowHeight: 74,
+ windowWidth: 380,
background: backgroundColor(theme, 300),
callerContainer: {
padding: 12,
@@ -24,6 +26,10 @@ export default function incomingCallNotification(theme: Theme): Object {
...text(theme, "sans", "secondary", { size: "xs" }),
margin: { top: -3 },
},
+ worktreeRoots: {
+ ...text(theme, "sans", "secondary", { size: "xs", weight: "bold" }),
+ margin: { top: -3 },
+ },
buttonWidth: 96,
acceptButton: {
background: backgroundColor(theme, "ok", "active"),
@@ -4,7 +4,7 @@ import { backgroundColor, borderColor, text } from "./components";
export default function projectSharedNotification(theme: Theme): Object {
const avatarSize = 48;
return {
- windowHeight: 72,
+ windowHeight: 74,
windowWidth: 380,
background: backgroundColor(theme, 300),
ownerContainer: {