fix(desktop): gate first launch onboarding (#34930)
This commit is contained in:
parent
7f57d2a9ac
commit
dffecb6478
12 changed files with 204 additions and 43 deletions
|
|
@ -23,6 +23,7 @@ import { render } from "solid-js/web"
|
|||
import pkg from "../../package.json"
|
||||
import { initI18n, t } from "./i18n"
|
||||
import { initializationData, initializationReady } from "./initialization"
|
||||
import { DesktopFirstLaunchOnboarding } from "./onboarding"
|
||||
import { resetZoom, setPinchZoomEnabled, webviewZoom, zoomIn, zoomOut } from "./webview-zoom"
|
||||
import { availableStartupServer, readyWslConnections } from "./wsl/connections"
|
||||
import "./styles.css"
|
||||
|
|
@ -347,6 +348,7 @@ function DesktopRoot(props: { windowState: DesktopWindowState }) {
|
|||
const router = (props: BaseRouterProps) => (
|
||||
<DesktopMemoryRouter {...props} windowID={platform.windowID ?? "browser"} />
|
||||
)
|
||||
const onboarding = Promise.withResolvers<void>()
|
||||
|
||||
function handleClick(e: MouseEvent) {
|
||||
const link = (e.target as HTMLElement).closest("a.external-link") as HTMLAnchorElement | null
|
||||
|
|
@ -400,12 +402,22 @@ function DesktopRoot(props: { windowState: DesktopWindowState }) {
|
|||
const effectiveDefaultServer = createMemo(() =>
|
||||
ServerConnection.Key.make(availableStartupServer(defaultServer.latest, wslServers.data)),
|
||||
)
|
||||
|
||||
return (
|
||||
<Show when={ready()} fallback={<LoadingSplash />}>
|
||||
<Show when={effectiveDefaultServer()} keyed>
|
||||
{(key) => (
|
||||
<AppInterface defaultServer={key} servers={servers()} router={router}>
|
||||
<AppInterface
|
||||
defaultServer={key}
|
||||
servers={servers()}
|
||||
router={router}
|
||||
startup={onboarding.promise}
|
||||
serverScoped={
|
||||
<DesktopFirstLaunchOnboarding
|
||||
initialUrl={getLastActiveUrl(platform.windowID ?? "browser")}
|
||||
onLoaded={onboarding.resolve}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Inner />
|
||||
</AppInterface>
|
||||
)}
|
||||
|
|
|
|||
79
packages/desktop/src/renderer/onboarding.tsx
Normal file
79
packages/desktop/src/renderer/onboarding.tsx
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import {
|
||||
ServerConnection,
|
||||
useLayout,
|
||||
useProviders,
|
||||
useServer,
|
||||
useServerSDK,
|
||||
useServerSync,
|
||||
useTabs,
|
||||
} from "@opencode-ai/app"
|
||||
import { onMount, startTransition } from "solid-js"
|
||||
|
||||
export function DesktopFirstLaunchOnboarding(props: { initialUrl: string; onLoaded: () => void }) {
|
||||
const server = useServer()
|
||||
const serverSDK = useServerSDK()
|
||||
const serverSync = useServerSync()
|
||||
const layout = useLayout()
|
||||
const providers = useProviders()
|
||||
const tabs = useTabs()
|
||||
|
||||
onMount(() => {
|
||||
void runFirstLaunchOnboarding().finally(props.onLoaded)
|
||||
})
|
||||
|
||||
async function runFirstLaunchOnboarding() {
|
||||
try {
|
||||
await Promise.all(
|
||||
[server.ready.promise, layout.ready.promise, tabs.ready.promise, tabs.recentReady.promise].map(
|
||||
(p) => p ?? Promise.resolve(),
|
||||
),
|
||||
)
|
||||
if (!server.isLocal()) return
|
||||
|
||||
const pending = await window.api.isFirstLaunchOnboardingPending()
|
||||
if (!pending) return
|
||||
|
||||
const sessions = await serverSDK()
|
||||
.client.session.list()
|
||||
.then((x) => x.data ?? [])
|
||||
.catch(() => undefined)
|
||||
const connectedProviders = providers.connected()
|
||||
const paidProviders = providers.paid()
|
||||
const persistedProjects = layout.projects.list()
|
||||
const shouldTrigger =
|
||||
props.initialUrl === "/" &&
|
||||
sessions?.length === 0 &&
|
||||
paidProviders.length === 0 &&
|
||||
persistedProjects.length === 0 &&
|
||||
tabs.store.length === 0 &&
|
||||
server.list.every(ServerConnection.builtin)
|
||||
|
||||
console.info("[desktop-onboarding] first launch onboarding evaluated", {
|
||||
pending,
|
||||
shouldTrigger,
|
||||
initialUrl: props.initialUrl,
|
||||
sessions: sessions?.length,
|
||||
connectedProviders: connectedProviders.length,
|
||||
paidProviders: paidProviders.length,
|
||||
serverProjects: serverSync().data.project.length,
|
||||
persistedProjects: persistedProjects.length,
|
||||
tabs: tabs.store.length,
|
||||
servers: server.list.map(ServerConnection.key),
|
||||
})
|
||||
|
||||
const directory = await window.api.finishFirstLaunchOnboarding(shouldTrigger)
|
||||
if (!shouldTrigger || !directory) return
|
||||
|
||||
console.info("[desktop-onboarding] starting first launch draft", { directory })
|
||||
server.projects.open(directory)
|
||||
server.projects.touch(directory)
|
||||
await startTransition(() => {
|
||||
tabs.newDraft({ server: server.key, directory })
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("[desktop-onboarding] first launch onboarding failed", error)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue