mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Merge PR #4410: restore terminal splash
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@buzz.block.builderlab.xyz> Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@buzz.block.builderlab.xyz>
This commit is contained in:
commit
ee862deb20
@@ -183,21 +183,55 @@ const VISIBLE_FRAME = {
|
||||
};
|
||||
|
||||
async function expectWelcome(view, present) {
|
||||
// Compare a boolean, never the node: an AssertionError carrying a mounted
|
||||
// element inspects it to build its message, and `__reactFiber$` makes that
|
||||
// walk the whole fiber graph — a failure takes ~2min to report instead of ms.
|
||||
await waitFor(() =>
|
||||
present
|
||||
? assert.ok(view.container.querySelector(".buzz-terminal-welcome"))
|
||||
: assert.equal(
|
||||
view.container.querySelector(".buzz-terminal-welcome"),
|
||||
null,
|
||||
),
|
||||
assert.equal(
|
||||
view.container.querySelector(".buzz-terminal-welcome") !== null,
|
||||
present,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
test("non-empty output from the active PTY dismisses the welcome overlay", async () => {
|
||||
async function reveal(view) {
|
||||
const substrate = view.container.querySelector(".buzz-terminal-substrate");
|
||||
toggleChord();
|
||||
await waitFor(() =>
|
||||
assert.equal(substrate.dataset.terminalOwner, "terminal"),
|
||||
);
|
||||
}
|
||||
|
||||
test("spawn-time output before the first reveal keeps the welcome overlay", async () => {
|
||||
const subject = fixture({ frame: EMPTY_FRAME });
|
||||
await ready(subject.view);
|
||||
await expectWelcome(subject.view, true);
|
||||
|
||||
subject.rerender({ frame: VISIBLE_FRAME });
|
||||
await expectWelcome(subject.view, true);
|
||||
|
||||
await reveal(subject.view);
|
||||
await expectWelcome(subject.view, true);
|
||||
});
|
||||
|
||||
test("the first keystroke dismisses the welcome overlay", async () => {
|
||||
const subject = fixture({ frame: VISIBLE_FRAME });
|
||||
await ready(subject.view);
|
||||
await reveal(subject.view);
|
||||
await expectWelcome(subject.view, true);
|
||||
|
||||
fireEvent.input(subject.view.getByLabelText("Terminal input"), {
|
||||
target: { value: "l" },
|
||||
});
|
||||
await expectWelcome(subject.view, false);
|
||||
});
|
||||
|
||||
test("non-empty output after the reveal dismisses the welcome overlay", async () => {
|
||||
const subject = fixture({ frame: EMPTY_FRAME });
|
||||
await ready(subject.view);
|
||||
await reveal(subject.view);
|
||||
await expectWelcome(subject.view, true);
|
||||
|
||||
subject.rerender({ frame: VISIBLE_FRAME });
|
||||
await expectWelcome(subject.view, false);
|
||||
});
|
||||
@@ -205,6 +239,7 @@ test("non-empty output from the active PTY dismisses the welcome overlay", async
|
||||
test("empty active output keeps the welcome overlay", async () => {
|
||||
const subject = fixture({ frame: EMPTY_FRAME });
|
||||
await ready(subject.view);
|
||||
await reveal(subject.view);
|
||||
await expectWelcome(subject.view, true);
|
||||
|
||||
subject.rerender({
|
||||
@@ -225,6 +260,7 @@ test("non-empty output from an inactive PTY keeps the welcome overlay", async ()
|
||||
],
|
||||
});
|
||||
await ready(subject.view);
|
||||
await reveal(subject.view);
|
||||
await expectWelcome(subject.view, true);
|
||||
|
||||
subject.rerender({
|
||||
|
||||
@@ -101,6 +101,7 @@ export function TerminalSubstrate({
|
||||
const previousFocusRef = React.useRef<HTMLElement | null>(null);
|
||||
const reportedFocusRef = React.useRef<boolean | null>(null);
|
||||
const scrollBySessionRef = React.useRef(new Map<string, number>());
|
||||
const revealedRef = React.useRef(false);
|
||||
const activeSession = sessions.find((session) => session.active);
|
||||
const activeSessionId = activeSession?.id ?? null;
|
||||
const frames = React.useMemo(
|
||||
@@ -146,6 +147,7 @@ export function TerminalSubstrate({
|
||||
const appSurface = getAppSurface();
|
||||
if (!appSurface) return;
|
||||
if (next === "terminal") {
|
||||
revealedRef.current = true;
|
||||
previousFocusRef.current =
|
||||
document.activeElement instanceof HTMLElement
|
||||
? document.activeElement
|
||||
@@ -339,9 +341,13 @@ export function TerminalSubstrate({
|
||||
consumeFrame(delivered.frame);
|
||||
if (
|
||||
delivered.sessionId === activeSessionId &&
|
||||
revealedRef.current &&
|
||||
hasVisibleOutput(delivered.frame)
|
||||
) {
|
||||
// Policy: first visible output from the active PTY removes the overlay.
|
||||
// Policy: the banner is a splash for the reveal, so spawn-time shell
|
||||
// output must not dismiss it. Only visible output from the active PTY
|
||||
// that arrives after the terminal has been revealed (or the first
|
||||
// keystroke, see sendInput) removes the overlay.
|
||||
setWelcomeVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user