Move persistence and restoration logic from workspace into project
Co-authored-by: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
parent
6a3a3a1124
commit
afdd386057
2 changed files with 81 additions and 78 deletions
|
@ -552,6 +552,50 @@ impl Project {
|
|||
project
|
||||
}
|
||||
|
||||
pub fn restore_state(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
||||
if self.is_remote() {
|
||||
return Task::ready(Ok(()));
|
||||
}
|
||||
|
||||
let db = self.project_store.read(cx).db.clone();
|
||||
let project_path_keys = self.project_path_keys(cx);
|
||||
let should_be_public = cx.background().spawn(async move {
|
||||
let values = db.read(project_path_keys)?;
|
||||
anyhow::Ok(values.into_iter().all(|e| e.is_some()))
|
||||
});
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let public = should_be_public.await.log_err().unwrap_or(false);
|
||||
this.update(&mut cx, |this, cx| {
|
||||
if let ProjectClientState::Local { public_tx, .. } = &mut this.client_state {
|
||||
let mut public_tx = public_tx.borrow_mut();
|
||||
if *public_tx != public {
|
||||
*public_tx = public;
|
||||
drop(public_tx);
|
||||
this.metadata_changed(false, cx);
|
||||
}
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn persist_state(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
||||
if self.is_remote() {
|
||||
return Task::ready(Ok(()));
|
||||
}
|
||||
|
||||
let db = self.project_store.read(cx).db.clone();
|
||||
let project_path_keys = self.project_path_keys(cx);
|
||||
let public = self.is_public();
|
||||
cx.background().spawn(async move {
|
||||
if public {
|
||||
db.write(project_path_keys.into_iter().map(|key| (key, &[])))
|
||||
} else {
|
||||
db.delete(project_path_keys)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn buffer_for_id(&self, remote_id: u64, cx: &AppContext) -> Option<ModelHandle<Buffer>> {
|
||||
self.opened_buffers
|
||||
.get(&remote_id)
|
||||
|
@ -633,8 +677,12 @@ impl Project {
|
|||
|
||||
pub fn set_public(&mut self, is_public: bool, cx: &mut ModelContext<Self>) {
|
||||
if let ProjectClientState::Local { public_tx, .. } = &mut self.client_state {
|
||||
*public_tx.borrow_mut() = is_public;
|
||||
self.metadata_changed(cx);
|
||||
let mut public_tx = public_tx.borrow_mut();
|
||||
if *public_tx != is_public {
|
||||
*public_tx = is_public;
|
||||
drop(public_tx);
|
||||
self.metadata_changed(true, cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -674,7 +722,7 @@ impl Project {
|
|||
*remote_id_tx.borrow_mut() = None;
|
||||
}
|
||||
this.subscriptions.clear();
|
||||
this.metadata_changed(cx);
|
||||
this.metadata_changed(false, cx);
|
||||
});
|
||||
response.map(drop)
|
||||
});
|
||||
|
@ -698,7 +746,7 @@ impl Project {
|
|||
*remote_id_tx.borrow_mut() = Some(remote_id);
|
||||
}
|
||||
|
||||
this.metadata_changed(cx);
|
||||
this.metadata_changed(false, cx);
|
||||
cx.emit(Event::RemoteIdChanged(Some(remote_id)));
|
||||
this.subscriptions
|
||||
.push(this.client.add_model_for_remote_entity(remote_id, cx));
|
||||
|
@ -761,7 +809,7 @@ impl Project {
|
|||
}
|
||||
}
|
||||
|
||||
fn metadata_changed(&mut self, cx: &mut ModelContext<Self>) {
|
||||
fn metadata_changed(&mut self, persist: bool, cx: &mut ModelContext<Self>) {
|
||||
if let ProjectClientState::Local {
|
||||
remote_id_rx,
|
||||
public_rx,
|
||||
|
@ -786,6 +834,9 @@ impl Project {
|
|||
}
|
||||
|
||||
self.project_store.update(cx, |_, cx| cx.notify());
|
||||
if persist {
|
||||
self.persist_state(cx).detach_and_log_err(cx);
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
@ -823,6 +874,25 @@ impl Project {
|
|||
.map(|tree| tree.read(cx).root_name())
|
||||
}
|
||||
|
||||
fn project_path_keys(&self, cx: &AppContext) -> Vec<String> {
|
||||
self.worktrees
|
||||
.iter()
|
||||
.filter_map(|worktree| {
|
||||
worktree.upgrade(&cx).map(|worktree| {
|
||||
format!(
|
||||
"public-project-path:{}",
|
||||
worktree
|
||||
.read(cx)
|
||||
.as_local()
|
||||
.unwrap()
|
||||
.abs_path()
|
||||
.to_string_lossy()
|
||||
)
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub fn worktree_for_id(
|
||||
&self,
|
||||
id: WorktreeId,
|
||||
|
@ -3769,7 +3839,7 @@ impl Project {
|
|||
false
|
||||
}
|
||||
});
|
||||
self.metadata_changed(cx);
|
||||
self.metadata_changed(true, cx);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
|
@ -3799,7 +3869,7 @@ impl Project {
|
|||
self.worktrees
|
||||
.push(WorktreeHandle::Weak(worktree.downgrade()));
|
||||
}
|
||||
self.metadata_changed(cx);
|
||||
self.metadata_changed(true, cx);
|
||||
cx.emit(Event::WorktreeAdded);
|
||||
cx.notify();
|
||||
}
|
||||
|
@ -4122,7 +4192,7 @@ impl Project {
|
|||
}
|
||||
}
|
||||
|
||||
this.metadata_changed(cx);
|
||||
this.metadata_changed(true, cx);
|
||||
for (id, _) in old_worktrees_by_id {
|
||||
cx.emit(Event::WorktreeRemoved(id));
|
||||
}
|
||||
|
@ -5274,56 +5344,6 @@ impl ProjectStore {
|
|||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn are_all_project_paths_public(
|
||||
&self,
|
||||
project: &Project,
|
||||
cx: &AppContext,
|
||||
) -> Task<Result<bool>> {
|
||||
let project_path_keys = self.project_path_keys(project, cx);
|
||||
let db = self.db.clone();
|
||||
cx.background().spawn(async move {
|
||||
let values = db.read(project_path_keys)?;
|
||||
Ok(values.into_iter().all(|e| e.is_some()))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_project_paths_public(
|
||||
&self,
|
||||
project: &Project,
|
||||
public: bool,
|
||||
cx: &AppContext,
|
||||
) -> Task<Result<()>> {
|
||||
let project_path_keys = self.project_path_keys(project, cx);
|
||||
let db = self.db.clone();
|
||||
cx.background().spawn(async move {
|
||||
if public {
|
||||
db.write(project_path_keys.into_iter().map(|key| (key, &[])))
|
||||
} else {
|
||||
db.delete(project_path_keys)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn project_path_keys(&self, project: &Project, cx: &AppContext) -> Vec<String> {
|
||||
project
|
||||
.worktrees
|
||||
.iter()
|
||||
.filter_map(|worktree| {
|
||||
worktree.upgrade(&cx).map(|worktree| {
|
||||
format!(
|
||||
"public-project-path:{}",
|
||||
worktree
|
||||
.read(cx)
|
||||
.as_local()
|
||||
.unwrap()
|
||||
.abs_path()
|
||||
.to_string_lossy()
|
||||
)
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
}
|
||||
|
||||
impl WorktreeHandle {
|
||||
|
|
|
@ -1057,12 +1057,6 @@ impl Workspace {
|
|||
project.update(cx, |project, cx| {
|
||||
let public = !project.is_public();
|
||||
project.set_public(public, cx);
|
||||
project.project_store().update(cx, |store, cx| {
|
||||
store
|
||||
.set_project_paths_public(project, public, cx)
|
||||
.detach_and_log_err(cx);
|
||||
cx.notify();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2454,21 +2448,10 @@ pub fn open_paths(
|
|||
.await;
|
||||
|
||||
if let Some(project) = new_project {
|
||||
let public = project
|
||||
.read_with(&cx, |project, cx| {
|
||||
app_state
|
||||
.project_store
|
||||
.read(cx)
|
||||
.are_all_project_paths_public(project, cx)
|
||||
})
|
||||
project
|
||||
.update(&mut cx, |project, cx| project.restore_state(cx))
|
||||
.await
|
||||
.log_err()
|
||||
.unwrap_or(false);
|
||||
if public {
|
||||
project.update(&mut cx, |project, cx| {
|
||||
project.set_public(true, cx);
|
||||
});
|
||||
}
|
||||
.log_err();
|
||||
}
|
||||
|
||||
(workspace, items)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue