Model pending screen share in Room
This commit is contained in:
parent
e49fc9f4b1
commit
3160d07b9c
1 changed files with 90 additions and 34 deletions
|
@ -10,8 +10,8 @@ use gpui::{AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext
|
|||
use live_kit_client::{LocalTrackPublication, LocalVideoTrack, RemoteVideoTrackUpdate};
|
||||
use postage::watch;
|
||||
use project::Project;
|
||||
use std::{os::unix::prelude::OsStrExt, sync::Arc};
|
||||
use util::ResultExt;
|
||||
use std::{mem, os::unix::prelude::OsStrExt, sync::Arc};
|
||||
use util::{post_inc, ResultExt};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Event {
|
||||
|
@ -100,7 +100,8 @@ impl Room {
|
|||
.detach_and_log_err(cx);
|
||||
Some(LiveKitRoom {
|
||||
room,
|
||||
screen_track: None,
|
||||
screen_track: ScreenTrack::None,
|
||||
next_publish_id: 0,
|
||||
_maintain_room,
|
||||
})
|
||||
} else {
|
||||
|
@ -607,9 +608,9 @@ impl Room {
|
|||
}
|
||||
|
||||
pub fn is_screen_sharing(&self) -> bool {
|
||||
self.live_kit
|
||||
.as_ref()
|
||||
.map_or(false, |live_kit| live_kit.screen_track.is_some())
|
||||
self.live_kit.as_ref().map_or(false, |live_kit| {
|
||||
!matches!(live_kit.screen_track, ScreenTrack::None)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn share_screen(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
||||
|
@ -619,23 +620,34 @@ impl Room {
|
|||
return Task::ready(Err(anyhow!("screen was already shared")));
|
||||
}
|
||||
|
||||
cx.spawn_weak(|this, mut cx| async move {
|
||||
let displays = live_kit_client::display_sources().await?;
|
||||
let display = displays
|
||||
.first()
|
||||
.ok_or_else(|| anyhow!("no display found"))?;
|
||||
let track = LocalVideoTrack::screen_share_for_display(&display);
|
||||
let publication = this
|
||||
.upgrade(&cx)
|
||||
.ok_or_else(|| anyhow!("room was dropped"))?
|
||||
.read_with(&cx, |this, _| {
|
||||
this.live_kit
|
||||
.as_ref()
|
||||
.map(|live_kit| live_kit.room.publish_video_track(&track))
|
||||
})
|
||||
.ok_or_else(|| anyhow!("live-kit was not initialized"))?
|
||||
.await?;
|
||||
let publish_id = if let Some(live_kit) = self.live_kit.as_mut() {
|
||||
let publish_id = post_inc(&mut live_kit.next_publish_id);
|
||||
live_kit.screen_track = ScreenTrack::Pending { publish_id };
|
||||
cx.notify();
|
||||
publish_id
|
||||
} else {
|
||||
return Task::ready(Err(anyhow!("live-kit was not initialized")));
|
||||
};
|
||||
|
||||
cx.spawn_weak(|this, mut cx| async move {
|
||||
let publish_track = async {
|
||||
let displays = live_kit_client::display_sources().await?;
|
||||
let display = displays
|
||||
.first()
|
||||
.ok_or_else(|| anyhow!("no display found"))?;
|
||||
let track = LocalVideoTrack::screen_share_for_display(&display);
|
||||
this.upgrade(&cx)
|
||||
.ok_or_else(|| anyhow!("room was dropped"))?
|
||||
.read_with(&cx, |this, _| {
|
||||
this.live_kit
|
||||
.as_ref()
|
||||
.map(|live_kit| live_kit.room.publish_video_track(&track))
|
||||
})
|
||||
.ok_or_else(|| anyhow!("live-kit was not initialized"))?
|
||||
.await
|
||||
};
|
||||
|
||||
let publication = publish_track.await;
|
||||
this.upgrade(&cx)
|
||||
.ok_or_else(|| anyhow!("room was dropped"))?
|
||||
.update(&mut cx, |this, cx| {
|
||||
|
@ -643,9 +655,36 @@ impl Room {
|
|||
.live_kit
|
||||
.as_mut()
|
||||
.ok_or_else(|| anyhow!("live-kit was not initialized"))?;
|
||||
live_kit.screen_track = Some(publication);
|
||||
cx.notify();
|
||||
Ok(())
|
||||
|
||||
let canceled = if let ScreenTrack::Pending {
|
||||
publish_id: cur_publish_id,
|
||||
} = &live_kit.screen_track
|
||||
{
|
||||
*cur_publish_id != publish_id
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
||||
match publication {
|
||||
Ok(publication) => {
|
||||
if canceled {
|
||||
live_kit.room.unpublish_track(publication);
|
||||
} else {
|
||||
live_kit.screen_track = ScreenTrack::Published(publication);
|
||||
cx.notify();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Err(error) => {
|
||||
if canceled {
|
||||
Ok(())
|
||||
} else {
|
||||
live_kit.screen_track = ScreenTrack::None;
|
||||
cx.notify();
|
||||
Err(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -659,23 +698,40 @@ impl Room {
|
|||
.live_kit
|
||||
.as_mut()
|
||||
.ok_or_else(|| anyhow!("live-kit was not initialized"))?;
|
||||
let track = live_kit
|
||||
.screen_track
|
||||
.take()
|
||||
.ok_or_else(|| anyhow!("screen was not shared"))?;
|
||||
live_kit.room.unpublish_track(track);
|
||||
cx.notify();
|
||||
|
||||
Ok(())
|
||||
match mem::take(&mut live_kit.screen_track) {
|
||||
ScreenTrack::None => Err(anyhow!("screen was not shared")),
|
||||
ScreenTrack::Pending { .. } => {
|
||||
cx.notify();
|
||||
Ok(())
|
||||
}
|
||||
ScreenTrack::Published(track) => {
|
||||
live_kit.room.unpublish_track(track);
|
||||
cx.notify();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LiveKitRoom {
|
||||
room: Arc<live_kit_client::Room>,
|
||||
screen_track: Option<LocalTrackPublication>,
|
||||
screen_track: ScreenTrack,
|
||||
next_publish_id: usize,
|
||||
_maintain_room: Task<()>,
|
||||
}
|
||||
|
||||
pub enum ScreenTrack {
|
||||
None,
|
||||
Pending { publish_id: usize },
|
||||
Published(LocalTrackPublication),
|
||||
}
|
||||
|
||||
impl Default for ScreenTrack {
|
||||
fn default() -> Self {
|
||||
Self::None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum RoomStatus {
|
||||
Online,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue