fix: (regression beta) get-list button not working

Massimo Melina committed Apr 19, 2025 at 11:05 UTC 37ace6cb9af7449751eee02bdc33519b34efbb24
3 files changed +17 -9
e2e/frontend.spec.ts
+10
@@ -48,11 +48,21 @@ test('around1', async ({ page }) => {
48 await page.getByRole('link', { name: 'alfa.txt', exact: true }).click();
49 await screenshot(page);
50 await page.getByRole('button', { name: 'Close' }).click();
51 +
52 await page.getByRole('link', { name: 'cantListPage' }).click();
53 await page.getByRole('button', { name: 'Calculate' }).click();
54 await page.getByText('KB / 2 files').click();
55 await page.locator('#menu-prop-name').getByText('cantListPage').click();
56 + const downloadPromise = page.waitForEvent('download');
57 await page.getByRole('link', { name: 'Download' }).click();
58 + await downloadPromise;
59 + await page.getByRole('link', { name: 'cantListPage' }).click();
60 + const pageListPromise = page.waitForEvent('popup');
61 + await page.getByRole('link', { name: 'Get list' }).click();
62 + const pageList = await pageListPromise;
63 + await expect(pageList.getByText('localhost')).toBeVisible();
64 + await pageList.close()
65 +
66 await page.getByRole('link', { name: 'home' }).click();
67 await page.getByRole('button', { name: 'Select' }).click();
68 await page.getByRole('textbox', { name: 'Type here to filter the list' }).click();
frontend/src/fileMenu.ts
+2 -2
@@ -36,7 +36,7 @@ export async function openFileMenu(entry: DirEntry, ev: MouseEvent, addToMenu: (
36 const forbidden = entry.cantOpen === DirEntry.FORBIDDEN
37 const cantDownload = forbidden || isFolder && !(canRead && entry.canArchive() && canList) // folders needs list+read+archive
38 const menu = [
39 - !cantDownload && { id: 'download', label: t`Download`, href: uri + (isFolder ? '?get=zip' : '?dl'), icon: 'download' },
39 + !cantDownload && { id: 'download', label: t`Download`, href: uri + (isFolder ? '?get=zip' : '?dl'), icon: 'download', target: '_blank' },
40 state.props?.can_comment && { id: 'comment', label: t`Comment`, icon: 'comment', onClick: () => editComment(entry) },
41 ...addToMenu.map(x => {
42 if (x === 'open') {
@@ -69,7 +69,7 @@ export async function openFileMenu(entry: DirEntry, ev: MouseEvent, addToMenu: (
69 }),
70 entry.canDelete() && { id: 'rename', label: t`Rename`, icon: 'edit', onClick: () => rename(entry) },
71 entry.canDelete() && { id: 'cut', label: t`Cut`, icon: 'cut', onClick: () => close(cut([entry])) },
72 - isFolder && !entry.web && !entry.cantOpen && { id: 'list', label: t`Get list`, href: uri + '?get=list&folders=*', icon: 'list' },
72 + isFolder && !entry.web && !entry.cantOpen && { id: 'list', label: t`Get list`, href: uri + '?get=list&folders=*', icon: 'list', target: '_blank' },
73 ].filter(Boolean)
74 const folder = entry.n.slice(0, -1 - entry.name.length)
75 const props = [
shared/dialogs.ts
+5 -7
@@ -77,13 +77,11 @@ let waitClosing = Promise.resolve()
77 let ignorePopState = false
78 async function back() {
79 ignorePopState = true
80 - const was = history.state
81 - return waitClosing = waitClosing.then(() => new Promise<void>(async res => {
82 - await wait(10) // this is necessary for safari in case we close a dialog while it is processing a change of url (after clicking a file to download). This could be avoided by adding a target=_blank on the link, but we want to be agnostic about it. In my tests, 2ms is the minimum necessary, but 10 is safer.
83 - history.back()
84 - // wait for history.back to change history.state, up to 500ms. Events popstate and pageshow have no consistent behavior, so polling is necessary.
85 - const t = setInterval(() => was !== history.state && res(), 10)
86 - setTimeout(() => clearTimeout(t), 500)
80 + let was = history.state
81 + history.back()
82 + return waitClosing = waitClosing.then(() => new Promise<void>(res => {
83 + const h = setInterval(() => was !== history.state && res() , 10)
84 + setTimeout(() => clearTimeout(h), 500)
85 }))
86 }
87