modal.rs

 1use gpui::{ModelHandle, ViewContext};
 2use workspace::Workspace;
 3
 4use crate::{get_working_directory, DeployModal, Event, Terminal, TerminalConnection};
 5
 6struct StoredConnection(ModelHandle<TerminalConnection>);
 7
 8pub fn deploy_modal(workspace: &mut Workspace, _: &DeployModal, cx: &mut ViewContext<Workspace>) {
 9    // Pull the terminal connection out of the global if it has been stored
10    let possible_connection =
11        cx.update_default_global::<Option<StoredConnection>, _, _>(|possible_connection, _| {
12            possible_connection.take()
13        });
14
15    if let Some(StoredConnection(stored_connection)) = possible_connection {
16        // Create a view from the stored connection
17        workspace.toggle_modal(cx, |_, cx| {
18            cx.add_view(|cx| Terminal::from_connection(stored_connection, true, cx))
19        });
20    } else {
21        // No connection was stored, create a new terminal
22        if let Some(closed_terminal_handle) = workspace.toggle_modal(cx, |workspace, cx| {
23            let project = workspace.project().read(cx);
24            let abs_path = project
25                .active_entry()
26                .and_then(|entry_id| project.worktree_for_entry(entry_id, cx))
27                .and_then(|worktree_handle| worktree_handle.read(cx).as_local())
28                .and_then(get_working_directory);
29
30            let this = cx.add_view(|cx| Terminal::new(abs_path, true, cx));
31            let connection_handle = this.read(cx).connection.clone();
32            cx.subscribe(&connection_handle, on_event).detach();
33            this
34        }) {
35            let connection = closed_terminal_handle.read(cx).connection.clone();
36            cx.set_global(Some(StoredConnection(connection)));
37        }
38    }
39}
40
41pub fn on_event(
42    workspace: &mut Workspace,
43    _: ModelHandle<TerminalConnection>,
44    event: &Event,
45    cx: &mut ViewContext<Workspace>,
46) {
47    // Dismiss the modal if the terminal quit
48    if let Event::CloseTerminal = event {
49        cx.set_global::<Option<StoredConnection>>(None);
50        if workspace
51            .modal()
52            .cloned()
53            .and_then(|modal| modal.downcast::<Terminal>())
54            .is_some()
55        {
56            workspace.dismiss_modal(cx)
57        }
58    }
59}