diff options
| author | Brendan Allan <[email protected]> | 2026-03-19 21:59:14 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-03-19 19:29:14 +0530 |
| commit | 84f60d97a0c37c9136dfd965a66a0c8685a19e71 (patch) | |
| tree | 3257e9da5114ddf3775b310db9b5707cc48267c4 /packages/app/src/pages/directory-layout.tsx | |
| parent | cbf4b68fee8ff45c10a484b27f94e2dbe5f5dea2 (diff) | |
| download | opencode-84f60d97a0c37c9136dfd965a66a0c8685a19e71.tar.gz opencode-84f60d97a0c37c9136dfd965a66a0c8685a19e71.zip | |
app: fix workspace flicker when switching directories (#18207)
Co-authored-by: Shoubhit Dash <[email protected]>
Diffstat (limited to 'packages/app/src/pages/directory-layout.tsx')
| -rw-r--r-- | packages/app/src/pages/directory-layout.tsx | 97 |
1 files changed, 46 insertions, 51 deletions
diff --git a/packages/app/src/pages/directory-layout.tsx b/packages/app/src/pages/directory-layout.tsx index f993ffcd8..cd5e079a6 100644 --- a/packages/app/src/pages/directory-layout.tsx +++ b/packages/app/src/pages/directory-layout.tsx @@ -1,16 +1,15 @@ -import { batch, createEffect, createMemo, Show, type ParentProps } from "solid-js" -import { createStore } from "solid-js/store" +import { DataProvider } from "@opencode-ai/ui/context" +import { showToast } from "@opencode-ai/ui/toast" +import { base64Encode } from "@opencode-ai/util/encode" import { useLocation, useNavigate, useParams } from "@solidjs/router" +import { createMemo, createResource, type ParentProps, Show } from "solid-js" +import { useGlobalSDK } from "@/context/global-sdk" +import { useLanguage } from "@/context/language" +import { LocalProvider } from "@/context/local" import { SDKProvider } from "@/context/sdk" import { SyncProvider, useSync } from "@/context/sync" -import { LocalProvider } from "@/context/local" -import { useGlobalSDK } from "@/context/global-sdk" - -import { DataProvider } from "@opencode-ai/ui/context" -import { base64Encode } from "@opencode-ai/util/encode" import { decode64 } from "@/utils/base64" -import { showToast } from "@opencode-ai/ui/toast" -import { useLanguage } from "@/context/language" + function DirectoryDataProvider(props: ParentProps<{ directory: string }>) { const navigate = useNavigate() const sync = useSync() @@ -30,57 +29,53 @@ function DirectoryDataProvider(props: ParentProps<{ directory: string }>) { export default function Layout(props: ParentProps) { const params = useParams() - const navigate = useNavigate() const location = useLocation() const language = useLanguage() const globalSDK = useGlobalSDK() - const directory = createMemo(() => decode64(params.dir) ?? "") - const [state, setState] = createStore({ invalid: "", resolved: "" }) + const navigate = useNavigate() + let invalid = "" + + const [resolved] = createResource( + () => { + if (params.dir) return [location.pathname, params.dir] as const + }, + async ([pathname, b64Dir]) => { + const directory = decode64(b64Dir) - createEffect(() => { - if (!params.dir) return - const raw = directory() - if (!raw) { - if (state.invalid === params.dir) return - setState("invalid", params.dir) - showToast({ - variant: "error", - title: language.t("common.requestFailed"), - description: language.t("directory.error.invalidUrl"), - }) - navigate("/", { replace: true }) - return - } + if (!directory) { + if (invalid === params.dir) return + invalid = b64Dir + showToast({ + variant: "error", + title: language.t("common.requestFailed"), + description: language.t("directory.error.invalidUrl"), + }) + navigate("/", { replace: true }) + return + } - const current = params.dir - globalSDK - .createClient({ - directory: raw, - throwOnError: true, - }) - .path.get() - .then((x) => { - if (params.dir !== current) return - const next = x.data?.directory ?? raw - batch(() => { - setState("invalid", "") - setState("resolved", next) + return await globalSDK + .createClient({ + directory, + throwOnError: true, }) - if (next === raw) return - const path = location.pathname.slice(current.length + 1) - navigate(`/${base64Encode(next)}${path}${location.search}${location.hash}`, { replace: true }) - }) - .catch(() => { - if (params.dir !== current) return - batch(() => { - setState("invalid", "") - setState("resolved", raw) + .path.get() + .then((x) => { + const next = x.data?.directory ?? directory + invalid = "" + if (next === directory) return next + const path = pathname.slice(b64Dir.length + 1) + navigate(`/${base64Encode(next)}${path}${location.search}${location.hash}`, { replace: true }) }) - }) - }) + .catch(() => { + invalid = "" + return directory + }) + }, + ) return ( - <Show when={state.resolved} keyed> + <Show when={resolved()} keyed> {(resolved) => ( <SDKProvider directory={() => resolved}> <SyncProvider> |
