macos.rs

  1use crate::{
  2    item::{Item, ItemEvent},
  3    ItemNavHistory, WorkspaceId,
  4};
  5use anyhow::Result;
  6use call::participant::{Frame, RemoteVideoTrack};
  7use client::{proto::PeerId, User};
  8use futures::StreamExt;
  9use gpui::{
 10    div, surface, App, Context, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement,
 11    ParentElement, Render, SharedString, Styled, Task, Window,
 12};
 13use std::sync::{Arc, Weak};
 14use ui::{prelude::*, Icon, IconName};
 15
 16pub enum Event {
 17    Close,
 18}
 19
 20pub struct SharedScreen {
 21    track: Weak<RemoteVideoTrack>,
 22    frame: Option<Frame>,
 23    pub peer_id: PeerId,
 24    user: Arc<User>,
 25    nav_history: Option<ItemNavHistory>,
 26    _maintain_frame: Task<Result<()>>,
 27    focus: FocusHandle,
 28}
 29
 30impl SharedScreen {
 31    pub fn new(
 32        track: Arc<RemoteVideoTrack>,
 33        peer_id: PeerId,
 34        user: Arc<User>,
 35        window: &mut Window,
 36        cx: &mut Context<Self>,
 37    ) -> Self {
 38        cx.focus_handle();
 39        let mut frames = track.frames();
 40        Self {
 41            track: Arc::downgrade(&track),
 42            frame: None,
 43            peer_id,
 44            user,
 45            nav_history: Default::default(),
 46            _maintain_frame: cx.spawn_in(window, async move |this, cx| {
 47                while let Some(frame) = frames.next().await {
 48                    this.update(cx, |this, cx| {
 49                        this.frame = Some(frame);
 50                        cx.notify();
 51                    })?;
 52                }
 53                this.update(cx, |_, cx| cx.emit(Event::Close))?;
 54                Ok(())
 55            }),
 56            focus: cx.focus_handle(),
 57        }
 58    }
 59}
 60
 61impl EventEmitter<Event> for SharedScreen {}
 62
 63impl Focusable for SharedScreen {
 64    fn focus_handle(&self, _: &App) -> FocusHandle {
 65        self.focus.clone()
 66    }
 67}
 68impl Render for SharedScreen {
 69    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
 70        div()
 71            .bg(cx.theme().colors().editor_background)
 72            .track_focus(&self.focus)
 73            .key_context("SharedScreen")
 74            .size_full()
 75            .children(
 76                self.frame
 77                    .as_ref()
 78                    .map(|frame| surface(frame.image()).size_full()),
 79            )
 80    }
 81}
 82
 83impl Item for SharedScreen {
 84    type Event = Event;
 85
 86    fn tab_tooltip_text(&self, _: &App) -> Option<SharedString> {
 87        Some(format!("{}'s screen", self.user.github_login).into())
 88    }
 89
 90    fn deactivated(&mut self, _: &mut Window, cx: &mut Context<Self>) {
 91        if let Some(nav_history) = self.nav_history.as_mut() {
 92            nav_history.push::<()>(None, cx);
 93        }
 94    }
 95
 96    fn tab_icon(&self, _window: &Window, _cx: &App) -> Option<Icon> {
 97        Some(Icon::new(IconName::Screen))
 98    }
 99
100    fn tab_content_text(&self, _window: &Window, _cx: &App) -> Option<SharedString> {
101        Some(format!("{}'s screen", self.user.github_login).into())
102    }
103
104    fn telemetry_event_text(&self) -> Option<&'static str> {
105        None
106    }
107
108    fn set_nav_history(
109        &mut self,
110        history: ItemNavHistory,
111        _window: &mut Window,
112        _: &mut Context<Self>,
113    ) {
114        self.nav_history = Some(history);
115    }
116
117    fn clone_on_split(
118        &self,
119        _workspace_id: Option<WorkspaceId>,
120        window: &mut Window,
121        cx: &mut Context<Self>,
122    ) -> Option<Entity<Self>> {
123        let track = self.track.upgrade()?;
124        Some(cx.new(|cx| Self::new(track, self.peer_id, self.user.clone(), window, cx)))
125    }
126
127    fn to_item_events(event: &Self::Event, mut f: impl FnMut(ItemEvent)) {
128        match event {
129            Event::Close => f(ItemEvent::CloseItem),
130        }
131    }
132}