diff --git a/packages/app/src/context/file.tsx b/packages/app/src/context/file.tsx index 805936cd8..962af19f0 100644 --- a/packages/app/src/context/file.tsx +++ b/packages/app/src/context/file.tsx @@ -561,6 +561,7 @@ export const { use: useFile, provider: FileProvider } = createSimpleContext({ const stop = sdk.event.listen((e) => { const event = e.details + console.log(event) if (event.type !== "file.watcher.updated") return const path = normalize(event.properties.file) if (!path) return diff --git a/packages/app/src/context/local.tsx b/packages/app/src/context/local.tsx index 4b27e6d37..5f5d51dbd 100644 --- a/packages/app/src/context/local.tsx +++ b/packages/app/src/context/local.tsx @@ -1,5 +1,5 @@ -import { createStore, produce, reconcile } from "solid-js/store" -import { batch, createEffect, createMemo, onCleanup } from "solid-js" +import { createStore } from "solid-js/store" +import { batch, createMemo } from "solid-js" import type { FileContent, FileNode, Model, Provider, File as FileStatus } from "@opencode-ai/sdk/v2" import { createSimpleContext } from "@opencode-ai/ui/context" import { useSDK } from "./sdk" @@ -7,8 +7,6 @@ import { useSync } from "./sync" import { base64Encode } from "@opencode-ai/util/encode" import { useProviders } from "@/hooks/use-providers" import { useModels } from "@/context/models" -import { showToast } from "@opencode-ai/ui/toast" -import { useLanguage } from "@/context/language" export type LocalFile = FileNode & Partial<{ @@ -41,7 +39,6 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const sdk = useSDK() const sync = useSync() const providers = useProviders() - const language = useLanguage() function isModelValid(model: ModelKey) { const provider = providers.all().find((x) => x.id === model.providerID) @@ -246,247 +243,10 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ } })() - const file = (() => { - const [store, setStore] = createStore<{ - node: Record - }>({ - node: {}, // Object.fromEntries(sync.data.node.map((x) => [x.path, x])), - }) - - const scope = createMemo(() => sdk.directory) - createEffect(() => { - scope() - setStore("node", {}) - }) - - // const changeset = createMemo(() => new Set(sync.data.changes.map((f) => f.path))) - // const changes = createMemo(() => Array.from(changeset()).sort((a, b) => a.localeCompare(b))) - - // createEffect((prev: FileStatus[]) => { - // const removed = prev.filter((p) => !sync.data.changes.find((c) => c.path === p.path)) - // for (const p of removed) { - // setStore( - // "node", - // p.path, - // produce((draft) => { - // draft.status = undefined - // draft.view = "raw" - // }), - // ) - // load(p.path) - // } - // for (const p of sync.data.changes) { - // if (store.node[p.path] === undefined) { - // fetch(p.path).then(() => { - // if (store.node[p.path] === undefined) return - // setStore("node", p.path, "status", p) - // }) - // } else { - // setStore("node", p.path, "status", p) - // } - // } - // return sync.data.changes - // }, sync.data.changes) - - // const changed = (path: string) => { - // const node = store.node[path] - // if (node?.status) return true - // const set = changeset() - // if (set.has(path)) return true - // for (const p of set) { - // if (p.startsWith(path ? path + "/" : "")) return true - // } - // return false - // } - - // const resetNode = (path: string) => { - // setStore("node", path, { - // loaded: undefined, - // pinned: undefined, - // content: undefined, - // selection: undefined, - // scrollTop: undefined, - // folded: undefined, - // view: undefined, - // selectedChange: undefined, - // }) - // } - - const relative = (path: string) => path.replace(sync.data.path.directory + "/", "") - - const load = async (path: string) => { - const directory = scope() - const client = sdk.client - const relativePath = relative(path) - await client.file - .read({ path: relativePath }) - .then((x) => { - if (scope() !== directory) return - if (!store.node[relativePath]) return - setStore( - "node", - relativePath, - produce((draft) => { - draft.loaded = true - draft.content = x.data - }), - ) - }) - .catch((e) => { - if (scope() !== directory) return - showToast({ - variant: "error", - title: language.t("toast.file.loadFailed.title"), - description: e.message, - }) - }) - } - - const fetch = async (path: string) => { - const relativePath = relative(path) - const parent = relativePath.split("/").slice(0, -1).join("/") - if (parent) { - await list(parent) - } - } - - const init = async (path: string) => { - const relativePath = relative(path) - if (!store.node[relativePath]) await fetch(path) - if (store.node[relativePath]?.loaded) return - return load(relativePath) - } - - const open = async (path: string, options?: { pinned?: boolean; view?: LocalFile["view"] }) => { - const relativePath = relative(path) - if (!store.node[relativePath]) await fetch(path) - // setStore("opened", (x) => { - // if (x.includes(relativePath)) return x - // return [ - // ...opened() - // .filter((x) => x.pinned) - // .map((x) => x.path), - // relativePath, - // ] - // }) - // setStore("active", relativePath) - // context.addActive() - if (options?.pinned) setStore("node", path, "pinned", true) - if (options?.view && store.node[relativePath].view === undefined) setStore("node", path, "view", options.view) - if (store.node[relativePath]?.loaded) return - return load(relativePath) - } - - const list = async (path: string) => { - const directory = scope() - const client = sdk.client - return client.file - .list({ path: path + "/" }) - .then((x) => { - if (scope() !== directory) return - setStore( - "node", - produce((draft) => { - x.data!.forEach((node) => { - if (node.path in draft) return - draft[node.path] = node - }) - }), - ) - }) - .catch(() => {}) - } - - const searchFiles = (query: string) => sdk.client.find.files({ query, dirs: "false" }).then((x) => x.data!) - const searchFilesAndDirectories = (query: string) => - sdk.client.find.files({ query, dirs: "true" }).then((x) => x.data!) - - const unsub = sdk.event.listen((e) => { - const event = e.details - switch (event.type) { - case "file.watcher.updated": - const relativePath = relative(event.properties.file) - if (relativePath.startsWith(".git/")) return - if (store.node[relativePath]) load(relativePath) - break - } - }) - onCleanup(unsub) - - return { - node: async (path: string) => { - if (!store.node[path] || !store.node[path].loaded) { - await init(path) - } - return store.node[path] - }, - update: (path: string, node: LocalFile) => setStore("node", path, reconcile(node)), - open, - load, - init, - expand(path: string) { - setStore("node", path, "expanded", true) - if (store.node[path]?.loaded) return - setStore("node", path, "loaded", true) - list(path) - }, - collapse(path: string) { - setStore("node", path, "expanded", false) - }, - select(path: string, selection: TextSelection | undefined) { - setStore("node", path, "selection", selection) - }, - scroll(path: string, scrollTop: number) { - setStore("node", path, "scrollTop", scrollTop) - }, - view(path: string): View { - const n = store.node[path] - return n && n.view ? n.view : "raw" - }, - setView(path: string, view: View) { - setStore("node", path, "view", view) - }, - unfold(path: string, key: string) { - setStore("node", path, "folded", (xs) => { - const a = xs ?? [] - if (a.includes(key)) return a - return [...a, key] - }) - }, - fold(path: string, key: string) { - setStore("node", path, "folded", (xs) => (xs ?? []).filter((k) => k !== key)) - }, - folded(path: string) { - const n = store.node[path] - return n && n.folded ? n.folded : [] - }, - changeIndex(path: string) { - return store.node[path]?.selectedChange - }, - setChangeIndex(path: string, index: number | undefined) { - setStore("node", path, "selectedChange", index) - }, - // changes, - // changed, - children(path: string) { - return Object.values(store.node).filter( - (x) => - x.path.startsWith(path) && - x.path !== path && - !x.path.replace(new RegExp(`^${path + "/"}`), "").includes("/"), - ) - }, - searchFiles, - searchFilesAndDirectories, - relative, - } - })() - const result = { slug: createMemo(() => base64Encode(sdk.directory)), model, agent, - file, } return result },