call.rs

 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}