mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Merge terminal close completion
* commit '477f7721a': fix(desktop): complete terminal tab close Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@buzz.block.builderlab.xyz>
This commit is contained in:
commit
c7dde02880
@@ -277,12 +277,11 @@ impl Session {
|
||||
}
|
||||
|
||||
fn shutdown(mut self) {
|
||||
if let Ok(mut channel) = self.channel.lock() {
|
||||
*channel = None;
|
||||
}
|
||||
// Publication is detached before the reader enters close mode; the
|
||||
// lifecycle helper then abandons parser work and keeps raw-draining
|
||||
// through child termination and reap.
|
||||
// through child termination and reap. Keep the renderer channel alive
|
||||
// until the reader has reported Exit; close() removes the session from
|
||||
// the runtime before shutdown begins, so this is its final message.
|
||||
if let Ok(mut publisher) = self.publisher.lock() {
|
||||
publisher.close();
|
||||
}
|
||||
@@ -300,6 +299,9 @@ impl Session {
|
||||
reader.join();
|
||||
}
|
||||
}
|
||||
if let Ok(mut channel) = self.channel.lock() {
|
||||
*channel = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -319,6 +319,43 @@ test("opening a tab keeps terminal ownership while its attachment is pending", a
|
||||
view.unmount();
|
||||
});
|
||||
|
||||
test("a successful close removes the tab even if the exit event is lost", async () => {
|
||||
const { createElement } = await import("react");
|
||||
const { fireEvent, render, waitFor } = await import("@testing-library/react");
|
||||
const { ThemeProvider } = await import("@/shared/theme/ThemeProvider");
|
||||
const { TerminalBootstrap } = await import("./TerminalBootstrap.tsx");
|
||||
|
||||
const view = render(
|
||||
createElement(
|
||||
ThemeProvider,
|
||||
null,
|
||||
createElement("div", {
|
||||
className: "buzz-huddle-app-surface",
|
||||
tabIndex: -1,
|
||||
}),
|
||||
createElement(TerminalBootstrap, {
|
||||
channelId: "channel-1",
|
||||
channelName: "general",
|
||||
npub: "npub1owner",
|
||||
relayUrl: "wss://relay.example",
|
||||
threadId: null,
|
||||
}),
|
||||
),
|
||||
);
|
||||
await waitFor(() =>
|
||||
assert.ok(calls.some(({ command }) => command === "terminal_attach")),
|
||||
);
|
||||
await waitFor(() => assert.ok(view.queryByRole("tab", { name: /SHELL/ })));
|
||||
|
||||
fireEvent.click(view.getByLabelText("Close SHELL"));
|
||||
|
||||
await waitFor(() =>
|
||||
assert.ok(calls.some(({ command }) => command === "terminal_close")),
|
||||
);
|
||||
await waitFor(() => assert.equal(view.queryByRole("tab"), null));
|
||||
view.unmount();
|
||||
});
|
||||
|
||||
// The wheel-to-IPC path end to end. `TerminalSubstrate` already proves it
|
||||
// accumulates pixels into whole cells and `buzz-terminal` already proves which
|
||||
// way the engine goes; the seam between them is this file's business, and the
|
||||
|
||||
@@ -228,7 +228,10 @@ export function TerminalBootstrap({
|
||||
removeSession(key);
|
||||
return;
|
||||
}
|
||||
void connection.close().catch(fail);
|
||||
void connection
|
||||
.close()
|
||||
.then(() => removeSession(key))
|
||||
.catch(fail);
|
||||
}}
|
||||
onFrameConsumed={(frame) => {
|
||||
const delivery = sessionsRef.current.find(
|
||||
|
||||
Reference in New Issue
Block a user