use crate::participant::{Frame, RemoteVideoTrack}; use anyhow::Result; use client::{proto::PeerId, User}; use futures::StreamExt; use gpui::{ div, img, AppContext, Div, Element, EventEmitter, FocusHandle, Focusable, FocusableView, InteractiveElement, ParentElement, Render, SharedString, Styled, Task, View, ViewContext, VisualContext, WindowContext, }; use std::sync::{Arc, Weak}; use ui::{h_stack, Icon, IconElement}; use workspace::{item::Item, ItemNavHistory, WorkspaceId}; pub enum Event { Close, } pub struct SharedScreen { track: Weak, frame: Option, pub peer_id: PeerId, user: Arc, nav_history: Option, _maintain_frame: Task>, focus: FocusHandle, } impl SharedScreen { pub fn new( track: &Arc, peer_id: PeerId, user: Arc, cx: &mut ViewContext, ) -> Self { cx.focus_handle(); let mut frames = track.frames(); Self { track: Arc::downgrade(track), frame: None, peer_id, user, nav_history: Default::default(), _maintain_frame: cx.spawn(|this, mut cx| async move { while let Some(frame) = frames.next().await { this.update(&mut cx, |this, cx| { this.frame = Some(frame); cx.notify(); })?; } this.update(&mut cx, |_, cx| cx.emit(Event::Close))?; Ok(()) }), focus: cx.focus_handle(), } } } impl EventEmitter for SharedScreen {} impl EventEmitter for SharedScreen {} impl FocusableView for SharedScreen { fn focus_handle(&self, _: &AppContext) -> FocusHandle { self.focus.clone() } } impl Render for SharedScreen { type Element = Focusable
; fn render(&mut self, _: &mut ViewContext) -> Self::Element { div().track_focus(&self.focus).size_full().children( self.frame .as_ref() .map(|frame| img(frame.image()).size_full()), ) } } impl Item for SharedScreen { fn tab_tooltip_text(&self, _: &AppContext) -> Option { Some(format!("{}'s screen", self.user.github_login).into()) } fn deactivated(&mut self, cx: &mut ViewContext) { if let Some(nav_history) = self.nav_history.as_mut() { nav_history.push::<()>(None, cx); } } fn tab_content(&self, _: Option, _: &WindowContext<'_>) -> gpui::AnyElement { h_stack() .gap_1() .child(IconElement::new(Icon::Screen)) .child(SharedString::from(format!( "{}'s screen", self.user.github_login ))) .into_any() } fn set_nav_history(&mut self, history: ItemNavHistory, _: &mut ViewContext) { self.nav_history = Some(history); } fn clone_on_split( &self, _workspace_id: WorkspaceId, cx: &mut ViewContext, ) -> Option> { let track = self.track.upgrade()?; Some(cx.build_view(|cx| Self::new(&track, self.peer_id, self.user.clone(), cx))) } }