From c918f6cde1732f4ae4c97f28f7402b0d9de1853d Mon Sep 17 00:00:00 2001 From: Umesh Yadav <23421535+imumesh18@users.noreply.github.com> Date: Sat, 3 May 2025 01:35:03 +0530 Subject: [PATCH] agent: Add assistant panel width persistence (#28808) Previously, the assistant panel width was not persisted across sessions. This meant that upon restarting the Zed editor, the panel would revert to its default size, disrupting the user's preferred layout. This pull request introduces persistence for the assistant panel width. The width is now saved to the key-value store when the editor is closed and restored on startup, ensuring a consistent UI experience across different sessions. Release Notes: - agent: Add assistant panel width persistence --------- Signed-off-by: Umesh Yadav --- crates/agent/src/assistant_panel.rs | 53 ++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/crates/agent/src/assistant_panel.rs b/crates/agent/src/assistant_panel.rs index 8a060d80bc..0b5d99867f 100644 --- a/crates/agent/src/assistant_panel.rs +++ b/crates/agent/src/assistant_panel.rs @@ -3,6 +3,9 @@ use std::path::Path; use std::sync::Arc; use std::time::Duration; +use db::kvp::KEY_VALUE_STORE; +use serde::{Deserialize, Serialize}; + use anyhow::{Result, anyhow}; use assistant_context_editor::{ AssistantContext, AssistantPanelDelegate, ConfigurationError, ContextEditor, ContextEvent, @@ -53,6 +56,13 @@ use crate::{ ToggleContextPicker, ToggleNavigationMenu, ToggleOptionsMenu, }; +const AGENT_PANEL_KEY: &str = "agent_panel"; + +#[derive(Serialize, Deserialize)] +struct SerializedAssistantPanel { + width: Option, +} + pub fn init(cx: &mut App) { cx.observe_new( |workspace: &mut Workspace, _window, _cx: &mut Context| { @@ -302,9 +312,22 @@ pub struct AssistantPanel { assistant_navigation_menu: Option>, width: Option, height: Option, + pending_serialization: Option>>, } impl AssistantPanel { + fn serialize(&mut self, cx: &mut Context) { + let width = self.width; + self.pending_serialization = Some(cx.background_spawn(async move { + KEY_VALUE_STORE + .write_kvp( + AGENT_PANEL_KEY.into(), + serde_json::to_string(&SerializedAssistantPanel { width })?, + ) + .await?; + anyhow::Ok(()) + })); + } pub fn load( workspace: WeakEntity, prompt_builder: Arc, @@ -343,8 +366,19 @@ impl AssistantPanel { })? .await?; - workspace.update_in(cx, |workspace, window, cx| { - cx.new(|cx| { + let serialized_panel = if let Some(panel) = cx + .background_spawn(async move { KEY_VALUE_STORE.read_kvp(AGENT_PANEL_KEY) }) + .await + .log_err() + .flatten() + { + Some(serde_json::from_str::(&panel)?) + } else { + None + }; + + let panel = workspace.update_in(cx, |workspace, window, cx| { + let panel = cx.new(|cx| { Self::new( workspace, thread_store, @@ -353,8 +387,17 @@ impl AssistantPanel { window, cx, ) - }) - }) + }); + if let Some(serialized_panel) = serialized_panel { + panel.update(cx, |panel, cx| { + panel.width = serialized_panel.width.map(|w| w.round()); + cx.notify(); + }); + } + panel + })?; + + Ok(panel) }) } @@ -586,6 +629,7 @@ impl AssistantPanel { assistant_navigation_menu: None, width: None, height: None, + pending_serialization: None, } } @@ -1209,6 +1253,7 @@ impl Panel for AssistantPanel { DockPosition::Left | DockPosition::Right => self.width = size, DockPosition::Bottom => self.height = size, } + self.serialize(cx); cx.notify(); }