1use crate::{
2 item::{Item, ItemEvent},
3 ItemNavHistory, WorkspaceId,
4};
5use call::{RemoteVideoTrack, RemoteVideoTrackView};
6use client::{proto::PeerId, User};
7use gpui::{
8 div, AppContext, EventEmitter, FocusHandle, FocusableView, InteractiveElement, ParentElement,
9 Render, SharedString, Styled, View, ViewContext, VisualContext, WindowContext,
10};
11use std::sync::Arc;
12use ui::{prelude::*, Icon, IconName};
13
14pub enum Event {
15 Close,
16}
17
18pub struct SharedScreen {
19 pub peer_id: PeerId,
20 user: Arc<User>,
21 nav_history: Option<ItemNavHistory>,
22 view: View<RemoteVideoTrackView>,
23 focus: FocusHandle,
24}
25
26impl SharedScreen {
27 pub fn new(
28 track: RemoteVideoTrack,
29 peer_id: PeerId,
30 user: Arc<User>,
31 cx: &mut ViewContext<Self>,
32 ) -> Self {
33 let view = cx.new_view(|cx| RemoteVideoTrackView::new(track.clone(), cx));
34 cx.subscribe(&view, |_, _, ev, cx| match ev {
35 call::RemoteVideoTrackViewEvent::Close => cx.emit(Event::Close),
36 })
37 .detach();
38 Self {
39 view,
40 peer_id,
41 user,
42 nav_history: Default::default(),
43 focus: cx.focus_handle(),
44 }
45 }
46}
47
48impl EventEmitter<Event> for SharedScreen {}
49
50impl FocusableView for SharedScreen {
51 fn focus_handle(&self, _: &AppContext) -> FocusHandle {
52 self.focus.clone()
53 }
54}
55impl Render for SharedScreen {
56 fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
57 div()
58 .bg(cx.theme().colors().editor_background)
59 .track_focus(&self.focus)
60 .key_context("SharedScreen")
61 .size_full()
62 .child(self.view.clone())
63 }
64}
65
66impl Item for SharedScreen {
67 type Event = Event;
68
69 fn tab_tooltip_text(&self, _: &AppContext) -> Option<SharedString> {
70 Some(format!("{}'s screen", self.user.github_login).into())
71 }
72
73 fn deactivated(&mut self, cx: &mut ViewContext<Self>) {
74 if let Some(nav_history) = self.nav_history.as_mut() {
75 nav_history.push::<()>(None, cx);
76 }
77 }
78
79 fn tab_icon(&self, _cx: &WindowContext) -> Option<Icon> {
80 Some(Icon::new(IconName::Screen))
81 }
82
83 fn tab_content_text(&self, _cx: &WindowContext) -> Option<SharedString> {
84 Some(format!("{}'s screen", self.user.github_login).into())
85 }
86
87 fn telemetry_event_text(&self) -> Option<&'static str> {
88 None
89 }
90
91 fn set_nav_history(&mut self, history: ItemNavHistory, _: &mut ViewContext<Self>) {
92 self.nav_history = Some(history);
93 }
94
95 fn clone_on_split(
96 &self,
97 _workspace_id: Option<WorkspaceId>,
98 cx: &mut ViewContext<Self>,
99 ) -> Option<View<Self>> {
100 Some(cx.new_view(|cx| Self {
101 view: self.view.update(cx, |view, cx| view.clone(cx)),
102 peer_id: self.peer_id,
103 user: self.user.clone(),
104 nav_history: Default::default(),
105 focus: cx.focus_handle(),
106 }))
107 }
108
109 fn to_item_events(event: &Self::Event, mut f: impl FnMut(ItemEvent)) {
110 match event {
111 Event::Close => f(ItemEvent::CloseItem),
112 }
113 }
114}