Basic channel joining!

This commit is contained in:
Conrad Irwin 2023-11-28 16:10:18 -07:00
parent b13638fa76
commit af3fa4ec0b
2 changed files with 102 additions and 55 deletions

View file

@ -14,8 +14,8 @@ use client::{
use collections::HashSet;
use futures::{channel::oneshot, future::Shared, Future, FutureExt};
use gpui::{
AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, Subscription, Task,
View, ViewContext, VisualContext, WeakModel, WeakView,
AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, PromptLevel,
Subscription, Task, View, ViewContext, VisualContext, WeakModel, WeakView, WindowHandle,
};
pub use participant::ParticipantLocation;
use postage::watch;
@ -334,12 +334,55 @@ impl ActiveCall {
pub fn join_channel(
&mut self,
channel_id: u64,
requesting_window: WindowHandle<Workspace>,
cx: &mut ModelContext<Self>,
) -> Task<Result<Option<Model<Room>>>> {
if let Some(room) = self.room().cloned() {
if room.read(cx).channel_id() == Some(channel_id) {
return Task::ready(Ok(Some(room)));
} else {
return cx.spawn(|_, _| async move {
todo!();
// let future = room.update(&mut cx, |room, cx| {
// room.most_active_project(cx).map(|(host, project)| {
// room.join_project(project, host, app_state.clone(), cx)
// })
// })
// if let Some(future) = future {
// future.await?;
// }
// Ok(Some(room))
});
}
let should_prompt = room.update(cx, |room, _| {
room.channel_id().is_some()
&& room.is_sharing_project()
&& room.remote_participants().len() > 0
});
if should_prompt {
return cx.spawn(|this, mut cx| async move {
let answer = requesting_window.update(&mut cx, |_, cx| {
cx.prompt(
PromptLevel::Warning,
"Leaving this call will unshare your current project.\nDo you want to switch channels?",
&["Yes, Join Channel", "Cancel"],
)
})?;
if answer.await? == 1 {
return Ok(None);
}
room.update(&mut cx, |room, cx| room.clear_state(cx))?;
this.update(&mut cx, |this, cx| {
this.join_channel(channel_id, requesting_window, cx)
})?
.await
});
}
if room.read(cx).channel_id().is_some() {
room.update(cx, |room, cx| room.clear_state(cx));
}
}

View file

@ -90,10 +90,10 @@ use rpc::proto;
// channel_id: ChannelId,
// }
// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
// pub struct OpenChannelNotes {
// pub channel_id: ChannelId,
// }
#[derive(Action, PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct OpenChannelNotes {
pub channel_id: ChannelId,
}
// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
// pub struct JoinChannelCall {
@ -167,10 +167,10 @@ use editor::Editor;
use feature_flags::{ChannelsAlpha, FeatureFlagAppExt};
use fuzzy::{match_strings, StringMatchCandidate};
use gpui::{
actions, div, img, prelude::*, serde_json, AppContext, AsyncWindowContext, Div, EventEmitter,
FocusHandle, Focusable, FocusableView, InteractiveElement, IntoElement, Model, ParentElement,
Render, RenderOnce, SharedString, Styled, Subscription, View, ViewContext, VisualContext,
WeakView,
actions, div, img, prelude::*, serde_json, Action, AppContext, AsyncWindowContext, Div,
EventEmitter, FocusHandle, Focusable, FocusableView, InteractiveElement, IntoElement, Model,
ParentElement, Render, RenderOnce, SharedString, Styled, Subscription, View, ViewContext,
VisualContext, WeakView,
};
use project::Fs;
use serde_derive::{Deserialize, Serialize};
@ -322,17 +322,17 @@ pub struct CollabPanel {
subscriptions: Vec<Subscription>,
collapsed_sections: Vec<Section>,
collapsed_channels: Vec<ChannelId>,
// drag_target_channel: ChannelDragTarget,
drag_target_channel: ChannelDragTarget,
workspace: WeakView<Workspace>,
// context_menu_on_selected: bool,
}
// #[derive(PartialEq, Eq)]
// enum ChannelDragTarget {
// None,
// Root,
// Channel(ChannelId),
// }
#[derive(PartialEq, Eq)]
enum ChannelDragTarget {
None,
Root,
Channel(ChannelId),
}
#[derive(Serialize, Deserialize)]
struct SerializedCollabPanel {
@ -614,7 +614,7 @@ impl CollabPanel {
workspace: workspace.weak_handle(),
client: workspace.app_state().client.clone(),
// context_menu_on_selected: true,
// drag_target_channel: ChannelDragTarget::None,
drag_target_channel: ChannelDragTarget::None,
// list_state,
};
@ -2346,11 +2346,12 @@ impl CollabPanel {
// }
// }
// fn open_channel_notes(&mut self, action: &OpenChannelNotes, cx: &mut ViewContext<Self>) {
// if let Some(workspace) = self.workspace.upgrade(cx) {
// ChannelView::open(action.channel_id, workspace, cx).detach();
// }
// }
fn open_channel_notes(&mut self, action: &OpenChannelNotes, cx: &mut ViewContext<Self>) {
if let Some(workspace) = self.workspace.upgrade() {
todo!();
// ChannelView::open(action.channel_id, workspace, cx).detach();
}
}
// fn show_inline_context_menu(&mut self, _: &menu::ShowContextMenu, cx: &mut ViewContext<Self>) {
// let Some(channel) = self.selected_channel() else {
@ -2504,21 +2505,17 @@ impl CollabPanel {
// .detach_and_log_err(cx);
// }
// fn join_channel(&self, channel_id: u64, cx: &mut ViewContext<Self>) {
// let Some(workspace) = self.workspace.upgrade(cx) else {
// return;
// };
// let Some(handle) = cx.window().downcast::<Workspace>() else {
// return;
// };
// workspace::join_channel(
// channel_id,
// workspace.read(cx).app_state().clone(),
// Some(handle),
// cx,
// )
// .detach_and_log_err(cx)
// }
fn join_channel(&self, channel_id: u64, cx: &mut ViewContext<Self>) {
let Some(handle) = cx.window_handle().downcast::<Workspace>() else {
return;
};
let active_call = ActiveCall::global(cx);
active_call
.update(cx, |active_call, cx| {
active_call.join_channel(channel_id, handle, cx)
})
.detach_and_log_err(cx)
}
// fn join_channel_chat(&mut self, action: &JoinChannelChat, cx: &mut ViewContext<Self>) {
// let channel_id = action.channel_id;
@ -2982,9 +2979,7 @@ impl CollabPanel {
is_selected: bool,
cx: &mut ViewContext<Self>,
) -> impl IntoElement {
ListItem::new("contact-placeholder")
.child(Label::new("Add a Contact"))
.on_click(cx.listener(|this, _, cx| todo!()))
ListItem::new("contact-placeholder").child(Label::new("Add a Contact"))
// enum AddContacts {}
// MouseEventHandler::new::<AddContacts, _>(0, cx, |state, _| {
// let style = theme.list_empty_state.style_for(is_selected, state);
@ -3023,6 +3018,15 @@ impl CollabPanel {
) -> impl IntoElement {
let channel_id = channel.id;
let is_active = maybe!({
let call_channel = ActiveCall::global(cx)
.read(cx)
.room()?
.read(cx)
.channel_id()?;
Some(call_channel == channel_id)
})
.unwrap_or(false);
let is_public = self
.channel_store
.read(cx)
@ -3034,16 +3038,6 @@ impl CollabPanel {
.then(|| !self.collapsed_channels.binary_search(&channel.id).is_ok())
.unwrap_or(false);
let is_active = maybe!({
let call_channel = ActiveCall::global(cx)
.read(cx)
.room()?
.read(cx)
.channel_id()?;
Some(call_channel == channel_id)
})
.unwrap_or(false);
let has_messages_notification = channel.unseen_message_id.is_some();
let has_notes_notification = channel.unseen_note_version.is_some();
@ -3052,6 +3046,7 @@ impl CollabPanel {
let face_pile = if !participants.is_empty() {
let extra_count = participants.len().saturating_sub(FACEPILE_LIMIT);
let user = &participants[0];
let result = FacePile {
faces: participants
@ -3059,6 +3054,7 @@ impl CollabPanel {
.filter_map(|user| Some(Avatar::data(user.avatar.clone()?).into_any_element()))
.take(FACEPILE_LIMIT)
.chain(if extra_count > 0 {
// todo!() @nate - this label looks wrong.
Some(Label::new(format!("+{}", extra_count)).into_any_element())
} else {
None
@ -3081,7 +3077,7 @@ impl CollabPanel {
.w_full()
.justify_between()
.child(
div()
h_stack()
.id(channel_id as usize)
.child(Label::new(channel.name.clone()))
.children(face_pile.map(|face_pile| face_pile.render(cx)))
@ -3128,7 +3124,15 @@ impl CollabPanel {
} else {
Toggle::NotToggleable
})
.on_click(cx.listener(|this, _, cx| todo!()))
.on_click(cx.listener(move |this, _, cx| {
if this.drag_target_channel == ChannelDragTarget::None {
if is_active {
this.open_channel_notes(&OpenChannelNotes { channel_id }, cx)
} else {
this.join_channel(channel_id, cx)
}
}
}))
.on_secondary_mouse_down(cx.listener(|this, _, cx| {
todo!() // open context menu
})),