Skip to content

Commit c3f63b3

Browse files
committed
feat(desktop): promote workspace sessions in place
1 parent d69fb2a commit c3f63b3

3 files changed

Lines changed: 59 additions & 1 deletion

File tree

crates/jcode-desktop/src/main.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,12 @@ async fn run() -> Result<()> {
835835
if let DesktopApp::Workspace(workspace) = &app {
836836
queue_desktop_preferences_save(workspace, &preferences_save_tx);
837837
}
838-
if let Err(error) =
838+
if app.promote_focused_workspace_session() {
839+
scroll_accumulator = ScrollLineAccumulator::default();
840+
scroll_metrics_cache = SingleSessionScrollMetricsCache::default();
841+
window.set_title(&app.status_title());
842+
window.request_redraw();
843+
} else if let Err(error) =
839844
session_launch::launch_validated_resume_session(&session_id, &title)
840845
{
841846
desktop_log::error(format_args!(
@@ -4829,6 +4834,21 @@ impl DesktopApp {
48294834
}
48304835
}
48314836

4837+
fn promote_focused_workspace_session(&mut self) -> bool {
4838+
let Self::Workspace(workspace) = self else {
4839+
return false;
4840+
};
4841+
let Some(card) = workspace.focused_session_card() else {
4842+
return false;
4843+
};
4844+
let session_id = card.session_id.clone();
4845+
let mut single_session = SingleSessionApp::new(Some(card));
4846+
single_session.initialize_resumed_session(&session_id);
4847+
single_session.hydrate_resumed_session_from_disk(&session_id);
4848+
*self = Self::SingleSession(single_session);
4849+
true
4850+
}
4851+
48324852
fn apply_session_event(&mut self, event: session_launch::DesktopSessionEvent) {
48334853
if let Self::SingleSession(app) = self {
48344854
app.apply_session_event(event);

crates/jcode-desktop/src/main_tests.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6465,6 +6465,24 @@ fn single_session_wraps_one_session_card() {
64656465
);
64666466
}
64676467

6468+
#[test]
6469+
fn workspace_focused_session_promotes_to_single_session_app() {
6470+
let mut app = DesktopApp::Workspace(Workspace::from_session_cards(vec![workspace::SessionCard {
6471+
session_id: "session_alpha".to_string(),
6472+
title: "alpha".to_string(),
6473+
subtitle: "active".to_string(),
6474+
detail: "3 msgs".to_string(),
6475+
preview_lines: vec!["user hello".to_string()],
6476+
detail_lines: vec!["assistant hi".to_string()],
6477+
}]));
6478+
6479+
assert!(app.promote_focused_workspace_session());
6480+
let snapshot = app.debug_snapshot();
6481+
assert_eq!(snapshot.mode, "single_session");
6482+
assert_eq!(snapshot.live_session_id.as_deref(), Some("session_alpha"));
6483+
assert!(snapshot.body_text.contains("user hello"));
6484+
}
6485+
64686486
#[test]
64696487
fn single_session_surface_is_the_panel_primitive() {
64706488
let card = workspace::SessionCard {

crates/jcode-desktop/src/workspace.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,26 @@ impl Workspace {
613613
})
614614
}
615615

616+
pub fn focused_session_card(&self) -> Option<SessionCard> {
617+
self.focused_surface().and_then(|surface| {
618+
let session_id = surface.session_id.as_ref()?.clone();
619+
Some(SessionCard {
620+
session_id,
621+
title: surface.title.clone(),
622+
subtitle: surface.body_lines.first().cloned().unwrap_or_default(),
623+
detail: surface.body_lines.get(1).cloned().unwrap_or_default(),
624+
preview_lines: surface
625+
.body_lines
626+
.iter()
627+
.skip_while(|line| line.as_str() != "recent transcript")
628+
.skip(1)
629+
.cloned()
630+
.collect(),
631+
detail_lines: surface.detail_lines.clone(),
632+
})
633+
})
634+
}
635+
616636
pub fn is_focused(&self, surface_id: u64) -> bool {
617637
self.focused_id == surface_id
618638
}

0 commit comments

Comments
 (0)