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