Merge branch 'dev' into sqlite2
commit
ac16068140
|
|
@ -3,9 +3,10 @@ import { test, expect } from "./fixtures"
|
|||
test("file tree can expand folders and open a file", async ({ page, gotoSession }) => {
|
||||
await gotoSession()
|
||||
|
||||
await page.getByRole("button", { name: "Toggle file tree" }).click()
|
||||
|
||||
const toggle = page.getByRole("button", { name: "Toggle file tree" })
|
||||
const treeTabs = page.locator('[data-component="tabs"][data-variant="pill"][data-scope="filetree"]')
|
||||
|
||||
if ((await toggle.getAttribute("aria-expanded")) !== "true") await toggle.click()
|
||||
await expect(treeTabs).toBeVisible()
|
||||
|
||||
await treeTabs.locator('[data-slot="tabs-trigger"]').nth(1).click()
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ test("titlebar back/forward navigates between sessions", async ({ page, slug, sd
|
|||
await expect(page).toHaveURL(new RegExp(`/${slug}/session/${two.id}(?:\\?|#|$)`))
|
||||
await expect(page.locator(promptSelector)).toBeVisible()
|
||||
|
||||
const back = page.getByRole("button", { name: "Go back" })
|
||||
const forward = page.getByRole("button", { name: "Go forward" })
|
||||
const back = page.getByRole("button", { name: "Back" })
|
||||
const forward = page.getByRole("button", { name: "Forward" })
|
||||
|
||||
await expect(back).toBeVisible()
|
||||
await expect(back).toBeEnabled()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {
|
|||
createMemo,
|
||||
For,
|
||||
Match,
|
||||
onCleanup,
|
||||
Show,
|
||||
splitProps,
|
||||
Switch,
|
||||
|
|
@ -123,7 +124,28 @@ export default function FileTree(props: {
|
|||
|
||||
createEffect(() => {
|
||||
const path = props.path
|
||||
untrack(() => void file.tree.list(path))
|
||||
const state = { cancelled: false, timer: undefined as number | undefined }
|
||||
|
||||
const load = (attempt: number) => {
|
||||
if (state.cancelled) return
|
||||
if (file.tree.state(path)?.loaded) return
|
||||
|
||||
void untrack(() => file.tree.list(path)).finally(() => {
|
||||
if (state.cancelled) return
|
||||
if (file.tree.state(path)?.loaded) return
|
||||
if (attempt >= 2) return
|
||||
|
||||
const wait = Math.min(2000, 250 * 2 ** attempt)
|
||||
state.timer = window.setTimeout(() => load(attempt + 1), wait)
|
||||
})
|
||||
}
|
||||
|
||||
load(0)
|
||||
|
||||
onCleanup(() => {
|
||||
state.cancelled = true
|
||||
if (state.timer !== undefined) clearTimeout(state.timer)
|
||||
})
|
||||
})
|
||||
|
||||
const nodes = createMemo(() => {
|
||||
|
|
|
|||
|
|
@ -1256,7 +1256,33 @@ export default function Page() {
|
|||
if (!wants) return
|
||||
if (sync.data.session_diff[id] !== undefined) return
|
||||
|
||||
sync.session.diff(id)
|
||||
const state = {
|
||||
cancelled: false,
|
||||
attempt: 0,
|
||||
timer: undefined as number | undefined,
|
||||
}
|
||||
|
||||
const load = () => {
|
||||
if (state.cancelled) return
|
||||
const pending = sync.session.diff(id)
|
||||
if (!pending) return
|
||||
pending.catch(() => {
|
||||
if (state.cancelled) return
|
||||
const attempt = state.attempt + 1
|
||||
state.attempt = attempt
|
||||
if (attempt > 5) return
|
||||
if (state.timer !== undefined) clearTimeout(state.timer)
|
||||
const wait = Math.min(10000, 250 * 2 ** (attempt - 1))
|
||||
state.timer = window.setTimeout(load, wait)
|
||||
})
|
||||
}
|
||||
|
||||
load()
|
||||
|
||||
onCleanup(() => {
|
||||
state.cancelled = true
|
||||
if (state.timer !== undefined) clearTimeout(state.timer)
|
||||
})
|
||||
})
|
||||
|
||||
const autoScroll = createAutoScroll({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[data-component="spinner"] {
|
||||
color: var(--text-base);
|
||||
color: inherit;
|
||||
flex-shrink: 0;
|
||||
width: 18px;
|
||||
aspect-ratio: 1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue