diff --git a/crates/collab_ui/src/collab_panel.rs b/crates/collab_ui/src/collab_panel.rs index 6df8baaacc..7b96bc4af7 100644 --- a/crates/collab_ui/src/collab_panel.rs +++ b/crates/collab_ui/src/collab_panel.rs @@ -378,16 +378,27 @@ impl CollabPanel { workspace: WeakEntity, mut cx: AsyncWindowContext, ) -> anyhow::Result> { - let serialized_panel = cx - .background_spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) }) - .await - .map_err(|_| anyhow::anyhow!("Failed to read collaboration panel from key value store")) - .log_err() + let serialized_panel = match workspace + .read_with(&cx, |workspace, _| { + CollabPanel::serialization_key(workspace) + }) + .ok() .flatten() - .map(|panel| serde_json::from_str::(&panel)) - .transpose() - .log_err() - .flatten(); + { + Some(serialization_key) => cx + .background_spawn(async move { KEY_VALUE_STORE.read_kvp(&serialization_key) }) + .await + .map_err(|_| { + anyhow::anyhow!("Failed to read collaboration panel from key value store") + }) + .log_err() + .flatten() + .map(|panel| serde_json::from_str::(&panel)) + .transpose() + .log_err() + .flatten(), + None => None, + }; workspace.update_in(&mut cx, |workspace, window, cx| { let panel = CollabPanel::new(workspace, window, cx); @@ -407,14 +418,30 @@ impl CollabPanel { }) } + fn serialization_key(workspace: &Workspace) -> Option { + workspace + .database_id() + .map(|id| i64::from(id).to_string()) + .or(workspace.session_id()) + .map(|id| format!("{}-{:?}", COLLABORATION_PANEL_KEY, id)) + } + fn serialize(&mut self, cx: &mut Context) { + let Some(serialization_key) = self + .workspace + .update(cx, |workspace, _| CollabPanel::serialization_key(workspace)) + .ok() + .flatten() + else { + return; + }; let width = self.width; let collapsed_channels = self.collapsed_channels.clone(); self.pending_serialization = cx.background_spawn( async move { KEY_VALUE_STORE .write_kvp( - COLLABORATION_PANEL_KEY.into(), + serialization_key, serde_json::to_string(&SerializedCollabPanel { width, collapsed_channels: Some( @@ -2999,10 +3026,12 @@ impl Panel for CollabPanel { .unwrap_or_else(|| CollaborationPanelSettings::get_global(cx).default_width) } - fn set_size(&mut self, size: Option, _: &mut Window, cx: &mut Context) { + fn set_size(&mut self, size: Option, window: &mut Window, cx: &mut Context) { self.width = size; - self.serialize(cx); cx.notify(); + cx.defer_in(window, |this, _, cx| { + this.serialize(cx); + }); } fn icon(&self, _window: &Window, cx: &App) -> Option { diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index 026fa45b71..b577408f06 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -680,16 +680,25 @@ impl OutlinePanel { workspace: WeakEntity, mut cx: AsyncWindowContext, ) -> anyhow::Result> { - let serialized_panel = cx - .background_spawn(async move { KEY_VALUE_STORE.read_kvp(OUTLINE_PANEL_KEY) }) - .await - .context("loading outline panel") - .log_err() + let serialized_panel = match workspace + .read_with(&cx, |workspace, _| { + OutlinePanel::serialization_key(workspace) + }) + .ok() .flatten() - .map(|panel| serde_json::from_str::(&panel)) - .transpose() - .log_err() - .flatten(); + { + Some(serialization_key) => cx + .background_spawn(async move { KEY_VALUE_STORE.read_kvp(&serialization_key) }) + .await + .context("loading outline panel") + .log_err() + .flatten() + .map(|panel| serde_json::from_str::(&panel)) + .transpose() + .log_err() + .flatten(), + None => None, + }; workspace.update_in(&mut cx, |workspace, window, cx| { let panel = Self::new(workspace, window, cx); @@ -845,14 +854,32 @@ impl OutlinePanel { outline_panel } + fn serialization_key(workspace: &Workspace) -> Option { + workspace + .database_id() + .map(|id| i64::from(id).to_string()) + .or(workspace.session_id()) + .map(|id| format!("{}-{:?}", OUTLINE_PANEL_KEY, id)) + } + fn serialize(&mut self, cx: &mut Context) { + let Some(serialization_key) = self + .workspace + .update(cx, |workspace, _| { + OutlinePanel::serialization_key(workspace) + }) + .ok() + .flatten() + else { + return; + }; let width = self.width; let active = Some(self.active); self.pending_serialization = cx.background_spawn( async move { KEY_VALUE_STORE .write_kvp( - OUTLINE_PANEL_KEY.into(), + serialization_key, serde_json::to_string(&SerializedOutlinePanel { width, active })?, ) .await?; @@ -4803,10 +4830,12 @@ impl Panel for OutlinePanel { .unwrap_or_else(|| OutlinePanelSettings::get_global(cx).default_width) } - fn set_size(&mut self, size: Option, _: &mut Window, cx: &mut Context) { + fn set_size(&mut self, size: Option, window: &mut Window, cx: &mut Context) { self.width = size; - self.serialize(cx); cx.notify(); + cx.defer_in(window, |this, _, cx| { + this.serialize(cx); + }); } fn icon(&self, _: &Window, cx: &App) -> Option { diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 2d55fa0b5f..d820c3693d 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -592,16 +592,25 @@ impl ProjectPanel { workspace: WeakEntity, mut cx: AsyncWindowContext, ) -> Result> { - let serialized_panel = cx - .background_spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) }) - .await - .map_err(|e| anyhow!("Failed to load project panel: {}", e)) - .log_err() + let serialized_panel = match workspace + .read_with(&cx, |workspace, _| { + ProjectPanel::serialization_key(workspace) + }) + .ok() .flatten() - .map(|panel| serde_json::from_str::(&panel)) - .transpose() - .log_err() - .flatten(); + { + Some(serialization_key) => cx + .background_spawn(async move { KEY_VALUE_STORE.read_kvp(&serialization_key) }) + .await + .map_err(|e| anyhow!("Failed to load project panel: {}", e)) + .log_err() + .flatten() + .map(|panel| serde_json::from_str::(&panel)) + .transpose() + .log_err() + .flatten(), + None => None, + }; workspace.update_in(&mut cx, |workspace, window, cx| { let panel = ProjectPanel::new(workspace, window, cx); @@ -673,13 +682,31 @@ impl ProjectPanel { .or_insert(diagnostic_severity); } + fn serialization_key(workspace: &Workspace) -> Option { + workspace + .database_id() + .map(|id| i64::from(id).to_string()) + .or(workspace.session_id()) + .map(|id| format!("{}-{:?}", PROJECT_PANEL_KEY, id)) + } + fn serialize(&mut self, cx: &mut Context) { + let Some(serialization_key) = self + .workspace + .update(cx, |workspace, _| { + ProjectPanel::serialization_key(workspace) + }) + .ok() + .flatten() + else { + return; + }; let width = self.width; self.pending_serialization = cx.background_spawn( async move { KEY_VALUE_STORE .write_kvp( - PROJECT_PANEL_KEY.into(), + serialization_key, serde_json::to_string(&SerializedProjectPanel { width })?, ) .await?; @@ -4967,10 +4994,12 @@ impl Panel for ProjectPanel { .unwrap_or_else(|| ProjectPanelSettings::get_global(cx).default_width) } - fn set_size(&mut self, size: Option, _: &mut Window, cx: &mut Context) { + fn set_size(&mut self, size: Option, window: &mut Window, cx: &mut Context) { self.width = size; - self.serialize(cx); cx.notify(); + cx.defer_in(window, |this, _, cx| { + this.serialize(cx); + }); } fn icon(&self, _: &Window, cx: &App) -> Option {