Directory: Podcasts and Blogs as a filter, beside the category chips

What a feed is and what it is about are two questions, so they are two
controls that combine: the same .tabs the item filters use for All,
Podcasts and Blogs, and a row of category chips that is always there,
offering only the categories among the feeds the filter lets through. A
picked chip lifts on a second press, so there is no second All.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 16:30:59 +00:00
parent 017cfd7e28
commit cbd16ce3f6
4 changed files with 54 additions and 41 deletions

View File

@@ -697,7 +697,7 @@ test('Popular lists what everyone here reads, but never a private feed', async (
// Subscribe from the directory this time: the same feeds, as a grid of cover art.
const tiles = piper.locator('#popular .tile');
const chip = name => piper.locator('#chips button', { hasText: new RegExp(`^${name}$`) });
const pick = (row, name) => piper.locator(`#dirbar .${row} button`, { hasText: new RegExp(`^${name}$`) });
await piper.locator('#feedlist .place', { hasText: 'Directory' }).click();
await expect(piper.locator('#count')).toContainText(`Directory: ${dir.length} feed`);
await expect(tiles.filter({ hasText: 'Test Show' })).toBeVisible();
@@ -706,18 +706,22 @@ test('Popular lists what everyone here reads, but never a private feed', async (
await expect(tiles.filter({ hasText: /Paid Show|paid-show/ })).toHaveCount(0);
await expect(tiles).toHaveCount(dir.length);
// What a feed is before what it is about: a podcast's categories open under Podcasts.
// Two filters that combine: what a feed is, and what it is about.
expect(dir.find(p => p.id === 'test-show')).toMatchObject({ podcast: true, category: 'Technology' });
expect(dir.find(p => p.id === 'picture-blog')).toMatchObject({ podcast: false });
await expect(chip('Technology')).toHaveCount(0);
await chip('Blogs').click();
await pick('tabs', 'Blogs').click();
await expect(tiles).toHaveCount(dir.filter(p => !p.podcast).length);
await expect(tiles.filter({ hasText: 'Test Show' })).toHaveCount(0);
await chip('Podcasts').click();
await chip('Technology').click();
await expect(chip('Technology')).toHaveAttribute('aria-pressed', 'true');
// No empty chips: no blog here names Technology, so Blogs does not offer it.
await expect(pick('chips', 'Technology')).toHaveCount(0);
await pick('tabs', 'Podcasts').click();
await pick('chips', 'Technology').click();
await expect(pick('chips', 'Technology')).toHaveAttribute('aria-pressed', 'true');
await expect(tiles).toHaveCount(dir.filter(p => p.podcast && p.category === 'Technology').length);
await chip('All').click();
// A second press lifts the chip and leaves the kind as it was.
await pick('chips', 'Technology').click();
await expect(tiles).toHaveCount(dir.filter(p => p.podcast).length);
await pick('tabs', 'All').click();
await expect(tiles).toHaveCount(dir.length);
// Add a feed opened over Directory fills its own list, not the pane behind it.