Keyboard shortcuts, after Feedly's

j/n and k/p step through the items, Shift-J and Shift-K through the feed
list, and g with a letter goes to a place: All Subscriptions, Directory,
Popular, Currently Listening, Settings. o plays the selected item, m marks
it read or unread and s keeps it, each by pressing the toolbar's own
button; v opens the original, Shift-A marks all read, r refreshes, [ hides
the feed list, and ? lists them all. None fire while typing, with a
modifier held, or with a dialog open.

Closes #8.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 17:08:54 +00:00
parent 4314b11237
commit 420f9eb9a0
4 changed files with 111 additions and 0 deletions

View File

@@ -91,6 +91,7 @@ const drive = [
['selectFeed (currently listening)', () => ctx.selectFeed(':listening')],
['selectFeed (all subscriptions)', () => ctx.selectFeed(':all')],
['logsModal', () => ctx.logsModal()],
['keysModal', () => ctx.keysModal()],
// `const S` is not reachable from here: top-level const/let do not become properties
// of a vm context the way var and function declarations do.
['renderGroup', () => ctx.renderGroup(feed, [{ ...feed, id: 'child', group: 'f', orphaned: true }])],

View File

@@ -918,3 +918,35 @@ test('someone the proxy signs in never sees the password page, and signs out thr
await expect(proxied).toHaveURL(/\/signed-out-by-the-proxy$/);
await ctx.close();
});
test('keys move through items and places, after Feedly', async ({ page }) => {
// Last in the file: selecting an item marks it read, which would change what later tests see.
await page.locator('.feed', { hasText: 'Test Show' }).click();
const rows = page.locator('#eps .ep');
await expect(rows.nth(1)).toBeVisible({ timeout: 20_000 });
const sel = page.locator('#eps .ep.sel');
const guid = i => rows.nth(i).getAttribute('data-guid');
await page.keyboard.press('j');
await expect(sel).toHaveAttribute('data-guid', await guid(0));
await page.keyboard.press('j');
await expect(sel).toHaveAttribute('data-guid', await guid(1));
await page.keyboard.press('k');
await expect(sel).toHaveAttribute('data-guid', await guid(0));
// g and a letter go somewhere; typed into a box, the same letters are only text.
await page.keyboard.press('g');
await page.keyboard.press('d');
await expect(page.locator('#count')).toContainText('Directory');
await page.locator('#epSearch').focus();
await page.keyboard.type('ga');
await expect(page.locator('#count')).toContainText('Directory');
await page.locator('#epSearch').fill('');
await page.locator('#epSearch').blur();
await page.keyboard.press('?');
await expect(page.locator('#modalCard')).toContainText('Keyboard shortcuts');
await page.keyboard.press('Escape');
await page.keyboard.press('g');
await page.keyboard.press('a');
await expect(page.locator('#count')).toContainText('All Subscriptions');
});