Update panels serialization from global to per-workspace (#30652)
Closes #27834 This PR changes project panel, outline panel and collab panel serialization from global to per-workspace, so configurations are restored only within the same workspace. Handles remote workspaces too. Opening a new window will start with a fresh panel defaults e.g. width. Release Notes: - Improved project panel, outline panel, and collab panel to persist width on a per-workspace basis. New windows will use the width specified in the `default_width` setting.
This commit is contained in:
parent
1ace5a27bc
commit
f98c6fb2cf
3 changed files with 123 additions and 36 deletions
|
@ -378,16 +378,27 @@ impl CollabPanel {
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
mut cx: AsyncWindowContext,
|
mut cx: AsyncWindowContext,
|
||||||
) -> anyhow::Result<Entity<Self>> {
|
) -> anyhow::Result<Entity<Self>> {
|
||||||
let serialized_panel = cx
|
let serialized_panel = match workspace
|
||||||
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
|
.read_with(&cx, |workspace, _| {
|
||||||
.await
|
CollabPanel::serialization_key(workspace)
|
||||||
.map_err(|_| anyhow::anyhow!("Failed to read collaboration panel from key value store"))
|
})
|
||||||
.log_err()
|
.ok()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|panel| serde_json::from_str::<SerializedCollabPanel>(&panel))
|
{
|
||||||
.transpose()
|
Some(serialization_key) => cx
|
||||||
.log_err()
|
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(&serialization_key) })
|
||||||
.flatten();
|
.await
|
||||||
|
.map_err(|_| {
|
||||||
|
anyhow::anyhow!("Failed to read collaboration panel from key value store")
|
||||||
|
})
|
||||||
|
.log_err()
|
||||||
|
.flatten()
|
||||||
|
.map(|panel| serde_json::from_str::<SerializedCollabPanel>(&panel))
|
||||||
|
.transpose()
|
||||||
|
.log_err()
|
||||||
|
.flatten(),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
workspace.update_in(&mut cx, |workspace, window, cx| {
|
workspace.update_in(&mut cx, |workspace, window, cx| {
|
||||||
let panel = CollabPanel::new(workspace, window, cx);
|
let panel = CollabPanel::new(workspace, window, cx);
|
||||||
|
@ -407,14 +418,30 @@ impl CollabPanel {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialization_key(workspace: &Workspace) -> Option<String> {
|
||||||
|
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<Self>) {
|
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||||
|
let Some(serialization_key) = self
|
||||||
|
.workspace
|
||||||
|
.update(cx, |workspace, _| CollabPanel::serialization_key(workspace))
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
let collapsed_channels = self.collapsed_channels.clone();
|
let collapsed_channels = self.collapsed_channels.clone();
|
||||||
self.pending_serialization = cx.background_spawn(
|
self.pending_serialization = cx.background_spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
COLLABORATION_PANEL_KEY.into(),
|
serialization_key,
|
||||||
serde_json::to_string(&SerializedCollabPanel {
|
serde_json::to_string(&SerializedCollabPanel {
|
||||||
width,
|
width,
|
||||||
collapsed_channels: Some(
|
collapsed_channels: Some(
|
||||||
|
@ -2999,10 +3026,12 @@ impl Panel for CollabPanel {
|
||||||
.unwrap_or_else(|| CollaborationPanelSettings::get_global(cx).default_width)
|
.unwrap_or_else(|| CollaborationPanelSettings::get_global(cx).default_width)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_size(&mut self, size: Option<Pixels>, _: &mut Window, cx: &mut Context<Self>) {
|
fn set_size(&mut self, size: Option<Pixels>, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
self.width = size;
|
self.width = size;
|
||||||
self.serialize(cx);
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
cx.defer_in(window, |this, _, cx| {
|
||||||
|
this.serialize(cx);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon(&self, _window: &Window, cx: &App) -> Option<ui::IconName> {
|
fn icon(&self, _window: &Window, cx: &App) -> Option<ui::IconName> {
|
||||||
|
|
|
@ -680,16 +680,25 @@ impl OutlinePanel {
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
mut cx: AsyncWindowContext,
|
mut cx: AsyncWindowContext,
|
||||||
) -> anyhow::Result<Entity<Self>> {
|
) -> anyhow::Result<Entity<Self>> {
|
||||||
let serialized_panel = cx
|
let serialized_panel = match workspace
|
||||||
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(OUTLINE_PANEL_KEY) })
|
.read_with(&cx, |workspace, _| {
|
||||||
.await
|
OutlinePanel::serialization_key(workspace)
|
||||||
.context("loading outline panel")
|
})
|
||||||
.log_err()
|
.ok()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|panel| serde_json::from_str::<SerializedOutlinePanel>(&panel))
|
{
|
||||||
.transpose()
|
Some(serialization_key) => cx
|
||||||
.log_err()
|
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(&serialization_key) })
|
||||||
.flatten();
|
.await
|
||||||
|
.context("loading outline panel")
|
||||||
|
.log_err()
|
||||||
|
.flatten()
|
||||||
|
.map(|panel| serde_json::from_str::<SerializedOutlinePanel>(&panel))
|
||||||
|
.transpose()
|
||||||
|
.log_err()
|
||||||
|
.flatten(),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
workspace.update_in(&mut cx, |workspace, window, cx| {
|
workspace.update_in(&mut cx, |workspace, window, cx| {
|
||||||
let panel = Self::new(workspace, window, cx);
|
let panel = Self::new(workspace, window, cx);
|
||||||
|
@ -845,14 +854,32 @@ impl OutlinePanel {
|
||||||
outline_panel
|
outline_panel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialization_key(workspace: &Workspace) -> Option<String> {
|
||||||
|
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<Self>) {
|
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||||
|
let Some(serialization_key) = self
|
||||||
|
.workspace
|
||||||
|
.update(cx, |workspace, _| {
|
||||||
|
OutlinePanel::serialization_key(workspace)
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
let active = Some(self.active);
|
let active = Some(self.active);
|
||||||
self.pending_serialization = cx.background_spawn(
|
self.pending_serialization = cx.background_spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
OUTLINE_PANEL_KEY.into(),
|
serialization_key,
|
||||||
serde_json::to_string(&SerializedOutlinePanel { width, active })?,
|
serde_json::to_string(&SerializedOutlinePanel { width, active })?,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -4803,10 +4830,12 @@ impl Panel for OutlinePanel {
|
||||||
.unwrap_or_else(|| OutlinePanelSettings::get_global(cx).default_width)
|
.unwrap_or_else(|| OutlinePanelSettings::get_global(cx).default_width)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_size(&mut self, size: Option<Pixels>, _: &mut Window, cx: &mut Context<Self>) {
|
fn set_size(&mut self, size: Option<Pixels>, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
self.width = size;
|
self.width = size;
|
||||||
self.serialize(cx);
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
cx.defer_in(window, |this, _, cx| {
|
||||||
|
this.serialize(cx);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon(&self, _: &Window, cx: &App) -> Option<IconName> {
|
fn icon(&self, _: &Window, cx: &App) -> Option<IconName> {
|
||||||
|
|
|
@ -592,16 +592,25 @@ impl ProjectPanel {
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
mut cx: AsyncWindowContext,
|
mut cx: AsyncWindowContext,
|
||||||
) -> Result<Entity<Self>> {
|
) -> Result<Entity<Self>> {
|
||||||
let serialized_panel = cx
|
let serialized_panel = match workspace
|
||||||
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) })
|
.read_with(&cx, |workspace, _| {
|
||||||
.await
|
ProjectPanel::serialization_key(workspace)
|
||||||
.map_err(|e| anyhow!("Failed to load project panel: {}", e))
|
})
|
||||||
.log_err()
|
.ok()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|panel| serde_json::from_str::<SerializedProjectPanel>(&panel))
|
{
|
||||||
.transpose()
|
Some(serialization_key) => cx
|
||||||
.log_err()
|
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(&serialization_key) })
|
||||||
.flatten();
|
.await
|
||||||
|
.map_err(|e| anyhow!("Failed to load project panel: {}", e))
|
||||||
|
.log_err()
|
||||||
|
.flatten()
|
||||||
|
.map(|panel| serde_json::from_str::<SerializedProjectPanel>(&panel))
|
||||||
|
.transpose()
|
||||||
|
.log_err()
|
||||||
|
.flatten(),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
workspace.update_in(&mut cx, |workspace, window, cx| {
|
workspace.update_in(&mut cx, |workspace, window, cx| {
|
||||||
let panel = ProjectPanel::new(workspace, window, cx);
|
let panel = ProjectPanel::new(workspace, window, cx);
|
||||||
|
@ -673,13 +682,31 @@ impl ProjectPanel {
|
||||||
.or_insert(diagnostic_severity);
|
.or_insert(diagnostic_severity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialization_key(workspace: &Workspace) -> Option<String> {
|
||||||
|
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<Self>) {
|
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||||
|
let Some(serialization_key) = self
|
||||||
|
.workspace
|
||||||
|
.update(cx, |workspace, _| {
|
||||||
|
ProjectPanel::serialization_key(workspace)
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
self.pending_serialization = cx.background_spawn(
|
self.pending_serialization = cx.background_spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
PROJECT_PANEL_KEY.into(),
|
serialization_key,
|
||||||
serde_json::to_string(&SerializedProjectPanel { width })?,
|
serde_json::to_string(&SerializedProjectPanel { width })?,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -4967,10 +4994,12 @@ impl Panel for ProjectPanel {
|
||||||
.unwrap_or_else(|| ProjectPanelSettings::get_global(cx).default_width)
|
.unwrap_or_else(|| ProjectPanelSettings::get_global(cx).default_width)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_size(&mut self, size: Option<Pixels>, _: &mut Window, cx: &mut Context<Self>) {
|
fn set_size(&mut self, size: Option<Pixels>, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
self.width = size;
|
self.width = size;
|
||||||
self.serialize(cx);
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
cx.defer_in(window, |this, _, cx| {
|
||||||
|
this.serialize(cx);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon(&self, _: &Window, cx: &App) -> Option<IconName> {
|
fn icon(&self, _: &Window, cx: &App) -> Option<IconName> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue