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