Move CallHandler impl into call2
This commit is contained in:
parent
170291ff96
commit
ebccdb64bc
6 changed files with 196 additions and 165 deletions
|
@ -31,7 +31,7 @@ media = { path = "../media" }
|
|||
project = { package = "project2", path = "../project2" }
|
||||
settings = { package = "settings2", path = "../settings2" }
|
||||
util = { path = "../util" }
|
||||
|
||||
workspace = {package = "workspace2", path = "../workspace2"}
|
||||
anyhow.workspace = true
|
||||
async-broadcast = "0.4"
|
||||
futures.workspace = true
|
||||
|
|
|
@ -505,6 +505,160 @@ pub fn report_call_event_for_channel(
|
|||
)
|
||||
}
|
||||
|
||||
struct Call {
|
||||
follower_states: HashMap<View<Pane>, FollowerState>,
|
||||
active_call: Option<(Model<ActiveCall>, Vec<Subscription>)>,
|
||||
parent_workspace: WeakView<Workspace>,
|
||||
}
|
||||
|
||||
impl Call {
|
||||
fn new(parent_workspace: WeakView<Workspace>, cx: &mut ViewContext<'_, Workspace>) -> Self {
|
||||
let mut active_call = None;
|
||||
if cx.has_global::<Model<ActiveCall>>() {
|
||||
let call = cx.global::<Model<ActiveCall>>().clone();
|
||||
let subscriptions = vec![cx.subscribe(&call, Self::on_active_call_event)];
|
||||
active_call = Some((call, subscriptions));
|
||||
}
|
||||
Self {
|
||||
follower_states: Default::default(),
|
||||
active_call,
|
||||
parent_workspace,
|
||||
}
|
||||
}
|
||||
fn on_active_call_event(
|
||||
workspace: &mut Workspace,
|
||||
_: Model<ActiveCall>,
|
||||
event: &call2::room::Event,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
match event {
|
||||
call2::room::Event::ParticipantLocationChanged { participant_id }
|
||||
| call2::room::Event::RemoteVideoTracksChanged { participant_id } => {
|
||||
workspace.leader_updated(*participant_id, cx);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl CallHandler for Call {
|
||||
fn leader_updated(&mut self, leader_id: PeerId, cx: &mut ViewContext<Workspace>) -> Option<()> {
|
||||
cx.notify();
|
||||
|
||||
let (call, _) = self.active_call.as_ref()?;
|
||||
let room = call.read(cx).room()?.read(cx);
|
||||
let participant = room.remote_participant_for_peer_id(leader_id)?;
|
||||
let mut items_to_activate = Vec::new();
|
||||
|
||||
let leader_in_this_app;
|
||||
let leader_in_this_project;
|
||||
match participant.location {
|
||||
call2::ParticipantLocation::SharedProject { project_id } => {
|
||||
leader_in_this_app = true;
|
||||
leader_in_this_project = Some(project_id)
|
||||
== self
|
||||
.parent_workspace
|
||||
.update(cx, |this, cx| this.project.read(cx).remote_id())
|
||||
.log_err()
|
||||
.flatten();
|
||||
}
|
||||
call2::ParticipantLocation::UnsharedProject => {
|
||||
leader_in_this_app = true;
|
||||
leader_in_this_project = false;
|
||||
}
|
||||
call2::ParticipantLocation::External => {
|
||||
leader_in_this_app = false;
|
||||
leader_in_this_project = false;
|
||||
}
|
||||
};
|
||||
|
||||
for (pane, state) in &self.follower_states {
|
||||
if state.leader_id != leader_id {
|
||||
continue;
|
||||
}
|
||||
if let (Some(active_view_id), true) = (state.active_view_id, leader_in_this_app) {
|
||||
if let Some(item) = state.items_by_leader_view_id.get(&active_view_id) {
|
||||
if leader_in_this_project || !item.is_project_item(cx) {
|
||||
items_to_activate.push((pane.clone(), item.boxed_clone()));
|
||||
}
|
||||
} else {
|
||||
log::warn!(
|
||||
"unknown view id {:?} for leader {:?}",
|
||||
active_view_id,
|
||||
leader_id
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// todo!()
|
||||
// if let Some(shared_screen) = self.shared_screen_for_peer(leader_id, pane, cx) {
|
||||
// items_to_activate.push((pane.clone(), Box::new(shared_screen)));
|
||||
// }
|
||||
}
|
||||
|
||||
for (pane, item) in items_to_activate {
|
||||
let pane_was_focused = pane.read(cx).has_focus(cx);
|
||||
if let Some(index) = pane.update(cx, |pane, _| pane.index_for_item(item.as_ref())) {
|
||||
pane.update(cx, |pane, cx| pane.activate_item(index, false, false, cx));
|
||||
} else {
|
||||
pane.update(cx, |pane, mut cx| {
|
||||
pane.add_item(item.boxed_clone(), false, false, None, &mut cx)
|
||||
});
|
||||
}
|
||||
|
||||
if pane_was_focused {
|
||||
pane.update(cx, |pane, cx| pane.focus_active_item(cx));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn shared_screen_for_peer(
|
||||
&self,
|
||||
peer_id: PeerId,
|
||||
pane: &View<Pane>,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> Option<Box<dyn ItemHandle>> {
|
||||
let (call, _) = self.active_call.as_ref()?;
|
||||
let room = call.read(cx).room()?.read(cx);
|
||||
let participant = room.remote_participant_for_peer_id(peer_id)?;
|
||||
let track = participant.video_tracks.values().next()?.clone();
|
||||
let user = participant.user.clone();
|
||||
todo!();
|
||||
// for item in pane.read(cx).items_of_type::<SharedScreen>() {
|
||||
// if item.read(cx).peer_id == peer_id {
|
||||
// return Box::new(Some(item));
|
||||
// }
|
||||
// }
|
||||
|
||||
// Some(Box::new(cx.build_view(|cx| {
|
||||
// SharedScreen::new(&track, peer_id, user.clone(), cx)
|
||||
// })))
|
||||
}
|
||||
|
||||
fn follower_states_mut(&mut self) -> &mut HashMap<View<Pane>, FollowerState> {
|
||||
&mut self.follower_states
|
||||
}
|
||||
fn follower_states(&self) -> &HashMap<View<Pane>, FollowerState> {
|
||||
&self.follower_states
|
||||
}
|
||||
fn room_id(&self, cx: &AppContext) -> Option<u64> {
|
||||
Some(self.active_call.as_ref()?.0.read(cx).room()?.read(cx).id())
|
||||
}
|
||||
fn hang_up(&self, mut cx: AsyncWindowContext) -> Result<Task<Result<()>>> {
|
||||
let Some((call, _)) = self.active_call.as_ref() else {
|
||||
bail!("Cannot exit a call; not in a call");
|
||||
};
|
||||
|
||||
call.update(&mut cx, |this, cx| this.hang_up(cx))
|
||||
}
|
||||
fn active_project(&self, cx: &AppContext) -> Option<WeakModel<Project>> {
|
||||
ActiveCall::global(cx).read(cx).location().cloned()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use gpui::TestAppContext;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue