Enable reload of images in image viewer (#20374)
Closes #11529 Release Notes: - Fixed an issue where the image preview would not update when the underlying file changed --------- Co-authored-by: Bennet <bennet@zed.dev>
This commit is contained in:
parent
f3320998a8
commit
0dbda71423
10 changed files with 840 additions and 109 deletions
|
@ -2,6 +2,7 @@ pub mod buffer_store;
|
|||
mod color_extractor;
|
||||
pub mod connection_manager;
|
||||
pub mod debounced_delay;
|
||||
pub mod image_store;
|
||||
pub mod lsp_command;
|
||||
pub mod lsp_ext_command;
|
||||
pub mod lsp_store;
|
||||
|
@ -35,6 +36,8 @@ use futures::{
|
|||
future::try_join_all,
|
||||
StreamExt,
|
||||
};
|
||||
pub use image_store::{ImageItem, ImageStore};
|
||||
use image_store::{ImageItemEvent, ImageStoreEvent};
|
||||
|
||||
use git::{blame::Blame, repository::GitRepository};
|
||||
use gpui::{
|
||||
|
@ -146,6 +149,7 @@ pub struct Project {
|
|||
client_subscriptions: Vec<client::Subscription>,
|
||||
worktree_store: Model<WorktreeStore>,
|
||||
buffer_store: Model<BufferStore>,
|
||||
image_store: Model<ImageStore>,
|
||||
lsp_store: Model<LspStore>,
|
||||
_subscriptions: Vec<gpui::Subscription>,
|
||||
buffers_needing_diff: HashSet<WeakModel<Buffer>>,
|
||||
|
@ -205,10 +209,11 @@ enum BufferOrderedMessage {
|
|||
|
||||
#[derive(Debug)]
|
||||
enum ProjectClientState {
|
||||
/// Single-player mode.
|
||||
Local,
|
||||
Shared {
|
||||
remote_id: u64,
|
||||
},
|
||||
/// Multi-player mode but still a local project.
|
||||
Shared { remote_id: u64 },
|
||||
/// Multi-player mode but working on a remote project.
|
||||
Remote {
|
||||
sharing_has_stopped: bool,
|
||||
capability: Capability,
|
||||
|
@ -606,6 +611,10 @@ impl Project {
|
|||
cx.subscribe(&buffer_store, Self::on_buffer_store_event)
|
||||
.detach();
|
||||
|
||||
let image_store = cx.new_model(|cx| ImageStore::local(worktree_store.clone(), cx));
|
||||
cx.subscribe(&image_store, Self::on_image_store_event)
|
||||
.detach();
|
||||
|
||||
let prettier_store = cx.new_model(|cx| {
|
||||
PrettierStore::new(
|
||||
node.clone(),
|
||||
|
@ -666,6 +675,7 @@ impl Project {
|
|||
collaborators: Default::default(),
|
||||
worktree_store,
|
||||
buffer_store,
|
||||
image_store,
|
||||
lsp_store,
|
||||
join_project_response_message_id: 0,
|
||||
client_state: ProjectClientState::Local,
|
||||
|
@ -729,6 +739,14 @@ impl Project {
|
|||
cx,
|
||||
)
|
||||
});
|
||||
let image_store = cx.new_model(|cx| {
|
||||
ImageStore::remote(
|
||||
worktree_store.clone(),
|
||||
ssh.read(cx).proto_client(),
|
||||
SSH_PROJECT_ID,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
cx.subscribe(&buffer_store, Self::on_buffer_store_event)
|
||||
.detach();
|
||||
|
||||
|
@ -774,6 +792,7 @@ impl Project {
|
|||
collaborators: Default::default(),
|
||||
worktree_store,
|
||||
buffer_store,
|
||||
image_store,
|
||||
lsp_store,
|
||||
join_project_response_message_id: 0,
|
||||
client_state: ProjectClientState::Local,
|
||||
|
@ -920,6 +939,9 @@ impl Project {
|
|||
let buffer_store = cx.new_model(|cx| {
|
||||
BufferStore::remote(worktree_store.clone(), client.clone().into(), remote_id, cx)
|
||||
})?;
|
||||
let image_store = cx.new_model(|cx| {
|
||||
ImageStore::remote(worktree_store.clone(), client.clone().into(), remote_id, cx)
|
||||
})?;
|
||||
|
||||
let lsp_store = cx.new_model(|cx| {
|
||||
let mut lsp_store = LspStore::new_remote(
|
||||
|
@ -982,6 +1004,7 @@ impl Project {
|
|||
let mut this = Self {
|
||||
buffer_ordered_messages_tx: tx,
|
||||
buffer_store: buffer_store.clone(),
|
||||
image_store,
|
||||
worktree_store: worktree_store.clone(),
|
||||
lsp_store: lsp_store.clone(),
|
||||
active_entry: None,
|
||||
|
@ -1783,7 +1806,7 @@ impl Project {
|
|||
path: impl Into<ProjectPath>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
if (self.is_via_collab() || self.is_via_ssh()) && self.is_disconnected(cx) {
|
||||
if self.is_disconnected(cx) {
|
||||
return Task::ready(Err(anyhow!(ErrorCode::Disconnected)));
|
||||
}
|
||||
|
||||
|
@ -1879,6 +1902,20 @@ impl Project {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn open_image(
|
||||
&mut self,
|
||||
path: impl Into<ProjectPath>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Model<ImageItem>>> {
|
||||
if self.is_disconnected(cx) {
|
||||
return Task::ready(Err(anyhow!(ErrorCode::Disconnected)));
|
||||
}
|
||||
|
||||
self.image_store.update(cx, |image_store, cx| {
|
||||
image_store.open_image(path.into(), cx)
|
||||
})
|
||||
}
|
||||
|
||||
async fn send_buffer_ordered_messages(
|
||||
this: WeakModel<Self>,
|
||||
rx: UnboundedReceiver<BufferOrderedMessage>,
|
||||
|
@ -2013,6 +2050,22 @@ impl Project {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_image_store_event(
|
||||
&mut self,
|
||||
_: Model<ImageStore>,
|
||||
event: &ImageStoreEvent,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
match event {
|
||||
ImageStoreEvent::ImageAdded(image) => {
|
||||
cx.subscribe(image, |this, image, event, cx| {
|
||||
this.on_image_event(image, event, cx);
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_lsp_store_event(
|
||||
&mut self,
|
||||
_: Model<LspStore>,
|
||||
|
@ -2253,6 +2306,25 @@ impl Project {
|
|||
None
|
||||
}
|
||||
|
||||
fn on_image_event(
|
||||
&mut self,
|
||||
image: Model<ImageItem>,
|
||||
event: &ImageItemEvent,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Option<()> {
|
||||
match event {
|
||||
ImageItemEvent::ReloadNeeded => {
|
||||
if !self.is_via_collab() {
|
||||
self.reload_images([image.clone()].into_iter().collect(), cx)
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn request_buffer_diff_recalculation(
|
||||
&mut self,
|
||||
buffer: &Model<Buffer>,
|
||||
|
@ -2466,6 +2538,15 @@ impl Project {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn reload_images(
|
||||
&self,
|
||||
images: HashSet<Model<ImageItem>>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<()>> {
|
||||
self.image_store
|
||||
.update(cx, |image_store, cx| image_store.reload_images(images, cx))
|
||||
}
|
||||
|
||||
pub fn format(
|
||||
&mut self,
|
||||
buffers: HashSet<Model<Buffer>>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue