-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Add new welcome screen #5531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new welcome screen #5531
Changes from 8 commits
1b715c0
ff3955d
f084227
66dbaf2
0e8481f
d5040cf
dd9ff72
3d63d9c
29b02df
0701ced
7b3ad03
91339a2
5d2f26e
e101e11
22d09fe
e0e6d03
db04215
b7942ae
e678523
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "kilo-code": minor | ||
| --- | ||
|
|
||
| Add new welcome screen for improved onboarding |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,7 @@ import { ExtensionStateContextProvider, useExtensionState } from "./context/Exte | |
| import ChatView, { ChatViewRef } from "./components/chat/ChatView" | ||
| import HistoryView from "./components/history/HistoryView" | ||
| import SettingsView, { SettingsViewRef } from "./components/settings/SettingsView" | ||
| import WelcomeView from "./components/kilocode/welcome/WelcomeView" // kilocode_change | ||
| import OnboardingView from "./components/kilocode/welcome/OnboardingView" // kilocode_change | ||
| import ProfileView from "./components/kilocode/profile/ProfileView" // kilocode_change | ||
| import McpView from "./components/mcp/McpView" // kilocode_change | ||
| import AuthView from "./components/kilocode/auth/AuthView" // kilocode_change | ||
|
|
@@ -80,7 +80,6 @@ const defaultSectionByAction: Partial<Record<NonNullable<ExtensionMessage["actio | |
| const App = () => { | ||
| const { | ||
| didHydrateState, | ||
| showWelcome, | ||
| shouldShowAnnouncement, | ||
| telemetrySetting, | ||
| telemetryKey, | ||
|
|
@@ -94,6 +93,8 @@ const App = () => { | |
| renderContext, | ||
| mdmCompliant, | ||
| apiConfiguration, // kilocode_change | ||
| hasCompletedOnboarding, // kilocode_change: Track onboarding state | ||
| taskHistoryFullLength, // kilocode_change: Used to detect existing users | ||
| } = useExtensionState() | ||
|
|
||
| // Create a persistent state manager | ||
|
|
@@ -314,16 +315,54 @@ const App = () => { | |
| } | ||
| }, [tab]) | ||
|
|
||
| // kilocode_change start: Onboarding handlers | ||
| const handleSelectFreeModels = useCallback(() => { | ||
| // Mark onboarding as complete - the default profile is already set up with a free model | ||
| vscode.postMessage({ type: "hasCompletedOnboarding", bool: true }) | ||
| }, []) | ||
|
|
||
| const handleSelectPremiumModels = useCallback(() => { | ||
| // Mark onboarding as complete | ||
| vscode.postMessage({ type: "hasCompletedOnboarding", bool: true }) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WARNING: Onboarding is marked complete before premium sign-in succeeds
Consider setting completion only after successful authentication (or using a separate "started onboarding" flag). |
||
| // Navigate to auth view which will show the device code and handle the OAuth flow | ||
| // The AuthView auto-starts device auth on mount | ||
| switchTab("auth") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WARNING:
Consider hiding onboarding immediately (e.g., local state) or making the render conditional prioritize |
||
| setAuthReturnTo("chat") | ||
| }, [switchTab]) | ||
|
|
||
| const handleSelectBYOK = useCallback(() => { | ||
| // Mark onboarding as complete | ||
| vscode.postMessage({ type: "hasCompletedOnboarding", bool: true }) | ||
| // Navigate to settings with providers section | ||
| switchTab("settings") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WARNING: Navigation won’t be visible until onboarding is dismissed Because |
||
| setCurrentSection("providers") | ||
| }, [switchTab]) | ||
|
|
||
| // One-time migration: mark existing users as having completed onboarding | ||
| useEffect(() => { | ||
| if (hasCompletedOnboarding !== true && (taskHistoryFullLength ?? 0) > 0) { | ||
| vscode.postMessage({ type: "hasCompletedOnboarding", bool: true }) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WARNING: Onboarding migration may repeatedly post state updates The migration Consider guarding with a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again don't think this is a concern and have not seen it in my testing. |
||
| } | ||
| }, [hasCompletedOnboarding, taskHistoryFullLength]) | ||
| // kilocode_change end | ||
|
|
||
| if (!didHydrateState) { | ||
| return null | ||
| } | ||
|
|
||
| // kilocode_change start: Show OnboardingView for new users who haven't completed onboarding | ||
| const showOnboarding = hasCompletedOnboarding !== true | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WARNING: Onboarding may briefly flash for existing users
If the goal is to never show onboarding to existing users, consider including
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is an actual concern, and I don't see it in my testing.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you test it by completing the onboarding, doing zero tasks, and restarting the extensions (cmd-shift-p, reload webviews) with the extensions open? If the bot is right you'll probably see this screen flash. It sounds at least 70% probable to me
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @markijbema - I've tested. It does not flash, at least for me. AI says the reason why is: The Flow
The key is that setDidHydrateState(true) is called AFTER setState merges the new state. This happens in the same event handler, so React batches these updates. By the time the component renders for the first time (when didHydrateState becomes true), hasCompletedOnboarding already has the value from the extension's global state. |
||
|
|
||
| // Do not conditionally load ChatView, it's expensive and there's state we | ||
| // don't want to lose (user input, disableInput, askResponse promise, etc.) | ||
| // kilocode_change: no WelcomeViewProvider toggle | ||
| return showWelcome ? ( | ||
| <WelcomeView /> | ||
| return showOnboarding ? ( | ||
| <OnboardingView | ||
| onSelectFreeModels={handleSelectFreeModels} | ||
| onSelectPremiumModels={handleSelectPremiumModels} | ||
| onSelectBYOK={handleSelectBYOK} | ||
| /> | ||
| ) : ( | ||
| // kilocode_change end | ||
| <> | ||
| {/* kilocode_change start */} | ||
| <MemoryWarningBanner /> | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,63 @@ | ||||||
| // kilocode_change - new file | ||||||
| import React from "react" | ||||||
| import Logo from "../common/Logo" | ||||||
| import { useAppTranslation } from "@/i18n/TranslationContext" | ||||||
|
|
||||||
| interface OnboardingOptionProps { | ||||||
| title: string | ||||||
| description: string | ||||||
| onClick: () => void | ||||||
| } | ||||||
|
|
||||||
| const OnboardingOption: React.FC<OnboardingOptionProps> = ({ title, description, onClick }) => { | ||||||
| return ( | ||||||
| <button | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SUGGESTION: Add an explicit Buttons default to
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't seem to be a risk, since this is not in a form and unlikely to be. |
||||||
| className="w-full p-5 rounded-lg border border-vscode-panel-border bg-vscode-editor-background hover:bg-vscode-list-hoverBackground cursor-pointer text-left transition-colors" | ||||||
| onClick={onClick}> | ||||||
| <h3 className="text-lg font-semibold text-vscode-foreground m-0 mb-2">{title}</h3> | ||||||
| <p className="text-sm text-vscode-descriptionForeground m-0">{description}</p> | ||||||
| </button> | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| interface OnboardingViewProps { | ||||||
| onSelectFreeModels: () => void | ||||||
| onSelectPremiumModels: () => void | ||||||
| onSelectBYOK: () => void | ||||||
| } | ||||||
|
|
||||||
| const OnboardingView: React.FC<OnboardingViewProps> = ({ onSelectFreeModels, onSelectPremiumModels, onSelectBYOK }) => { | ||||||
| const { t } = useAppTranslation() | ||||||
|
|
||||||
| return ( | ||||||
| <div className="flex flex-col items-center justify-center min-h-screen p-6 bg-vscode-sideBar-background"> | ||||||
| <Logo width={80} height={80} /> | ||||||
|
|
||||||
| <h1 className="text-2xl font-bold text-vscode-foreground text-center mt-4 mb-10"> | ||||||
| {t("kilocode:onboarding.title")} | ||||||
| </h1> | ||||||
|
|
||||||
| <div className="w-full max-w-md flex flex-col gap-4"> | ||||||
| <OnboardingOption | ||||||
| title={t("kilocode:onboarding.freeModels.title")} | ||||||
| description={t("kilocode:onboarding.freeModels.description")} | ||||||
| onClick={onSelectFreeModels} | ||||||
| /> | ||||||
|
|
||||||
| <OnboardingOption | ||||||
| title={t("kilocode:onboarding.premiumModels.title")} | ||||||
| description={t("kilocode:onboarding.premiumModels.description")} | ||||||
| onClick={onSelectPremiumModels} | ||||||
| /> | ||||||
|
|
||||||
| <OnboardingOption | ||||||
| title={t("kilocode:onboarding.byok.title")} | ||||||
| description={t("kilocode:onboarding.byok.description")} | ||||||
| onClick={onSelectBYOK} | ||||||
| /> | ||||||
| </div> | ||||||
| </div> | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| export default OnboardingView | ||||||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WARNING: "Free models" selection only sets onboarding complete; it may still show the Welcome screen
handleSelectFreeModelspostshasCompletedOnboardingbut does not navigate to chat or otherwise affectshowWelcome. On the next render, this falls through toshowWelcome ? <WelcomeView /> : …, so users who still haveshowWelcome === truemay immediately land onWelcomeViewinstead of "Start coding immediately".