Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions apps/mobile/src/features/browser/PreviewStreamWebView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { AppText } from "../../components/AppText";
import { downloadAndShareAttachment } from "../../lib/attachmentDownload";
import { beginForegroundHandoff } from "../../lib/foreground-handoff";
import { usePreviewStreamAccess } from "../../state/preview";
import { previewPromptText } from "./previewPromptText";

import {
previewStreamDocument,
Expand Down Expand Up @@ -256,6 +257,7 @@ function PreviewStreamDocumentView({
const [hostSetup, setHostSetup] = useState<PreviewStreamHostSetup | null>(null);
const [started, setStarted] = useState(false);
const [control, setControl] = useState<PreviewStreamControl | null>(null);
const dialogRef = useRef<PreviewStreamControl["dialog"]>(null);
const [promptText, setPromptText] = useState("");
const [fileChooser, setFileChooser] = useState<PreviewStreamFileChooser | null>(null);
const answerFileChooser = (pick: boolean) => {
Expand Down Expand Up @@ -371,11 +373,14 @@ function PreviewStreamDocumentView({
const message = previewStreamMessage(event.nativeEvent.data);
if (message === null) return;
switch (message.type) {
case "control":
case "control": {
setControl(message);
setPromptText(message.dialog?.defaultValue ?? "");
const previousDialog = dialogRef.current;
dialogRef.current = message.dialog;
setPromptText((draft) => previewPromptText(previousDialog, message.dialog, draft));
onControl?.(message);
return;
}
case "unauthorized":
if (!onUnauthorized()) {
fail("This session can't open the browser stream. Reconnect to try again.");
Expand Down Expand Up @@ -413,6 +418,8 @@ function PreviewStreamDocumentView({
}
setStatus(message.status);
if (message.status === "connecting") {
// Dialogs may have closed and reopened while this viewer was disconnected.
dialogRef.current = null;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
setControl(null);
onControl?.(null);
}
Expand Down
41 changes: 41 additions & 0 deletions apps/mobile/src/features/browser/previewPromptText.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { describe, expect, it } from "vite-plus/test";

import { previewPromptText } from "./previewPromptText";

describe("browser prompt response", () => {
const prompt = { type: "prompt" as const, message: "Your name?", defaultValue: "Guest" };

it("preserves a typed response across repeated control broadcasts", () => {
expect(previewPromptText(prompt, { ...prompt }, "Alice")).toBe("Alice");
});

it("preserves an intentionally empty response", () => {
expect(previewPromptText(prompt, { ...prompt }, "")).toBe("");
});

it("initializes a newly opened prompt", () => {
expect(previewPromptText(null, prompt, "")).toBe("Guest");
});

it("resets a stale draft after reconnecting without dialog history", () => {
expect(previewPromptText(null, prompt, "Alice")).toBe("Guest");
});

it("resets when the message changes", () => {
expect(previewPromptText(prompt, { ...prompt, message: "Next name?" }, "Alice")).toBe("Guest");
});

it("resets when the default value changes", () => {
expect(previewPromptText(prompt, { ...prompt, defaultValue: "Bob" }, "Alice")).toBe("Bob");
});

it("resets when the dialog type changes with matching message and default", () => {
expect(previewPromptText(prompt, { ...prompt, type: "confirm" }, "Alice")).toBe("Guest");
});

it("clears a closed dialog and initializes an identical reopened prompt", () => {
const cleared = previewPromptText(prompt, null, "Alice");
expect(cleared).toBe("");
expect(previewPromptText(null, prompt, cleared)).toBe("Guest");
});
});
15 changes: 15 additions & 0 deletions apps/mobile/src/features/browser/previewPromptText.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { PreviewStreamControl } from "@t3tools/client-runtime/preview/server-browser-stream";

type Dialog = PreviewStreamControl["dialog"];

/** Updates the native response draft when a browser control message arrives. */
export function previewPromptText(previous: Dialog, next: Dialog, draft: string) {
if (
next?.type !== previous?.type ||
next?.message !== previous?.message ||
next?.defaultValue !== previous?.defaultValue
) {
return next?.defaultValue ?? "";
}
return draft;
}
Loading