From 46b61feb9aad46bfc8ddd35e2d52d30c9e4bb361 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 28 Sep 2022 19:35:24 +0200 Subject: [PATCH] Open popup window when receiving a call We still need to style and allow people to accept the call but this is a good starting point. Co-Authored-By: Nathan Sobo --- crates/collab_ui/src/collab_ui.rs | 80 ++++++++++++++++++++++++++++++- crates/gpui/src/app.rs | 4 ++ crates/zed/src/main.rs | 2 +- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/crates/collab_ui/src/collab_ui.rs b/crates/collab_ui/src/collab_ui.rs index 312c7478e2..d3f12fdf6f 100644 --- a/crates/collab_ui/src/collab_ui.rs +++ b/crates/collab_ui/src/collab_ui.rs @@ -1,10 +1,86 @@ mod collab_titlebar_item; mod contacts_popover; +use client::{call::Call, UserStore}; pub use collab_titlebar_item::CollabTitlebarItem; -use gpui::MutableAppContext; +use futures::StreamExt; +use gpui::{ + elements::*, + geometry::{rect::RectF, vector::vec2f}, + Entity, ModelHandle, MutableAppContext, View, WindowBounds, WindowKind, WindowOptions, +}; +use settings::Settings; -pub fn init(cx: &mut MutableAppContext) { +pub fn init(user_store: ModelHandle, cx: &mut MutableAppContext) { contacts_popover::init(cx); collab_titlebar_item::init(cx); + + let mut incoming_call = user_store.read(cx).incoming_call(); + cx.spawn(|mut cx| async move { + let mut notification_window = None; + while let Some(incoming_call) = incoming_call.next().await { + if let Some(window_id) = notification_window.take() { + cx.remove_window(window_id); + } + + if let Some(incoming_call) = incoming_call { + let (window_id, _) = cx.add_window( + WindowOptions { + bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(300., 400.))), + titlebar: None, + center: true, + kind: WindowKind::PopUp, + is_movable: false, + }, + |_| IncomingCallNotification::new(incoming_call), + ); + notification_window = Some(window_id); + } + } + }) + .detach(); +} + +struct IncomingCallNotification { + call: Call, +} + +impl IncomingCallNotification { + fn new(call: Call) -> Self { + Self { call } + } +} + +impl Entity for IncomingCallNotification { + type Event = (); +} + +impl View for IncomingCallNotification { + fn ui_name() -> &'static str { + "IncomingCallNotification" + } + + fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox { + let theme = &cx.global::().theme.contacts_panel; + Flex::row() + .with_children(self.call.from.avatar.clone().map(|avatar| { + Image::new(avatar) + .with_style(theme.contact_avatar) + .aligned() + .left() + .boxed() + })) + .with_child( + Label::new( + self.call.from.github_login.clone(), + theme.contact_username.text.clone(), + ) + .contained() + .aligned() + .left() + .flex(1., true) + .boxed(), + ) + .boxed() + } } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 18a2f8a4d0..04e27a8279 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -786,6 +786,10 @@ impl AsyncAppContext { self.update(|cx| cx.add_window(window_options, build_root_view)) } + pub fn remove_window(&mut self, window_id: usize) { + self.update(|cx| cx.remove_window(window_id)) + } + pub fn platform(&self) -> Arc { self.0.borrow().platform() } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 6233f0a037..de769a6e5e 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -107,7 +107,7 @@ fn main() { project::Project::init(&client); client::Channel::init(&client); client::init(client.clone(), cx); - collab_ui::init(cx); + collab_ui::init(user_store.clone(), cx); command_palette::init(cx); editor::init(cx); go_to_line::init(cx);