mirror of
https://github.com/zed-industries/zed.git
synced 2024-10-24 23:47:05 +00:00
Add tooltip to follow collaborators
This commit is contained in:
parent
8a146e49ca
commit
516bd13474
6 changed files with 86 additions and 72 deletions
|
@ -350,6 +350,8 @@ impl ContactsPanel {
|
|||
is_selected: bool,
|
||||
cx: &mut RenderContext<Self>,
|
||||
) -> ElementBox {
|
||||
enum ToggleOnline {}
|
||||
|
||||
let project = &contact.projects[project_index];
|
||||
let project_id = project.id;
|
||||
let is_host = Some(contact.user.id) == current_user_id;
|
||||
|
@ -445,7 +447,7 @@ impl ContactsPanel {
|
|||
project: Some(open_project.clone()),
|
||||
})
|
||||
})
|
||||
.with_tooltip(
|
||||
.with_tooltip::<ToggleOnline, _>(
|
||||
project_id as usize,
|
||||
"Take project offline".to_string(),
|
||||
None,
|
||||
|
@ -565,7 +567,7 @@ impl ContactsPanel {
|
|||
project: Some(project.clone()),
|
||||
})
|
||||
})
|
||||
.with_tooltip(
|
||||
.with_tooltip::<ToggleOnline, _>(
|
||||
project_id,
|
||||
"Take project online".to_string(),
|
||||
None,
|
||||
|
|
|
@ -883,7 +883,7 @@ impl EditorElement {
|
|||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(move |_, _, cx| cx.dispatch_action(jump_action.clone()))
|
||||
.with_tooltip(
|
||||
.with_tooltip::<JumpIcon, _>(
|
||||
*key,
|
||||
"Jump to Buffer".to_string(),
|
||||
Some(Box::new(crate::OpenExcerpts)),
|
||||
|
|
|
@ -157,7 +157,7 @@ pub trait Element {
|
|||
FlexItem::new(self.boxed()).float()
|
||||
}
|
||||
|
||||
fn with_tooltip<T: View>(
|
||||
fn with_tooltip<Tag: 'static, T: View>(
|
||||
self,
|
||||
id: usize,
|
||||
text: String,
|
||||
|
@ -168,7 +168,7 @@ pub trait Element {
|
|||
where
|
||||
Self: 'static + Sized,
|
||||
{
|
||||
Tooltip::new(id, text, action, style, self.boxed(), cx)
|
||||
Tooltip::new::<Tag, T>(id, text, action, style, self.boxed(), cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ pub struct KeystrokeStyle {
|
|||
}
|
||||
|
||||
impl Tooltip {
|
||||
pub fn new<T: View>(
|
||||
pub fn new<Tag: 'static, T: View>(
|
||||
id: usize,
|
||||
text: String,
|
||||
action: Option<Box<dyn Action>>,
|
||||
|
@ -57,7 +57,10 @@ impl Tooltip {
|
|||
child: ElementBox,
|
||||
cx: &mut RenderContext<T>,
|
||||
) -> Self {
|
||||
let state_handle = cx.element_state::<TooltipState, Rc<TooltipState>>(id);
|
||||
struct ElementState<Tag>(Tag);
|
||||
struct MouseEventHandlerState<Tag>(Tag);
|
||||
|
||||
let state_handle = cx.element_state::<ElementState<Tag>, Rc<TooltipState>>(id);
|
||||
let state = state_handle.read(cx).clone();
|
||||
let tooltip = if state.visible.get() {
|
||||
let mut collapsed_tooltip = Self::render_tooltip(
|
||||
|
@ -86,33 +89,34 @@ impl Tooltip {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
let child = MouseEventHandler::new::<Self, _, _>(id, cx, |_, _| child)
|
||||
.on_hover(move |position, hover, cx| {
|
||||
let window_id = cx.window_id();
|
||||
if let Some(view_id) = cx.view_id() {
|
||||
if hover {
|
||||
if !state.visible.get() {
|
||||
state.position.set(position);
|
||||
let child =
|
||||
MouseEventHandler::new::<MouseEventHandlerState<Tag>, _, _>(id, cx, |_, _| child)
|
||||
.on_hover(move |position, hover, cx| {
|
||||
let window_id = cx.window_id();
|
||||
if let Some(view_id) = cx.view_id() {
|
||||
if hover {
|
||||
if !state.visible.get() {
|
||||
state.position.set(position);
|
||||
|
||||
let mut debounce = state.debounce.borrow_mut();
|
||||
if debounce.is_none() {
|
||||
*debounce = Some(cx.spawn({
|
||||
let state = state.clone();
|
||||
|mut cx| async move {
|
||||
cx.background().timer(DEBOUNCE_TIMEOUT).await;
|
||||
state.visible.set(true);
|
||||
cx.update(|cx| cx.notify_view(window_id, view_id));
|
||||
}
|
||||
}));
|
||||
let mut debounce = state.debounce.borrow_mut();
|
||||
if debounce.is_none() {
|
||||
*debounce = Some(cx.spawn({
|
||||
let state = state.clone();
|
||||
|mut cx| async move {
|
||||
cx.background().timer(DEBOUNCE_TIMEOUT).await;
|
||||
state.visible.set(true);
|
||||
cx.update(|cx| cx.notify_view(window_id, view_id));
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
state.visible.set(false);
|
||||
state.debounce.take();
|
||||
}
|
||||
} else {
|
||||
state.visible.set(false);
|
||||
state.debounce.take();
|
||||
}
|
||||
}
|
||||
})
|
||||
.boxed();
|
||||
})
|
||||
.boxed();
|
||||
Self {
|
||||
child,
|
||||
tooltip,
|
||||
|
|
|
@ -266,47 +266,44 @@ impl View for SidebarButtons {
|
|||
side,
|
||||
item_index: ix,
|
||||
};
|
||||
MouseEventHandler::new::<Self, _, _>(ix, cx, {
|
||||
let action = action.clone();
|
||||
let tooltip_style = tooltip_style.clone();
|
||||
move |state, cx| {
|
||||
let is_active = Some(ix) == active_ix;
|
||||
let style = item_style.style_for(state, is_active);
|
||||
Stack::new()
|
||||
.with_child(
|
||||
Svg::new(icon_path).with_color(style.icon_color).boxed(),
|
||||
MouseEventHandler::new::<Self, _, _>(ix, cx, move |state, cx| {
|
||||
let is_active = Some(ix) == active_ix;
|
||||
let style = item_style.style_for(state, is_active);
|
||||
Stack::new()
|
||||
.with_child(Svg::new(icon_path).with_color(style.icon_color).boxed())
|
||||
.with_children(if !is_active && item_view.should_show_badge(cx) {
|
||||
Some(
|
||||
Empty::new()
|
||||
.collapsed()
|
||||
.contained()
|
||||
.with_style(badge_style)
|
||||
.aligned()
|
||||
.bottom()
|
||||
.right()
|
||||
.boxed(),
|
||||
)
|
||||
.with_children(if !is_active && item_view.should_show_badge(cx) {
|
||||
Some(
|
||||
Empty::new()
|
||||
.collapsed()
|
||||
.contained()
|
||||
.with_style(badge_style)
|
||||
.aligned()
|
||||
.bottom()
|
||||
.right()
|
||||
.boxed(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.constrained()
|
||||
.with_width(style.icon_size)
|
||||
.with_height(style.icon_size)
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
.with_tooltip(
|
||||
ix,
|
||||
tooltip,
|
||||
Some(Box::new(action.clone())),
|
||||
tooltip_style.clone(),
|
||||
cx,
|
||||
)
|
||||
.boxed()
|
||||
}
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.constrained()
|
||||
.with_width(style.icon_size)
|
||||
.with_height(style.icon_size)
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
.boxed()
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(move |_, _, cx| cx.dispatch_action(action.clone()))
|
||||
.on_click({
|
||||
let action = action.clone();
|
||||
move |_, _, cx| cx.dispatch_action(action.clone())
|
||||
})
|
||||
.with_tooltip::<Self, _>(
|
||||
ix,
|
||||
tooltip,
|
||||
Some(Box::new(action)),
|
||||
tooltip_style.clone(),
|
||||
cx,
|
||||
)
|
||||
.boxed()
|
||||
},
|
||||
))
|
||||
|
|
|
@ -1788,7 +1788,7 @@ impl Workspace {
|
|||
Some(self.render_avatar(
|
||||
collaborator.user.avatar.clone()?,
|
||||
collaborator.replica_id,
|
||||
Some(collaborator.peer_id),
|
||||
Some((collaborator.peer_id, &collaborator.user.github_login)),
|
||||
theme,
|
||||
cx,
|
||||
))
|
||||
|
@ -1833,12 +1833,12 @@ impl Workspace {
|
|||
&self,
|
||||
avatar: Arc<ImageData>,
|
||||
replica_id: ReplicaId,
|
||||
peer_id: Option<PeerId>,
|
||||
peer: Option<(PeerId, &str)>,
|
||||
theme: &Theme,
|
||||
cx: &mut RenderContext<Self>,
|
||||
) -> ElementBox {
|
||||
let replica_color = theme.editor.replica_selection_style(replica_id).cursor;
|
||||
let is_followed = peer_id.map_or(false, |peer_id| {
|
||||
let is_followed = peer.map_or(false, |(peer_id, _)| {
|
||||
self.follower_states_by_leader.contains_key(&peer_id)
|
||||
});
|
||||
let mut avatar_style = theme.workspace.titlebar.avatar;
|
||||
|
@ -1869,10 +1869,21 @@ impl Workspace {
|
|||
.with_margin_left(theme.workspace.titlebar.avatar_margin)
|
||||
.boxed();
|
||||
|
||||
if let Some(peer_id) = peer_id {
|
||||
if let Some((peer_id, peer_github_login)) = peer {
|
||||
MouseEventHandler::new::<ToggleFollow, _, _>(replica_id.into(), cx, move |_, _| content)
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(move |_, _, cx| cx.dispatch_action(ToggleFollow(peer_id)))
|
||||
.with_tooltip::<ToggleFollow, _>(
|
||||
peer_id.0 as usize,
|
||||
if is_followed {
|
||||
format!("Unfollow {}", peer_github_login)
|
||||
} else {
|
||||
format!("Follow {}", peer_github_login)
|
||||
},
|
||||
Some(Box::new(FollowNextCollaborator)),
|
||||
theme.tooltip.clone(),
|
||||
cx,
|
||||
)
|
||||
.boxed()
|
||||
} else {
|
||||
content
|
||||
|
|
Loading…
Reference in a new issue