diff --git a/packages/app/src/pages/layout/sidebar-workspace.tsx b/packages/app/src/pages/layout/sidebar-workspace.tsx
index 9d74651b94..c1836fa8a4 100644
--- a/packages/app/src/pages/layout/sidebar-workspace.tsx
+++ b/packages/app/src/pages/layout/sidebar-workspace.tsx
@@ -14,10 +14,11 @@ import { Spinner } from "@opencode-ai/ui/spinner"
import { Tooltip } from "@opencode-ai/ui/tooltip"
import { type Session } from "@opencode-ai/sdk/v2/client"
import { type LocalProject } from "@/context/layout"
-import { useGlobalSync } from "@/context/global-sync"
+import { loadSessionsQuery, useGlobalSync } from "@/context/global-sync"
import { useLanguage } from "@/context/language"
import { NewSessionItem, SessionItem, SessionSkeleton } from "./sidebar-items"
import { sortedRootSessions, workspaceKey } from "./helpers"
+import { useQuery } from "@tanstack/solid-query"
type InlineEditorComponent = (props: {
id: string
@@ -454,7 +455,8 @@ export const LocalWorkspace = (props: {
const sessions = createMemo(() => sortedRootSessions(workspace().store, props.sortNow()))
const booted = createMemo((prev) => prev || workspace().store.status === "complete", false)
const count = createMemo(() => sessions()?.length ?? 0)
- const loading = createMemo(() => !booted() && count() === 0)
+ const query = useQuery(() => ({ ...loadSessionsQuery(props.project.worktree) }))
+ const loading = createMemo(() => query.isPending && count() === 0)
const hasMore = createMemo(() => workspace().store.sessionTotal > count())
const loadMore = async () => {
workspace().setStore("limit", (limit) => (limit ?? 0) + 5)
@@ -471,7 +473,7 @@ export const LocalWorkspace = (props: {
mobile={props.mobile}
ctx={props.ctx}
showNew={() => false}
- loading={loading}
+ loading={() => query.isLoading}
sessions={sessions}
hasMore={hasMore}
loadMore={loadMore}
diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx
index 1aba1bb08f..c4d642bf8d 100644
--- a/packages/app/src/pages/session.tsx
+++ b/packages/app/src/pages/session.tsx
@@ -13,6 +13,7 @@ import {
on,
onMount,
untrack,
+ createResource,
} from "solid-js"
import { makeEventListener } from "@solid-primitives/event-listener"
import { createMediaQuery } from "@solid-primitives/media"
@@ -804,8 +805,9 @@ export default function Page() {
const hasScrollGesture = () => Date.now() - ui.scrollGesture < scrollGestureWindowMs
- createEffect(
- on([() => sdk.directory, () => params.id] as const, ([, id]) => {
+ const [sessionSync] = createResource(
+ () => [sdk.directory, params.id] as const,
+ ([directory, id]) => {
if (refreshFrame !== undefined) cancelAnimationFrame(refreshFrame)
if (refreshTimer !== undefined) window.clearTimeout(refreshTimer)
refreshFrame = undefined
@@ -816,13 +818,10 @@ export default function Page() {
const stale = !cached
? false
: (() => {
- const info = getSessionPrefetch(sdk.directory, id)
+ const info = getSessionPrefetch(directory, id)
if (!info) return true
return Date.now() - info.at > SESSION_PREFETCH_TTL
})()
- untrack(() => {
- void sync.session.sync(id)
- })
refreshFrame = requestAnimationFrame(() => {
refreshFrame = undefined
@@ -834,7 +833,9 @@ export default function Page() {
})
}, 0)
})
- }),
+
+ return sync.session.sync(id)
+ },
)
createEffect(
@@ -1881,6 +1882,7 @@ export default function Page() {
return (