diff --git a/.changeset/tidy-boxes-phone-notice.md b/.changeset/tidy-boxes-phone-notice.md new file mode 100644 index 0000000..fac0fa6 --- /dev/null +++ b/.changeset/tidy-boxes-phone-notice.md @@ -0,0 +1,5 @@ +--- +"playground-cli": patch +--- + +Title-case all bordered callout titles ("Moddable Setup Needed", "Check Your Phone", etc.) and show a "Keep Your Phone Ready" heads-up when a phone-signed deploy starts, so users have their mobile app ready before the first approval prompt. diff --git a/src/commands/contractDeployUi.tsx b/src/commands/contractDeployUi.tsx index 18a9f9d..82dde99 100644 --- a/src/commands/contractDeployUi.tsx +++ b/src/commands/contractDeployUi.tsx @@ -170,7 +170,7 @@ function ContractDeployScreen({ /> )} {adapter.signingError && ( - + {adapter.signingError} )} diff --git a/src/commands/decentralize/DecentralizeScreen.tsx b/src/commands/decentralize/DecentralizeScreen.tsx index 1dd7284..7e1a667 100644 --- a/src/commands/decentralize/DecentralizeScreen.tsx +++ b/src/commands/decentralize/DecentralizeScreen.tsx @@ -152,7 +152,7 @@ export function DecentralizeScreen({ {stage.kind === "prompt-url" && ( <> - + Mirrors a live static site (https URL) and republishes it as a .dot site. @@ -621,7 +621,7 @@ function DoneStage({ {outcome.metadataCid && } {outcome.signerSource === "dev" && ( - + To deploy to a domain owned by you, run `playground init` and re-run `playground decentralize` with the mobile signer. @@ -644,7 +644,7 @@ function ErrorStage({ message, onExit }: { message: string; onExit: () => void } return ( - + {message} diff --git a/src/commands/deploy/DeployScreen.tsx b/src/commands/deploy/DeployScreen.tsx index f8dc7d4..2e2a6d4 100644 --- a/src/commands/deploy/DeployScreen.tsx +++ b/src/commands/deploy/DeployScreen.tsx @@ -482,7 +482,7 @@ function ModdableErrorStage({ message, onExit }: { message: string; onExit: () = }); return ( - + {message} @@ -661,7 +661,7 @@ function ConfirmStage({ {oversizedReadme && ( - + README.md is {formatKbCeil(oversizedReadme.size)} — over the{" "} {README_CAP_BYTES / 1024} KB limit. the rest of the deploy will continue @@ -722,6 +722,10 @@ function RunningStage({ const frontendState = runningState.frontend; const playgroundState = runningState.playground; const [signingPrompt, setSigningPrompt] = useState(null); + // Heads-up rendered from the moment the run starts until the first real + // sign-request arrives — once the PhoneApprovalCallout takes over, the + // readiness reminder is redundant and stays hidden for the rest of the run. + const [showPhoneNotice, setShowPhoneNotice] = useState(inputs.mode === "phone"); // Per-chunk timing for the sparkline on completion. Held in refs to avoid // re-renders on every chunk tick. @@ -775,10 +779,16 @@ function RunningStage({ plan: plan ?? undefined, onEvent: (event) => handleEvent(event), }); - if (!cancelled) onFinish(outcome, chunkTimingsRef.current); + if (!cancelled) { + // RunningStage stays mounted through "done"/"error", so + // clear the readiness notice in case no sign-request fired. + setShowPhoneNotice(false); + onFinish(outcome, chunkTimingsRef.current); + } } catch (err) { if (!cancelled) { const message = err instanceof Error ? err.message : String(err); + setShowPhoneNotice(false); onError(message); } } @@ -812,6 +822,7 @@ function RunningStage({ } } else if (event.kind === "signing") { if (event.event.kind === "sign-request") { + setShowPhoneNotice(false); setSigningPrompt(event.event); } else if (event.event.kind === "sign-complete") { setSigningPrompt(null); @@ -834,6 +845,13 @@ function RunningStage({ return ( + {showPhoneNotice && ( + + + This deploy will ask you to approve transactions in your mobile app. + + + )} {playgroundState.status !== "skipped" && ( diff --git a/src/utils/ui/theme/PhoneApprovalCallout.tsx b/src/utils/ui/theme/PhoneApprovalCallout.tsx index cc1332f..d5a6ddb 100644 --- a/src/utils/ui/theme/PhoneApprovalCallout.tsx +++ b/src/utils/ui/theme/PhoneApprovalCallout.tsx @@ -31,7 +31,7 @@ export interface PhoneApprovalCalloutProps { export function PhoneApprovalCallout({ step, total, label }: PhoneApprovalCalloutProps) { return ( - + approve step {step} {total !== undefined ? ` of ${total}` : ""}: {label}