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