Add/fix mouse interactions in current call sidebar

This commit is contained in:
Conrad Irwin 2023-10-02 19:38:45 -06:00
parent 528fa5c57b
commit d7867cd1e2

View file

@ -47,7 +47,7 @@ use util::{iife, ResultExt, TryFutureExt};
use workspace::{
dock::{DockPosition, Panel},
item::ItemHandle,
Workspace,
FollowNextCollaborator, Workspace,
};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
@ -404,6 +404,7 @@ enum ListEntry {
Header(Section),
CallParticipant {
user: Arc<User>,
peer_id: Option<PeerId>,
is_pending: bool,
},
ParticipantProject {
@ -508,14 +509,19 @@ impl CollabPanel {
let is_collapsed = this.collapsed_sections.contains(section);
this.render_header(*section, &theme, is_selected, is_collapsed, cx)
}
ListEntry::CallParticipant { user, is_pending } => {
Self::render_call_participant(
user,
*is_pending,
is_selected,
&theme.collab_panel,
)
}
ListEntry::CallParticipant {
user,
peer_id,
is_pending,
} => Self::render_call_participant(
user,
*peer_id,
this.user_store.clone(),
*is_pending,
is_selected,
&theme,
cx,
),
ListEntry::ParticipantProject {
project_id,
worktree_root_names,
@ -528,7 +534,7 @@ impl CollabPanel {
Some(*project_id) == current_project_id,
*is_last,
is_selected,
&theme.collab_panel,
&theme,
cx,
),
ListEntry::ParticipantScreen { peer_id, is_last } => {
@ -793,6 +799,7 @@ impl CollabPanel {
let user_id = user.id;
self.entries.push(ListEntry::CallParticipant {
user,
peer_id: None,
is_pending: false,
});
let mut projects = room.local_participant().projects.iter().peekable();
@ -830,6 +837,7 @@ impl CollabPanel {
let participant = &room.remote_participants()[&user_id];
self.entries.push(ListEntry::CallParticipant {
user: participant.user.clone(),
peer_id: Some(participant.peer_id),
is_pending: false,
});
let mut projects = participant.projects.iter().peekable();
@ -871,6 +879,7 @@ impl CollabPanel {
self.entries
.extend(matches.iter().map(|mat| ListEntry::CallParticipant {
user: room.pending_participants()[mat.candidate_id].clone(),
peer_id: None,
is_pending: true,
}));
}
@ -1174,46 +1183,97 @@ impl CollabPanel {
fn render_call_participant(
user: &User,
peer_id: Option<PeerId>,
user_store: ModelHandle<UserStore>,
is_pending: bool,
is_selected: bool,
theme: &theme::CollabPanel,
theme: &theme::Theme,
cx: &mut ViewContext<Self>,
) -> AnyElement<Self> {
Flex::row()
.with_children(user.avatar.clone().map(|avatar| {
Image::from_data(avatar)
.with_style(theme.contact_avatar)
.aligned()
.left()
}))
.with_child(
Label::new(
user.github_login.clone(),
theme.contact_username.text.clone(),
)
.contained()
.with_style(theme.contact_username.container)
.aligned()
.left()
.flex(1., true),
)
.with_children(if is_pending {
Some(
Label::new("Calling", theme.calling_indicator.text.clone())
enum CallParticipant {}
enum CallParticipantTooltip {}
let collab_theme = &theme.collab_panel;
let is_current_user =
user_store.read(cx).current_user().map(|user| user.id) == Some(user.id);
let content =
MouseEventHandler::new::<CallParticipant, _>(user.id as usize, cx, |mouse_state, _| {
let style = if is_current_user {
*collab_theme
.contact_row
.in_state(is_selected)
.style_for(&mut Default::default())
} else {
*collab_theme
.contact_row
.in_state(is_selected)
.style_for(mouse_state)
};
Flex::row()
.with_children(user.avatar.clone().map(|avatar| {
Image::from_data(avatar)
.with_style(collab_theme.contact_avatar)
.aligned()
.left()
}))
.with_child(
Label::new(
user.github_login.clone(),
collab_theme.contact_username.text.clone(),
)
.contained()
.with_style(theme.calling_indicator.container)
.aligned(),
)
} else {
None
.with_style(collab_theme.contact_username.container)
.aligned()
.left()
.flex(1., true),
)
.with_children(if is_pending {
Some(
Label::new("Calling", collab_theme.calling_indicator.text.clone())
.contained()
.with_style(collab_theme.calling_indicator.container)
.aligned(),
)
} else if is_current_user {
Some(
Label::new("You", collab_theme.calling_indicator.text.clone())
.contained()
.with_style(collab_theme.calling_indicator.container)
.aligned(),
)
} else {
None
})
.constrained()
.with_height(collab_theme.row_height)
.contained()
.with_style(style)
});
if is_current_user || is_pending || peer_id.is_none() {
return content.into_any();
}
let tooltip = format!("Follow {}", user.github_login);
content
.on_click(MouseButton::Left, move |_, this, cx| {
if let Some(workspace) = this.workspace.upgrade(cx) {
workspace
.update(cx, |workspace, cx| workspace.follow(peer_id.unwrap(), cx))
.map(|task| task.detach_and_log_err(cx));
}
})
.constrained()
.with_height(theme.row_height)
.contained()
.with_style(
*theme
.contact_row
.in_state(is_selected)
.style_for(&mut Default::default()),
.with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<CallParticipantTooltip>(
user.id as usize,
tooltip,
Some(Box::new(FollowNextCollaborator)),
theme.tooltip.clone(),
cx,
)
.into_any()
}
@ -1225,74 +1285,91 @@ impl CollabPanel {
is_current: bool,
is_last: bool,
is_selected: bool,
theme: &theme::CollabPanel,
theme: &theme::Theme,
cx: &mut ViewContext<Self>,
) -> AnyElement<Self> {
enum JoinProject {}
enum JoinProjectTooltip {}
let host_avatar_width = theme
let collab_theme = &theme.collab_panel;
let host_avatar_width = collab_theme
.contact_avatar
.width
.or(theme.contact_avatar.height)
.or(collab_theme.contact_avatar.height)
.unwrap_or(0.);
let tree_branch = theme.tree_branch;
let tree_branch = collab_theme.tree_branch;
let project_name = if worktree_root_names.is_empty() {
"untitled".to_string()
} else {
worktree_root_names.join(", ")
};
MouseEventHandler::new::<JoinProject, _>(project_id as usize, cx, |mouse_state, cx| {
let tree_branch = *tree_branch.in_state(is_selected).style_for(mouse_state);
let row = theme
.project_row
.in_state(is_selected)
.style_for(mouse_state);
let content =
MouseEventHandler::new::<JoinProject, _>(project_id as usize, cx, |mouse_state, cx| {
let tree_branch = *tree_branch.in_state(is_selected).style_for(mouse_state);
let row = if is_current {
collab_theme
.project_row
.in_state(true)
.style_for(&mut Default::default())
} else {
collab_theme
.project_row
.in_state(is_selected)
.style_for(mouse_state)
};
Flex::row()
.with_child(render_tree_branch(
tree_branch,
&row.name.text,
is_last,
vec2f(host_avatar_width, theme.row_height),
cx.font_cache(),
))
.with_child(
Svg::new("icons/file_icons/folder.svg")
.with_color(theme.channel_hash.color)
.constrained()
.with_width(theme.channel_hash.width)
.aligned()
.left(),
)
.with_child(
Label::new(project_name, row.name.text.clone())
.aligned()
.left()
.contained()
.with_style(row.name.container)
.flex(1., false),
)
.constrained()
.with_height(theme.row_height)
.contained()
.with_style(row.container)
})
.with_cursor_style(if !is_current {
CursorStyle::PointingHand
} else {
CursorStyle::Arrow
})
.on_click(MouseButton::Left, move |_, this, cx| {
if !is_current {
Flex::row()
.with_child(render_tree_branch(
tree_branch,
&row.name.text,
is_last,
vec2f(host_avatar_width, collab_theme.row_height),
cx.font_cache(),
))
.with_child(
Svg::new("icons/file_icons/folder.svg")
.with_color(collab_theme.channel_hash.color)
.constrained()
.with_width(collab_theme.channel_hash.width)
.aligned()
.left(),
)
.with_child(
Label::new(project_name.clone(), row.name.text.clone())
.aligned()
.left()
.contained()
.with_style(row.name.container)
.flex(1., false),
)
.constrained()
.with_height(collab_theme.row_height)
.contained()
.with_style(row.container)
});
if is_current {
return content.into_any();
}
content
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, move |_, this, cx| {
if let Some(workspace) = this.workspace.upgrade(cx) {
let app_state = workspace.read(cx).app_state().clone();
workspace::join_remote_project(project_id, host_user_id, app_state, cx)
.detach_and_log_err(cx);
}
}
})
.into_any()
})
.with_tooltip::<JoinProjectTooltip>(
project_id as usize,
format!("Open {}", project_name),
None,
theme.tooltip.clone(),
cx,
)
.into_any()
}
fn render_participant_screen(