1mod participant;
2pub mod room;
3
4use anyhow::{anyhow, Result};
5use client::{incoming_call::IncomingCall, Client, UserStore};
6use gpui::{Entity, ModelContext, ModelHandle, MutableAppContext, Task};
7pub use participant::ParticipantLocation;
8pub use room::Room;
9use std::sync::Arc;
10
11pub fn init(client: Arc<Client>, user_store: ModelHandle<UserStore>, cx: &mut MutableAppContext) {
12 let active_call = cx.add_model(|_| ActiveCall::new(client, user_store));
13 cx.set_global(active_call);
14}
15
16pub struct ActiveCall {
17 room: Option<ModelHandle<Room>>,
18 client: Arc<Client>,
19 user_store: ModelHandle<UserStore>,
20}
21
22impl Entity for ActiveCall {
23 type Event = ();
24}
25
26impl ActiveCall {
27 fn new(client: Arc<Client>, user_store: ModelHandle<UserStore>) -> Self {
28 Self {
29 room: None,
30 client,
31 user_store,
32 }
33 }
34
35 pub fn global(cx: &mut MutableAppContext) -> ModelHandle<Self> {
36 cx.global::<ModelHandle<Self>>().clone()
37 }
38
39 pub fn invite(
40 &mut self,
41 recipient_user_id: u64,
42 cx: &mut ModelContext<Self>,
43 ) -> Task<Result<()>> {
44 let room = self.room.clone();
45
46 let client = self.client.clone();
47 let user_store = self.user_store.clone();
48 cx.spawn(|this, mut cx| async move {
49 let room = if let Some(room) = room {
50 room
51 } else {
52 let room = cx.update(|cx| Room::create(client, user_store, cx)).await?;
53 this.update(&mut cx, |this, cx| {
54 this.room = Some(room.clone());
55 cx.notify();
56 });
57 room
58 };
59 room.update(&mut cx, |room, cx| room.call(recipient_user_id, cx))
60 .await?;
61
62 Ok(())
63 })
64 }
65
66 pub fn join(&mut self, call: &IncomingCall, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
67 if self.room.is_some() {
68 return Task::ready(Err(anyhow!("cannot join while on another call")));
69 }
70
71 let join = Room::join(call, self.client.clone(), self.user_store.clone(), cx);
72 cx.spawn(|this, mut cx| async move {
73 let room = join.await?;
74 this.update(&mut cx, |this, cx| {
75 this.room = Some(room);
76 cx.notify();
77 });
78 Ok(())
79 })
80 }
81
82 pub fn room(&self) -> Option<&ModelHandle<Room>> {
83 self.room.as_ref()
84 }
85}