refactor(app): centralize sync query options (#25941)
Co-authored-by: Brendan Allan <git@brendonovich.dev> Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com>
This commit is contained in:
co-authored by
Brendan Allan
Brendan Allan
parent
ff38bbeeeb
commit
caf1151cb5
@@ -6,7 +6,8 @@ import { Dialog } from "@opencode-ai/ui/dialog"
|
|||||||
import { List } from "@opencode-ai/ui/list"
|
import { List } from "@opencode-ai/ui/list"
|
||||||
import { Switch } from "@opencode-ai/ui/switch"
|
import { Switch } from "@opencode-ai/ui/switch"
|
||||||
import { useLanguage } from "@/context/language"
|
import { useLanguage } from "@/context/language"
|
||||||
import { mcpQueryKey } from "@/context/global-sync"
|
import { useQueryOptions } from "@/context/global-sync"
|
||||||
|
import { pathKey } from "@/utils/path-key"
|
||||||
|
|
||||||
const statusLabels = {
|
const statusLabels = {
|
||||||
connected: "mcp.status.connected",
|
connected: "mcp.status.connected",
|
||||||
@@ -20,6 +21,7 @@ export const DialogSelectMcp: Component = () => {
|
|||||||
const sdk = useSDK()
|
const sdk = useSDK()
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
const queryOptions = useQueryOptions()
|
||||||
|
|
||||||
const items = createMemo(() =>
|
const items = createMemo(() =>
|
||||||
Object.entries(sync.data.mcp ?? {})
|
Object.entries(sync.data.mcp ?? {})
|
||||||
@@ -32,7 +34,7 @@ export const DialogSelectMcp: Component = () => {
|
|||||||
if (sync.data.mcp[name]?.status === "connected") await sdk.client.mcp.disconnect({ name })
|
if (sync.data.mcp[name]?.status === "connected") await sdk.client.mcp.disconnect({ name })
|
||||||
else await sdk.client.mcp.connect({ name })
|
else await sdk.client.mcp.connect({ name })
|
||||||
},
|
},
|
||||||
onSuccess: () => queryClient.refetchQueries({ queryKey: mcpQueryKey(sync.directory) }),
|
onSuccess: () => queryClient.refetchQueries(queryOptions.mcp(pathKey(sync.directory))),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const enabledCount = createMemo(() => items().filter((i) => i.status === "connected").length)
|
const enabledCount = createMemo(() => items().filter((i) => i.status === "connected").length)
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import {
|
|||||||
} from "@/context/prompt"
|
} from "@/context/prompt"
|
||||||
import { useLayout } from "@/context/layout"
|
import { useLayout } from "@/context/layout"
|
||||||
import { useSDK } from "@/context/sdk"
|
import { useSDK } from "@/context/sdk"
|
||||||
import { useGlobalSDK } from "@/context/global-sdk"
|
|
||||||
import { useSync } from "@/context/sync"
|
import { useSync } from "@/context/sync"
|
||||||
import { useComments } from "@/context/comments"
|
import { useComments } from "@/context/comments"
|
||||||
import { Button } from "@opencode-ai/ui/button"
|
import { Button } from "@opencode-ai/ui/button"
|
||||||
@@ -56,7 +55,8 @@ import { PromptDragOverlay } from "./prompt-input/drag-overlay"
|
|||||||
import { promptPlaceholder } from "./prompt-input/placeholder"
|
import { promptPlaceholder } from "./prompt-input/placeholder"
|
||||||
import { ImagePreview } from "@opencode-ai/ui/image-preview"
|
import { ImagePreview } from "@opencode-ai/ui/image-preview"
|
||||||
import { useQueries } from "@tanstack/solid-query"
|
import { useQueries } from "@tanstack/solid-query"
|
||||||
import { loadAgentsQuery, loadProvidersQuery } from "@/context/global-sync/bootstrap"
|
import { useQueryOptions } from "@/context/global-sync"
|
||||||
|
import { pathKey } from "@/utils/path-key"
|
||||||
|
|
||||||
interface PromptInputProps {
|
interface PromptInputProps {
|
||||||
class?: string
|
class?: string
|
||||||
@@ -103,7 +103,7 @@ const NON_EMPTY_TEXT = /[^\s\u200B]/
|
|||||||
|
|
||||||
export const PromptInput: Component<PromptInputProps> = (props) => {
|
export const PromptInput: Component<PromptInputProps> = (props) => {
|
||||||
const sdk = useSDK()
|
const sdk = useSDK()
|
||||||
const globalSDK = useGlobalSDK()
|
const queryOptions = useQueryOptions()
|
||||||
|
|
||||||
const sync = useSync()
|
const sync = useSync()
|
||||||
const local = useLocal()
|
const local = useLocal()
|
||||||
@@ -1256,9 +1256,9 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
|
|||||||
|
|
||||||
const [agentsQuery, globalProvidersQuery, providersQuery] = useQueries(() => ({
|
const [agentsQuery, globalProvidersQuery, providersQuery] = useQueries(() => ({
|
||||||
queries: [
|
queries: [
|
||||||
loadAgentsQuery(sdk.directory, sdk.client),
|
queryOptions.agents(pathKey(sdk.directory)),
|
||||||
loadProvidersQuery(null, globalSDK.client),
|
queryOptions.providers(null),
|
||||||
loadProvidersQuery(sdk.directory, sdk.client),
|
queryOptions.providers(pathKey(sdk.directory)),
|
||||||
],
|
],
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import { useSDK } from "@/context/sdk"
|
|||||||
import { normalizeServerUrl, ServerConnection, useServer } from "@/context/server"
|
import { normalizeServerUrl, ServerConnection, useServer } from "@/context/server"
|
||||||
import { useSync } from "@/context/sync"
|
import { useSync } from "@/context/sync"
|
||||||
import { useCheckServerHealth, type ServerHealth } from "@/utils/server-health"
|
import { useCheckServerHealth, type ServerHealth } from "@/utils/server-health"
|
||||||
import { mcpQueryKey } from "@/context/global-sync"
|
import { useQueryOptions } from "@/context/global-sync"
|
||||||
|
import { pathKey } from "@/utils/path-key"
|
||||||
|
|
||||||
const pollMs = 10_000
|
const pollMs = 10_000
|
||||||
|
|
||||||
@@ -139,13 +140,14 @@ const useMcpToggleMutation = () => {
|
|||||||
const sdk = useSDK()
|
const sdk = useSDK()
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
const queryOptions = useQueryOptions()
|
||||||
|
|
||||||
return useMutation(() => ({
|
return useMutation(() => ({
|
||||||
mutationFn: async (name: string) => {
|
mutationFn: async (name: string) => {
|
||||||
const status = sync.data.mcp[name]
|
const status = sync.data.mcp[name]
|
||||||
await (status?.status === "connected" ? sdk.client.mcp.disconnect({ name }) : sdk.client.mcp.connect({ name }))
|
await (status?.status === "connected" ? sdk.client.mcp.disconnect({ name }) : sdk.client.mcp.connect({ name }))
|
||||||
},
|
},
|
||||||
onSuccess: () => queryClient.refetchQueries({ queryKey: mcpQueryKey(sync.directory) }),
|
onSuccess: () => queryClient.refetchQueries(queryOptions.mcp(pathKey(sync.directory))),
|
||||||
onError: (err) => {
|
onError: (err) => {
|
||||||
showToast({
|
showToast({
|
||||||
variant: "error",
|
variant: "error",
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ import {
|
|||||||
bootstrapDirectory,
|
bootstrapDirectory,
|
||||||
bootstrapGlobal,
|
bootstrapGlobal,
|
||||||
clearProviderRev,
|
clearProviderRev,
|
||||||
|
loadAgentsQuery,
|
||||||
loadGlobalConfigQuery,
|
loadGlobalConfigQuery,
|
||||||
loadPathQuery,
|
loadPathQuery,
|
||||||
|
loadProjectsQuery,
|
||||||
loadProvidersQuery,
|
loadProvidersQuery,
|
||||||
} from "./global-sync/bootstrap"
|
} from "./global-sync/bootstrap"
|
||||||
import { createChildStoreManager } from "./global-sync/child-store"
|
import { createChildStoreManager } from "./global-sync/child-store"
|
||||||
@@ -33,6 +35,7 @@ import { formatServerError } from "@/utils/server-errors"
|
|||||||
import { queryOptions, useMutation, useQueries, useQuery, useQueryClient } from "@tanstack/solid-query"
|
import { queryOptions, useMutation, useQueries, useQuery, useQueryClient } from "@tanstack/solid-query"
|
||||||
import { createRefreshQueue } from "./global-sync/queue"
|
import { createRefreshQueue } from "./global-sync/queue"
|
||||||
import { directoryKey } from "./global-sync/utils"
|
import { directoryKey } from "./global-sync/utils"
|
||||||
|
import { PathKey } from "@/utils/path-key"
|
||||||
|
|
||||||
type GlobalStore = {
|
type GlobalStore = {
|
||||||
ready: boolean
|
ready: boolean
|
||||||
@@ -48,24 +51,33 @@ type GlobalStore = {
|
|||||||
reload: undefined | "pending" | "complete"
|
reload: undefined | "pending" | "complete"
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadSessionsQueryKey = (directory: string) => [directory, "loadSessions"] as const
|
|
||||||
|
|
||||||
export const mcpQueryKey = (directory: string) => [directory, "mcp"] as const
|
|
||||||
|
|
||||||
export const loadMcpQuery = (directory: string, sdk: OpencodeClient) =>
|
export const loadMcpQuery = (directory: string, sdk: OpencodeClient) =>
|
||||||
queryOptions({
|
queryOptions({
|
||||||
queryKey: mcpQueryKey(directory),
|
queryKey: [directory, "mcp"] as const,
|
||||||
queryFn: () => sdk.mcp.status().then((r) => r.data ?? {}),
|
queryFn: () => sdk.mcp.status().then((r) => r.data ?? {}),
|
||||||
})
|
})
|
||||||
|
|
||||||
export const lspQueryKey = (directory: string) => [directory, "lsp"] as const
|
|
||||||
|
|
||||||
export const loadLspQuery = (directory: string, sdk: OpencodeClient) =>
|
export const loadLspQuery = (directory: string, sdk: OpencodeClient) =>
|
||||||
queryOptions({
|
queryOptions({
|
||||||
queryKey: lspQueryKey(directory),
|
queryKey: [directory, "lsp"] as const,
|
||||||
queryFn: () => sdk.lsp.status().then((r) => r.data ?? []),
|
queryFn: () => sdk.lsp.status().then((r) => r.data ?? []),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function makeQueryOptionsApi(globalSDK: () => OpencodeClient, sdkFor: (dir: PathKey) => OpencodeClient) {
|
||||||
|
return {
|
||||||
|
globalConfig: () => loadGlobalConfigQuery(globalSDK()),
|
||||||
|
projects: () => loadProjectsQuery(globalSDK()),
|
||||||
|
providers: (directory: PathKey | null) =>
|
||||||
|
loadProvidersQuery(directory, directory === null ? globalSDK() : sdkFor(directory)),
|
||||||
|
path: (directory: PathKey | null) => loadPathQuery(directory, directory === null ? globalSDK() : sdkFor(directory)),
|
||||||
|
agents: (directory: PathKey) => loadAgentsQuery(directory, sdkFor(directory)),
|
||||||
|
mcp: (directory: PathKey) => loadMcpQuery(directory, sdkFor(directory)),
|
||||||
|
lsp: (directory: PathKey) => loadLspQuery(directory, sdkFor(directory)),
|
||||||
|
sessions: (directory: PathKey) => ({ queryKey: [directory, "loadSessions"] as const }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export type QueryOptionsApi = ReturnType<typeof makeQueryOptionsApi>
|
||||||
|
|
||||||
function createGlobalSync() {
|
function createGlobalSync() {
|
||||||
const globalSDK = useGlobalSDK()
|
const globalSDK = useGlobalSDK()
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
@@ -77,12 +89,22 @@ function createGlobalSync() {
|
|||||||
const sessionLoads = new Map<string, Promise<void>>()
|
const sessionLoads = new Map<string, Promise<void>>()
|
||||||
const sessionMeta = new Map<string, { limit: number }>()
|
const sessionMeta = new Map<string, { limit: number }>()
|
||||||
|
|
||||||
|
const sdkFor = (directory: string) => {
|
||||||
|
const key = directoryKey(directory)
|
||||||
|
const cached = sdkCache.get(key)
|
||||||
|
if (cached) return cached
|
||||||
|
const sdk = globalSDK.createClient({
|
||||||
|
directory,
|
||||||
|
throwOnError: true,
|
||||||
|
})
|
||||||
|
sdkCache.set(key, sdk)
|
||||||
|
return sdk
|
||||||
|
}
|
||||||
|
|
||||||
|
const queryOptionsApi = makeQueryOptionsApi(() => globalSDK.client, sdkFor)
|
||||||
|
|
||||||
const [configQuery, providerQuery, pathQuery] = useQueries(() => ({
|
const [configQuery, providerQuery, pathQuery] = useQueries(() => ({
|
||||||
queries: [
|
queries: [queryOptionsApi.globalConfig(), queryOptionsApi.providers(null), queryOptionsApi.path(null)],
|
||||||
loadGlobalConfigQuery(globalSDK.client),
|
|
||||||
loadProvidersQuery(null, globalSDK.client),
|
|
||||||
loadPathQuery(null, globalSDK.client),
|
|
||||||
],
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const [globalStore, setGlobalStore] = createStore<GlobalStore>({
|
const [globalStore, setGlobalStore] = createStore<GlobalStore>({
|
||||||
@@ -181,18 +203,6 @@ function createGlobalSync() {
|
|||||||
bootstrapInstance,
|
bootstrapInstance,
|
||||||
})
|
})
|
||||||
|
|
||||||
const sdkFor = (directory: string) => {
|
|
||||||
const key = directoryKey(directory)
|
|
||||||
const cached = sdkCache.get(key)
|
|
||||||
if (cached) return cached
|
|
||||||
const sdk = globalSDK.createClient({
|
|
||||||
directory,
|
|
||||||
throwOnError: true,
|
|
||||||
})
|
|
||||||
sdkCache.set(key, sdk)
|
|
||||||
return sdk
|
|
||||||
}
|
|
||||||
|
|
||||||
const children = createChildStoreManager({
|
const children = createChildStoreManager({
|
||||||
owner,
|
owner,
|
||||||
isBooting: (directory) => booting.has(directory),
|
isBooting: (directory) => booting.has(directory),
|
||||||
@@ -209,7 +219,7 @@ function createGlobalSync() {
|
|||||||
clearSessionPrefetchDirectory(key)
|
clearSessionPrefetchDirectory(key)
|
||||||
},
|
},
|
||||||
translate: language.t,
|
translate: language.t,
|
||||||
getSdk: sdkFor,
|
queryOptions: queryOptionsApi,
|
||||||
global: {
|
global: {
|
||||||
provider: globalStore.provider,
|
provider: globalStore.provider,
|
||||||
},
|
},
|
||||||
@@ -239,7 +249,7 @@ function createGlobalSync() {
|
|||||||
const limit = Math.max(store.limit + SESSION_RECENT_LIMIT, SESSION_RECENT_LIMIT)
|
const limit = Math.max(store.limit + SESSION_RECENT_LIMIT, SESSION_RECENT_LIMIT)
|
||||||
const promise = queryClient
|
const promise = queryClient
|
||||||
.fetchQuery({
|
.fetchQuery({
|
||||||
queryKey: loadSessionsQueryKey(key),
|
...queryOptionsApi.sessions(key),
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
loadRootSessionsWithFallback({
|
loadRootSessionsWithFallback({
|
||||||
directory,
|
directory,
|
||||||
@@ -368,7 +378,7 @@ function createGlobalSync() {
|
|||||||
setSessionTodo,
|
setSessionTodo,
|
||||||
vcsCache: children.vcsCache.get(key),
|
vcsCache: children.vcsCache.get(key),
|
||||||
loadLsp: () => {
|
loadLsp: () => {
|
||||||
void queryClient.fetchQuery(loadLspQuery(key, sdkFor(directory)))
|
void queryClient.fetchQuery(queryOptionsApi.lsp(key))
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -426,6 +436,7 @@ function createGlobalSync() {
|
|||||||
},
|
},
|
||||||
child: children.child,
|
child: children.child,
|
||||||
peek: children.peek,
|
peek: children.peek,
|
||||||
|
queryOptions: queryOptionsApi,
|
||||||
// bootstrap,
|
// bootstrap,
|
||||||
updateConfig: updateConfigMutation.mutateAsync,
|
updateConfig: updateConfigMutation.mutateAsync,
|
||||||
project: projectApi,
|
project: projectApi,
|
||||||
@@ -447,3 +458,7 @@ export function useGlobalSync() {
|
|||||||
if (!context) throw new Error("useGlobalSync must be used within GlobalSyncProvider")
|
if (!context) throw new Error("useGlobalSync must be used within GlobalSyncProvider")
|
||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useQueryOptions() {
|
||||||
|
return useGlobalSync().queryOptions
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ describe("createChildStoreManager", () => {
|
|||||||
onBootstrap() {},
|
onBootstrap() {},
|
||||||
onDispose() {},
|
onDispose() {},
|
||||||
translate: (key) => key,
|
translate: (key) => key,
|
||||||
getSdk: () => null!,
|
queryOptions: {} as any,
|
||||||
global: { provider: null! },
|
global: { provider: null! },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createRoot, getOwner, onCleanup, runWithOwner, type Owner } from "solid-js"
|
import { createRoot, getOwner, onCleanup, runWithOwner, type Owner } from "solid-js"
|
||||||
import { createStore, type SetStoreFunction, type Store } from "solid-js/store"
|
import { createStore, type SetStoreFunction, type Store } from "solid-js/store"
|
||||||
import { Persist, persisted } from "@/utils/persist"
|
import { Persist, persisted } from "@/utils/persist"
|
||||||
import type { OpencodeClient, ProviderListResponse, VcsInfo } from "@opencode-ai/sdk/v2/client"
|
import type { ProviderListResponse, VcsInfo } from "@opencode-ai/sdk/v2/client"
|
||||||
import {
|
import {
|
||||||
DIR_IDLE_TTL_MS,
|
DIR_IDLE_TTL_MS,
|
||||||
MAX_DIR_STORES,
|
MAX_DIR_STORES,
|
||||||
@@ -15,8 +15,7 @@ import {
|
|||||||
} from "./types"
|
} from "./types"
|
||||||
import { canDisposeDirectory, pickDirectoriesToEvict } from "./eviction"
|
import { canDisposeDirectory, pickDirectoriesToEvict } from "./eviction"
|
||||||
import { useQueries } from "@tanstack/solid-query"
|
import { useQueries } from "@tanstack/solid-query"
|
||||||
import { loadPathQuery, loadProvidersQuery } from "./bootstrap"
|
import { QueryOptionsApi } from "../global-sync"
|
||||||
import { loadLspQuery, loadMcpQuery } from "../global-sync"
|
|
||||||
import { directoryKey, type DirectoryKey } from "./utils"
|
import { directoryKey, type DirectoryKey } from "./utils"
|
||||||
|
|
||||||
export function createChildStoreManager(input: {
|
export function createChildStoreManager(input: {
|
||||||
@@ -26,7 +25,7 @@ export function createChildStoreManager(input: {
|
|||||||
onBootstrap: (directory: string) => void
|
onBootstrap: (directory: string) => void
|
||||||
onDispose: (directory: string) => void
|
onDispose: (directory: string) => void
|
||||||
translate: (key: string, vars?: Record<string, string | number>) => string
|
translate: (key: string, vars?: Record<string, string | number>) => string
|
||||||
getSdk: (directory: string) => OpencodeClient
|
queryOptions: QueryOptionsApi
|
||||||
global: {
|
global: {
|
||||||
provider: ProviderListResponse
|
provider: ProviderListResponse
|
||||||
}
|
}
|
||||||
@@ -171,17 +170,15 @@ export function createChildStoreManager(input: {
|
|||||||
|
|
||||||
const init = () =>
|
const init = () =>
|
||||||
createRoot((dispose) => {
|
createRoot((dispose) => {
|
||||||
const sdk = input.getSdk(directory)
|
|
||||||
|
|
||||||
const initialMeta = meta[0].value
|
const initialMeta = meta[0].value
|
||||||
const initialIcon = icon[0].value
|
const initialIcon = icon[0].value
|
||||||
|
|
||||||
const [pathQuery, mcpQuery, lspQuery, providerQuery] = useQueries(() => ({
|
const [pathQuery, mcpQuery, lspQuery, providerQuery] = useQueries(() => ({
|
||||||
queries: [
|
queries: [
|
||||||
loadPathQuery(key, sdk),
|
input.queryOptions.path(key),
|
||||||
loadMcpQuery(key, sdk),
|
input.queryOptions.mcp(key),
|
||||||
loadLspQuery(key, sdk),
|
input.queryOptions.lsp(key),
|
||||||
loadProvidersQuery(key, sdk),
|
input.queryOptions.providers(key),
|
||||||
],
|
],
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { Spinner } from "@opencode-ai/ui/spinner"
|
|||||||
import { Tooltip } from "@opencode-ai/ui/tooltip"
|
import { Tooltip } from "@opencode-ai/ui/tooltip"
|
||||||
import { type Session } from "@opencode-ai/sdk/v2/client"
|
import { type Session } from "@opencode-ai/sdk/v2/client"
|
||||||
import { type LocalProject } from "@/context/layout"
|
import { type LocalProject } from "@/context/layout"
|
||||||
import { loadSessionsQueryKey, useGlobalSync } from "@/context/global-sync"
|
import { useGlobalSync, useQueryOptions } from "@/context/global-sync"
|
||||||
import { useLanguage } from "@/context/language"
|
import { useLanguage } from "@/context/language"
|
||||||
import { pathKey } from "@/utils/path-key"
|
import { pathKey } from "@/utils/path-key"
|
||||||
import { NewSessionItem, SessionItem, SessionSkeleton } from "./sidebar-items"
|
import { NewSessionItem, SessionItem, SessionSkeleton } from "./sidebar-items"
|
||||||
@@ -300,6 +300,7 @@ export const SortableWorkspace = (props: {
|
|||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const params = useParams()
|
const params = useParams()
|
||||||
const globalSync = useGlobalSync()
|
const globalSync = useGlobalSync()
|
||||||
|
const queryOptions = useQueryOptions()
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
const sortable = createSortable(props.directory)
|
const sortable = createSortable(props.directory)
|
||||||
const [workspaceStore, setWorkspaceStore] = globalSync.child(props.directory, { bootstrap: false })
|
const [workspaceStore, setWorkspaceStore] = globalSync.child(props.directory, { bootstrap: false })
|
||||||
@@ -320,7 +321,7 @@ export const SortableWorkspace = (props: {
|
|||||||
const boot = createMemo(() => open() || active())
|
const boot = createMemo(() => open() || active())
|
||||||
const count = createMemo(() => sessions()?.length ?? 0)
|
const count = createMemo(() => sessions()?.length ?? 0)
|
||||||
const hasMore = createMemo(() => workspaceStore.sessionTotal > count())
|
const hasMore = createMemo(() => workspaceStore.sessionTotal > count())
|
||||||
const fetching = useIsFetching(() => ({ queryKey: loadSessionsQueryKey(props.directory) }))
|
const fetching = useIsFetching(() => queryOptions.sessions(pathKey(props.directory)))
|
||||||
const busy = createMemo(() => props.ctx.isBusy(props.directory))
|
const busy = createMemo(() => props.ctx.isBusy(props.directory))
|
||||||
const loading = () => fetching() > 0 && count() === 0
|
const loading = () => fetching() > 0 && count() === 0
|
||||||
const touch = createMediaQuery("(hover: none)")
|
const touch = createMediaQuery("(hover: none)")
|
||||||
@@ -446,6 +447,7 @@ export const LocalWorkspace = (props: {
|
|||||||
mobile?: boolean
|
mobile?: boolean
|
||||||
}): JSX.Element => {
|
}): JSX.Element => {
|
||||||
const globalSync = useGlobalSync()
|
const globalSync = useGlobalSync()
|
||||||
|
const queryOptions = useQueryOptions()
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
const workspace = createMemo(() => {
|
const workspace = createMemo(() => {
|
||||||
const [store, setStore] = globalSync.child(props.project.worktree)
|
const [store, setStore] = globalSync.child(props.project.worktree)
|
||||||
@@ -454,7 +456,7 @@ export const LocalWorkspace = (props: {
|
|||||||
const slug = createMemo(() => base64Encode(props.project.worktree))
|
const slug = createMemo(() => base64Encode(props.project.worktree))
|
||||||
const sessions = createMemo(() => sortedRootSessions(workspace().store, props.sortNow()))
|
const sessions = createMemo(() => sortedRootSessions(workspace().store, props.sortNow()))
|
||||||
const count = createMemo(() => sessions()?.length ?? 0)
|
const count = createMemo(() => sessions()?.length ?? 0)
|
||||||
const fetching = useIsFetching(() => ({ queryKey: loadSessionsQueryKey(props.project.worktree) }))
|
const fetching = useIsFetching(() => queryOptions.sessions(pathKey(props.project.worktree)))
|
||||||
const hasMore = createMemo(() => workspace().store.sessionTotal > count())
|
const hasMore = createMemo(() => workspace().store.sessionTotal > count())
|
||||||
const loading = () => fetching() > 0 && count() === 0
|
const loading = () => fetching() > 0 && count() === 0
|
||||||
const loadMore = async () => {
|
const loadMore = async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user