Skip to content

Commit 3d9aa8e

Browse files
committed
Add 'taking you to cloud' screen after provider welcome
1 parent 5b64aa9 commit 3d9aa8e

File tree

19 files changed

+267
-16
lines changed

19 files changed

+267
-16
lines changed

webview-ui/src/components/welcome/WelcomeViewProvider.tsx

Lines changed: 141 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { useCallback, useState } from "react"
2-
import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
1+
import { useCallback, useEffect, useRef, useState } from "react"
2+
import { VSCodeLink, VSCodeProgressRing, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
33

44
import type { ProviderSettings } from "@roo-code/types"
55

@@ -14,14 +14,47 @@ import { Tab, TabContent } from "../common/Tab"
1414

1515
import RooHero from "./RooHero"
1616
import { Trans } from "react-i18next"
17+
import { ArrowLeft } from "lucide-react"
1718

1819
type ProviderOption = "roo" | "custom"
1920

2021
const WelcomeViewProvider = () => {
21-
const { apiConfiguration, currentApiConfigName, setApiConfiguration, uriScheme } = useExtensionState()
22+
const { apiConfiguration, currentApiConfigName, setApiConfiguration, uriScheme, cloudIsAuthenticated } =
23+
useExtensionState()
2224
const { t } = useAppTranslation()
2325
const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined)
2426
const [selectedProvider, setSelectedProvider] = useState<ProviderOption>("roo")
27+
const [authInProgress, setAuthInProgress] = useState(false)
28+
const [showManualEntry, setShowManualEntry] = useState(false)
29+
const [manualUrl, setManualUrl] = useState("")
30+
const manualUrlInputRef = useRef<HTMLInputElement | null>(null)
31+
32+
// When auth completes during the provider signup flow, save the Roo config
33+
// This will cause showWelcome to become false and navigate to chat
34+
useEffect(() => {
35+
if (cloudIsAuthenticated && authInProgress) {
36+
// Auth completed from provider signup flow - save the config now
37+
const rooConfig: ProviderSettings = {
38+
apiProvider: "roo",
39+
}
40+
vscode.postMessage({
41+
type: "upsertApiConfiguration",
42+
text: currentApiConfigName,
43+
apiConfiguration: rooConfig,
44+
})
45+
setAuthInProgress(false)
46+
setShowManualEntry(false)
47+
}
48+
}, [cloudIsAuthenticated, authInProgress, currentApiConfigName])
49+
50+
// Focus the manual URL input when it becomes visible
51+
useEffect(() => {
52+
if (showManualEntry && manualUrlInputRef.current) {
53+
setTimeout(() => {
54+
manualUrlInputRef.current?.focus()
55+
}, 50)
56+
}
57+
}, [showManualEntry])
2558

2659
// Memoize the setApiConfigurationField function to pass to ApiOptions
2760
const setApiConfigurationFieldForApiOptions = useCallback(
@@ -33,20 +66,14 @@ const WelcomeViewProvider = () => {
3366

3467
const handleGetStarted = useCallback(() => {
3568
if (selectedProvider === "roo") {
36-
// Set the Roo provider configuration
37-
const rooConfig: ProviderSettings = {
38-
apiProvider: "roo",
39-
}
40-
41-
// Save the Roo provider configuration
42-
vscode.postMessage({
43-
type: "upsertApiConfiguration",
44-
text: currentApiConfigName,
45-
apiConfiguration: rooConfig,
46-
})
47-
48-
// Then trigger cloud sign-in with provider signup flow
69+
// Trigger cloud sign-in with provider signup flow
70+
// NOTE: We intentionally do NOT save the API configuration yet.
71+
// The configuration will be saved by the extension after auth completes.
72+
// This keeps showWelcome true so we can show the waiting state.
4973
vscode.postMessage({ type: "rooCloudSignIn", useProviderSignup: true })
74+
75+
// Show the waiting state
76+
setAuthInProgress(true)
5077
} else {
5178
// Use custom provider - validate first
5279
const error = apiConfiguration ? validateApiConfiguration(apiConfiguration) : undefined
@@ -61,6 +88,104 @@ const WelcomeViewProvider = () => {
6188
}
6289
}, [selectedProvider, apiConfiguration, currentApiConfigName])
6390

91+
const handleGoBack = useCallback(() => {
92+
setAuthInProgress(false)
93+
setShowManualEntry(false)
94+
setManualUrl("")
95+
}, [])
96+
97+
const handleManualUrlChange = (e: any) => {
98+
const url = e.target.value
99+
setManualUrl(url)
100+
101+
// Auto-trigger authentication when a complete URL is pasted
102+
setTimeout(() => {
103+
if (url.trim() && url.includes("://") && url.includes("/auth/clerk/callback")) {
104+
vscode.postMessage({ type: "rooCloudManualUrl", text: url.trim() })
105+
}
106+
}, 100)
107+
}
108+
109+
const handleKeyDown = (e: any) => {
110+
if (e.key === "Enter") {
111+
const url = manualUrl.trim()
112+
if (url && url.includes("://") && url.includes("/auth/clerk/callback")) {
113+
vscode.postMessage({ type: "rooCloudManualUrl", text: url })
114+
}
115+
}
116+
}
117+
118+
const handleOpenSignupUrl = () => {
119+
vscode.postMessage({ type: "rooCloudSignIn", useProviderSignup: true })
120+
}
121+
122+
// Render the waiting for cloud state
123+
if (authInProgress) {
124+
return (
125+
<Tab>
126+
<TabContent className="flex flex-col gap-4 p-6">
127+
<div className="flex flex-col items-start gap-4 pt-8">
128+
<VSCodeProgressRing className="size-6" />
129+
<h2 className="mt-0 mb-0 text-lg font-semibold">{t("welcome:waitingForCloud.heading")}</h2>
130+
<p className="text-sm text-vscode-descriptionForeground mt-0">
131+
{t("welcome:waitingForCloud.description")}
132+
</p>
133+
134+
<p className="text-sm text-vscode-descriptionForeground mt-2">
135+
<Trans
136+
i18nKey="welcome:waitingForCloud.noPrompt"
137+
components={{
138+
clickHere: (
139+
<button
140+
onClick={handleOpenSignupUrl}
141+
className="text-vscode-textLink-foreground hover:text-vscode-textLink-activeForeground underline cursor-pointer bg-transparent border-none p-0 text-sm"
142+
/>
143+
),
144+
}}
145+
/>
146+
</p>
147+
148+
<p className="text-sm text-vscode-descriptionForeground">
149+
<Trans
150+
i18nKey="welcome:waitingForCloud.havingTrouble"
151+
components={{
152+
clickHere: (
153+
<button
154+
onClick={() => setShowManualEntry(true)}
155+
className="text-vscode-textLink-foreground hover:text-vscode-textLink-activeForeground underline cursor-pointer bg-transparent border-none p-0 text-sm"
156+
/>
157+
),
158+
}}
159+
/>
160+
</p>
161+
162+
{showManualEntry && (
163+
<div className="mt-2 w-full max-w-sm">
164+
<p className="text-sm text-vscode-descriptionForeground mb-2">
165+
Paste the callback URL from your browser:
166+
</p>
167+
<VSCodeTextField
168+
ref={manualUrlInputRef as any}
169+
value={manualUrl}
170+
onChange={handleManualUrlChange}
171+
onKeyDown={handleKeyDown}
172+
placeholder="vscode://RooVeterinaryInc.roo-cline/auth/clerk/callback?state=..."
173+
className="w-full"
174+
/>
175+
</div>
176+
)}
177+
</div>
178+
</TabContent>
179+
<div className="sticky bottom-0 bg-vscode-sideBar-background p-4 border-t border-vscode-panel-border">
180+
<Button onClick={handleGoBack} variant="secondary" className="flex items-center gap-2">
181+
<ArrowLeft className="size-4" />
182+
{t("welcome:waitingForCloud.goBack")}
183+
</Button>
184+
</div>
185+
</Tab>
186+
)
187+
}
188+
64189
return (
65190
<Tab>
66191
<TabContent className="flex flex-col gap-4 p-6">

webview-ui/src/i18n/locales/ca/welcome.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/de/welcome.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/en/welcome.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525
"useAnotherProviderDescription": "Enter an API key and get going.",
2626
"getStarted": "Get started"
2727
},
28+
"waitingForCloud": {
29+
"heading": "Taking you to Roo Code Cloud...",
30+
"description": "Complete sign-up in your browser, then you'll return here automatically.",
31+
"noPrompt": "If you don't get prompted to open a URL, <clickHere>click here</clickHere>.",
32+
"havingTrouble": "If completed the sign up but are having trouble, <clickHere>click here</clickHere>.",
33+
"goBack": "Go back"
34+
},
2835
"startRouter": "We recommend using an LLM Router:",
2936
"startCustom": "Or you can bring your provider API key:",
3037
"telemetry": {

webview-ui/src/i18n/locales/es/welcome.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/fr/welcome.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/hi/welcome.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/id/welcome.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/it/welcome.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/ja/welcome.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)