Dedup channel views
Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
5888e7b214
commit
1ae54ca620
3 changed files with 94 additions and 86 deletions
|
@ -213,17 +213,12 @@ async fn test_channel_buffer_replica_ids(
|
||||||
assert_eq!(channel_buffer.buffer().read(cx).replica_id(), 0);
|
assert_eq!(channel_buffer.buffer().read(cx).replica_id(), 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
let channel_window_a = cx_a
|
let channel_window_a =
|
||||||
.add_window(|cx| ChannelView::new(project_a.clone(), channel_buffer_a.clone(), None, cx));
|
cx_a.add_window(|cx| ChannelView::new(project_a.clone(), channel_buffer_a.clone(), cx));
|
||||||
let channel_window_b = cx_b
|
let channel_window_b =
|
||||||
.add_window(|cx| ChannelView::new(project_b.clone(), channel_buffer_b.clone(), None, cx));
|
cx_b.add_window(|cx| ChannelView::new(project_b.clone(), channel_buffer_b.clone(), cx));
|
||||||
let channel_window_c = cx_c.add_window(|cx| {
|
let channel_window_c = cx_c.add_window(|cx| {
|
||||||
ChannelView::new(
|
ChannelView::new(separate_project_c.clone(), channel_buffer_c.clone(), cx)
|
||||||
separate_project_c.clone(),
|
|
||||||
channel_buffer_c.clone(),
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let channel_view_a = channel_window_a.root(cx_a);
|
let channel_view_a = channel_window_a.root(cx_a);
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
use channel::channel_buffer::{self, ChannelBuffer};
|
use anyhow::{anyhow, Result};
|
||||||
|
use channel::{
|
||||||
|
channel_buffer::{self, ChannelBuffer},
|
||||||
|
ChannelId,
|
||||||
|
};
|
||||||
use client::proto;
|
use client::proto;
|
||||||
use clock::ReplicaId;
|
use clock::ReplicaId;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
@ -6,15 +10,13 @@ use editor::Editor;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
elements::{ChildView, Label},
|
elements::{ChildView, Label},
|
||||||
AnyElement, AnyViewHandle, AppContext, Element, Entity, ModelHandle, Subscription, View,
|
AnyElement, AnyViewHandle, AppContext, Element, Entity, ModelHandle, Subscription, Task, View,
|
||||||
ViewContext, ViewHandle,
|
ViewContext, ViewHandle,
|
||||||
};
|
};
|
||||||
use language::Language;
|
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use std::sync::Arc;
|
|
||||||
use workspace::{
|
use workspace::{
|
||||||
item::{FollowableItem, Item, ItemHandle},
|
item::{FollowableItem, Item, ItemHandle},
|
||||||
register_followable_item, ViewId,
|
register_followable_item, Pane, ViewId, Workspace, WorkspaceId,
|
||||||
};
|
};
|
||||||
|
|
||||||
actions!(channel_view, [Deploy]);
|
actions!(channel_view, [Deploy]);
|
||||||
|
@ -32,14 +34,47 @@ pub struct ChannelView {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChannelView {
|
impl ChannelView {
|
||||||
|
pub fn open(
|
||||||
|
channel_id: ChannelId,
|
||||||
|
pane: ViewHandle<Pane>,
|
||||||
|
workspace: ViewHandle<Workspace>,
|
||||||
|
cx: &mut AppContext,
|
||||||
|
) -> Task<Result<ViewHandle<Self>>> {
|
||||||
|
let workspace = workspace.read(cx);
|
||||||
|
let project = workspace.project().to_owned();
|
||||||
|
let channel_store = workspace.app_state().channel_store.clone();
|
||||||
|
let markdown = workspace
|
||||||
|
.app_state()
|
||||||
|
.languages
|
||||||
|
.language_for_name("Markdown");
|
||||||
|
let channel_buffer =
|
||||||
|
channel_store.update(cx, |store, cx| store.open_channel_buffer(channel_id, cx));
|
||||||
|
|
||||||
|
cx.spawn(|mut cx| async move {
|
||||||
|
let channel_buffer = channel_buffer.await?;
|
||||||
|
let markdown = markdown.await?;
|
||||||
|
channel_buffer.update(&mut cx, |buffer, cx| {
|
||||||
|
buffer.buffer().update(cx, |buffer, cx| {
|
||||||
|
buffer.set_language(Some(markdown), cx);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
pane.update(&mut cx, |pane, cx| {
|
||||||
|
pane.items_of_type::<Self>()
|
||||||
|
.find(|channel_view| channel_view.read(cx).channel_buffer == channel_buffer)
|
||||||
|
.unwrap_or_else(|| cx.add_view(|cx| Self::new(project, channel_buffer, cx)))
|
||||||
|
})
|
||||||
|
.ok_or_else(|| anyhow!("pane was dropped"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
project: ModelHandle<Project>,
|
project: ModelHandle<Project>,
|
||||||
channel_buffer: ModelHandle<ChannelBuffer>,
|
channel_buffer: ModelHandle<ChannelBuffer>,
|
||||||
language: Option<Arc<Language>>,
|
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let buffer = channel_buffer.read(cx).buffer();
|
let buffer = channel_buffer.read(cx).buffer();
|
||||||
buffer.update(cx, |buffer, cx| buffer.set_language(language, cx));
|
// buffer.update(cx, |buffer, cx| buffer.set_language(language, cx));
|
||||||
let editor = cx.add_view(|cx| Editor::for_buffer(buffer, None, cx));
|
let editor = cx.add_view(|cx| Editor::for_buffer(buffer, None, cx));
|
||||||
let _editor_event_subscription = cx.subscribe(&editor, |_, _, e, cx| cx.emit(e.clone()));
|
let _editor_event_subscription = cx.subscribe(&editor, |_, _, e, cx| cx.emit(e.clone()));
|
||||||
|
|
||||||
|
@ -157,6 +192,14 @@ impl Item for ChannelView {
|
||||||
});
|
});
|
||||||
Label::new(channel_name, style.label.to_owned()).into_any()
|
Label::new(channel_name, style.label.to_owned()).into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_on_split(&self, _: WorkspaceId, cx: &mut ViewContext<Self>) -> Option<Self> {
|
||||||
|
Some(Self::new(
|
||||||
|
self.project.clone(),
|
||||||
|
self.channel_buffer.clone(),
|
||||||
|
cx,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FollowableItem for ChannelView {
|
impl FollowableItem for ChannelView {
|
||||||
|
@ -180,7 +223,7 @@ impl FollowableItem for ChannelView {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_state_proto(
|
fn from_state_proto(
|
||||||
_: ViewHandle<workspace::Pane>,
|
pane: ViewHandle<workspace::Pane>,
|
||||||
workspace: ViewHandle<workspace::Workspace>,
|
workspace: ViewHandle<workspace::Workspace>,
|
||||||
remote_id: workspace::ViewId,
|
remote_id: workspace::ViewId,
|
||||||
state: &mut Option<proto::view::Variant>,
|
state: &mut Option<proto::view::Variant>,
|
||||||
|
@ -189,31 +232,17 @@ impl FollowableItem for ChannelView {
|
||||||
let Some(proto::view::Variant::ChannelView(_)) = state else { return None };
|
let Some(proto::view::Variant::ChannelView(_)) = state else { return None };
|
||||||
let Some(proto::view::Variant::ChannelView(state)) = state.take() else { unreachable!() };
|
let Some(proto::view::Variant::ChannelView(state)) = state.take() else { unreachable!() };
|
||||||
|
|
||||||
let channel_store = &workspace.read(cx).app_state().channel_store.clone();
|
let open = ChannelView::open(state.channel_id, pane, workspace, cx);
|
||||||
let open_channel_buffer = channel_store.update(cx, |store, cx| {
|
|
||||||
store.open_channel_buffer(state.channel_id, cx)
|
|
||||||
});
|
|
||||||
let project = workspace.read(cx).project().to_owned();
|
|
||||||
let language = workspace.read(cx).app_state().languages.clone();
|
|
||||||
let get_markdown = language.language_for_name("Markdown");
|
|
||||||
|
|
||||||
Some(cx.spawn(|mut cx| async move {
|
Some(cx.spawn(|mut cx| async move {
|
||||||
let channel_buffer = open_channel_buffer.await?;
|
let this = open.await?;
|
||||||
let markdown = get_markdown.await?;
|
|
||||||
|
|
||||||
let this = workspace
|
let task = this
|
||||||
.update(&mut cx, move |_, cx| {
|
.update(&mut cx, |this, cx| {
|
||||||
cx.add_view(|cx| {
|
|
||||||
let mut this = Self::new(project, channel_buffer, Some(markdown), cx);
|
|
||||||
this.remote_id = Some(remote_id);
|
this.remote_id = Some(remote_id);
|
||||||
this
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.ok_or_else(|| anyhow::anyhow!("workspace dropped"))?;
|
|
||||||
|
|
||||||
if let Some(state) = state.editor {
|
if let Some(state) = state.editor {
|
||||||
let task = this.update(&mut cx, |this, cx| {
|
Some(this.editor.update(cx, |editor, cx| {
|
||||||
this.editor.update(cx, |editor, cx| {
|
|
||||||
editor.apply_update_proto(
|
editor.apply_update_proto(
|
||||||
&this.project,
|
&this.project,
|
||||||
proto::update_view::Variant::Editor(proto::update_view::Editor {
|
proto::update_view::Variant::Editor(proto::update_view::Editor {
|
||||||
|
@ -226,12 +255,16 @@ impl FollowableItem for ChannelView {
|
||||||
}),
|
}),
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
})
|
})
|
||||||
});
|
.ok_or_else(|| anyhow!("window was closed"))?;
|
||||||
|
|
||||||
if let Some(task) = task {
|
if let Some(task) = task {
|
||||||
task.await?;
|
task.await?;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Ok(this)
|
Ok(this)
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -2220,39 +2220,19 @@ impl CollabPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_channel_buffer(&mut self, action: &OpenChannelBuffer, cx: &mut ViewContext<Self>) {
|
fn open_channel_buffer(&mut self, action: &OpenChannelBuffer, cx: &mut ViewContext<Self>) {
|
||||||
let workspace = self.workspace;
|
if let Some(workspace) = self.workspace.upgrade(cx) {
|
||||||
let open = self.channel_store.update(cx, |channel_store, cx| {
|
let pane = workspace.read(cx).active_pane().clone();
|
||||||
channel_store.open_channel_buffer(action.channel_id, cx)
|
let channel_view = ChannelView::open(action.channel_id, pane.clone(), workspace, cx);
|
||||||
});
|
|
||||||
|
|
||||||
cx.spawn(|_, mut cx| async move {
|
cx.spawn(|_, mut cx| async move {
|
||||||
let channel_buffer = open.await?;
|
let channel_view = channel_view.await?;
|
||||||
|
pane.update(&mut cx, |pane, cx| {
|
||||||
let markdown = workspace
|
pane.add_item(Box::new(channel_view), true, true, None, cx)
|
||||||
.read_with(&cx, |workspace, _| {
|
|
||||||
workspace
|
|
||||||
.app_state()
|
|
||||||
.languages
|
|
||||||
.language_for_name("Markdown")
|
|
||||||
})?
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
workspace.update(&mut cx, |workspace, cx| {
|
|
||||||
let channel_view = cx.add_view(|cx| {
|
|
||||||
ChannelView::new(
|
|
||||||
workspace.project().to_owned(),
|
|
||||||
channel_buffer,
|
|
||||||
Some(markdown),
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
workspace.add_item(Box::new(channel_view), cx);
|
|
||||||
})?;
|
|
||||||
|
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn show_inline_context_menu(&mut self, _: &menu::ShowContextMenu, cx: &mut ViewContext<Self>) {
|
fn show_inline_context_menu(&mut self, _: &menu::ShowContextMenu, cx: &mut ViewContext<Self>) {
|
||||||
let Some(channel) = self.selected_channel() else {
|
let Some(channel) = self.selected_channel() else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue