Model pending screen share in Room

This commit is contained in:
Antonio Scandurra 2022-10-19 11:38:24 +02:00
parent e49fc9f4b1
commit 3160d07b9c

View file

@ -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,