Implement following and more collaboration panel features in zed2 (#3504)
This commit is contained in:
@@ -78,7 +78,7 @@ impl Settings for ItemSettings {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Hash, Debug)]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
|
||||
pub enum ItemEvent {
|
||||
CloseItem,
|
||||
UpdateTab,
|
||||
@@ -92,7 +92,9 @@ pub struct BreadcrumbText {
|
||||
pub highlights: Option<Vec<(Range<usize>, HighlightStyle)>>,
|
||||
}
|
||||
|
||||
pub trait Item: FocusableView + EventEmitter<ItemEvent> {
|
||||
pub trait Item: FocusableView + EventEmitter<Self::Event> {
|
||||
type Event;
|
||||
|
||||
fn deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
||||
fn workspace_deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
||||
fn navigate(&mut self, _: Box<dyn Any>, _: &mut ViewContext<Self>) -> bool {
|
||||
@@ -155,6 +157,8 @@ pub trait Item: FocusableView + EventEmitter<ItemEvent> {
|
||||
unimplemented!("reload() must be implemented if can_save() returns true")
|
||||
}
|
||||
|
||||
fn to_item_events(event: &Self::Event, f: impl FnMut(ItemEvent));
|
||||
|
||||
fn act_as_type<'a>(
|
||||
&'a self,
|
||||
type_id: TypeId,
|
||||
@@ -206,12 +210,12 @@ pub trait Item: FocusableView + EventEmitter<ItemEvent> {
|
||||
}
|
||||
|
||||
pub trait ItemHandle: 'static + Send {
|
||||
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle;
|
||||
fn subscribe_to_item_events(
|
||||
&self,
|
||||
cx: &mut WindowContext,
|
||||
handler: Box<dyn Fn(&ItemEvent, &mut WindowContext) + Send>,
|
||||
handler: Box<dyn Fn(ItemEvent, &mut WindowContext)>,
|
||||
) -> gpui::Subscription;
|
||||
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle;
|
||||
fn tab_tooltip_text(&self, cx: &AppContext) -> Option<SharedString>;
|
||||
fn tab_description(&self, detail: usize, cx: &AppContext) -> Option<SharedString>;
|
||||
fn tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement;
|
||||
@@ -285,20 +289,20 @@ impl dyn ItemHandle {
|
||||
}
|
||||
|
||||
impl<T: Item> ItemHandle for View<T> {
|
||||
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle {
|
||||
self.focus_handle(cx)
|
||||
}
|
||||
|
||||
fn subscribe_to_item_events(
|
||||
&self,
|
||||
cx: &mut WindowContext,
|
||||
handler: Box<dyn Fn(&ItemEvent, &mut WindowContext) + Send>,
|
||||
handler: Box<dyn Fn(ItemEvent, &mut WindowContext)>,
|
||||
) -> gpui::Subscription {
|
||||
cx.subscribe(self, move |_, event, cx| {
|
||||
handler(event, cx);
|
||||
T::to_item_events(event, |item_event| handler(item_event, cx));
|
||||
})
|
||||
}
|
||||
|
||||
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle {
|
||||
self.focus_handle(cx)
|
||||
}
|
||||
|
||||
fn tab_tooltip_text(&self, cx: &AppContext) -> Option<SharedString> {
|
||||
self.read(cx).tab_tooltip_text(cx)
|
||||
}
|
||||
@@ -461,7 +465,7 @@ impl<T: Item> ItemHandle for View<T> {
|
||||
}
|
||||
}
|
||||
|
||||
match event {
|
||||
T::to_item_events(event, |event| match event {
|
||||
ItemEvent::CloseItem => {
|
||||
pane.update(cx, |pane, cx| {
|
||||
pane.close_item_by_id(item.item_id(), crate::SaveIntent::Close, cx)
|
||||
@@ -489,7 +493,7 @@ impl<T: Item> ItemHandle for View<T> {
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
cx.on_blur(&self.focus_handle(cx), move |workspace, cx| {
|
||||
@@ -655,12 +659,7 @@ pub enum FollowEvent {
|
||||
Unfollow,
|
||||
}
|
||||
|
||||
pub trait FollowableEvents {
|
||||
fn to_follow_event(&self) -> Option<FollowEvent>;
|
||||
}
|
||||
|
||||
pub trait FollowableItem: Item {
|
||||
type FollowableEvent: FollowableEvents;
|
||||
fn remote_id(&self) -> Option<ViewId>;
|
||||
fn to_state_proto(&self, cx: &WindowContext) -> Option<proto::view::Variant>;
|
||||
fn from_state_proto(
|
||||
@@ -670,9 +669,10 @@ pub trait FollowableItem: Item {
|
||||
state: &mut Option<proto::view::Variant>,
|
||||
cx: &mut WindowContext,
|
||||
) -> Option<Task<Result<View<Self>>>>;
|
||||
fn to_follow_event(event: &Self::Event) -> Option<FollowEvent>;
|
||||
fn add_event_to_update_proto(
|
||||
&self,
|
||||
event: &Self::FollowableEvent,
|
||||
event: &Self::Event,
|
||||
update: &mut Option<proto::update_view::Variant>,
|
||||
cx: &WindowContext,
|
||||
) -> bool;
|
||||
@@ -683,7 +683,6 @@ pub trait FollowableItem: Item {
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Task<Result<()>>;
|
||||
fn is_project_item(&self, cx: &WindowContext) -> bool;
|
||||
|
||||
fn set_leader_peer_id(&mut self, leader_peer_id: Option<PeerId>, cx: &mut ViewContext<Self>);
|
||||
}
|
||||
|
||||
@@ -739,10 +738,7 @@ impl<T: FollowableItem> FollowableItemHandle for View<T> {
|
||||
}
|
||||
|
||||
fn to_follow_event(&self, event: &dyn Any) -> Option<FollowEvent> {
|
||||
event
|
||||
.downcast_ref()
|
||||
.map(T::FollowableEvent::to_follow_event)
|
||||
.flatten()
|
||||
T::to_follow_event(event.downcast_ref()?)
|
||||
}
|
||||
|
||||
fn apply_update_proto(
|
||||
@@ -929,6 +925,12 @@ pub mod test {
|
||||
}
|
||||
|
||||
impl Item for TestItem {
|
||||
type Event = ItemEvent;
|
||||
|
||||
fn to_item_events(event: &Self::Event, mut f: impl FnMut(ItemEvent)) {
|
||||
f(*event)
|
||||
}
|
||||
|
||||
fn tab_description(&self, detail: usize, _: &AppContext) -> Option<SharedString> {
|
||||
self.tab_descriptions.as_ref().and_then(|descriptions| {
|
||||
let description = *descriptions.get(detail).or_else(|| descriptions.last())?;
|
||||
|
||||
@@ -59,7 +59,6 @@ impl SharedScreen {
|
||||
}
|
||||
|
||||
impl EventEmitter<Event> for SharedScreen {}
|
||||
impl EventEmitter<ItemEvent> for SharedScreen {}
|
||||
|
||||
impl FocusableView for SharedScreen {
|
||||
fn focus_handle(&self, _: &AppContext) -> FocusHandle {
|
||||
@@ -79,9 +78,12 @@ impl Render for SharedScreen {
|
||||
}
|
||||
|
||||
impl Item for SharedScreen {
|
||||
type Event = Event;
|
||||
|
||||
fn tab_tooltip_text(&self, _: &AppContext) -> Option<SharedString> {
|
||||
Some(format!("{}'s screen", self.user.github_login).into())
|
||||
}
|
||||
|
||||
fn deactivated(&mut self, cx: &mut ViewContext<Self>) {
|
||||
if let Some(nav_history) = self.nav_history.as_mut() {
|
||||
nav_history.push::<()>(None, cx);
|
||||
@@ -111,4 +113,10 @@ impl Item for SharedScreen {
|
||||
let track = self.track.upgrade()?;
|
||||
Some(cx.build_view(|cx| Self::new(&track, self.peer_id, self.user.clone(), cx)))
|
||||
}
|
||||
|
||||
fn to_item_events(event: &Self::Event, mut f: impl FnMut(ItemEvent)) {
|
||||
match event {
|
||||
Event::Close => f(ItemEvent::CloseItem),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2625,8 +2625,6 @@ impl Workspace {
|
||||
update: proto::UpdateFollowers,
|
||||
cx: &mut AsyncWindowContext,
|
||||
) -> Result<()> {
|
||||
dbg!("process_leader_update", &update);
|
||||
|
||||
match update.variant.ok_or_else(|| anyhow!("invalid update"))? {
|
||||
proto::update_followers::Variant::UpdateActiveView(update_active_view) => {
|
||||
this.update(cx, |this, _| {
|
||||
@@ -3880,8 +3878,6 @@ impl WorkspaceStore {
|
||||
let leader_id = envelope.original_sender_id()?;
|
||||
let update = envelope.payload;
|
||||
|
||||
dbg!("handle_upate_followers");
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
for workspace in &this.workspaces {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
|
||||
Reference in New Issue
Block a user