Skip to content

Simplify reader filter context - #19

Merged
maniczko merged 1 commit into
mainfrom
codex/issue-7-reader-filter-model-simplification
May 25, 2026
Merged

Simplify reader filter context#19
maniczko merged 1 commit into
mainfrom
codex/issue-7-reader-filter-model-simplification

Conversation

@maniczko

Copy link
Copy Markdown
Owner

Summary

  • Adds one canonical reader context strip for queue, source scope, read scope, sort, and search.
  • Keeps existing controls and URL/API/state semantics intact, but visually separates active context from control widgets.
  • Adds removable chip affordances with aria-label/title, documents removal behavior, and fixes mobile queue controls to collapse to a readable 2x2 grid.

Evidence

  • npm run test:unit:web -- reader-browse-view passed.
  • npm run build passed.
  • npm run test:unit passed.
  • RSSMASTER_PLAYWRIGHT_MODULE=C:\Users\user\Desktop\RSSmaster\output\playwright-runtime\node_modules\playwright npm run check:reader passed.
  • RSSMASTER_PLAYWRIGHT_MODULE=C:\Users\user\Desktop\RSSmaster\output\playwright-runtime\node_modules\playwright npm run check:layout passed.

Screenshots

  • Desktop: output/playwright/page-audit-read-inbox-desktop-1180.png
  • Tablet: output/playwright/page-audit-read-inbox-tablet-1024.png
  • Mobile: output/playwright/page-audit-read-inbox-mobile-390.png

UX scorecard

  • Overall: 9/10 after mobile hard-stop fix.
  • Hard stops: none observed in final desktop/mobile screenshots.
  • Residual: manual screen-reader signoff is still pending; automated a11y/focus probes passed in layout/reader checks.

Closes #7

@maniczko
maniczko merged commit 18efc84 into main May 25, 2026
1 check passed

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new 'reader context panel' to the browse view, featuring interactive chips that display and allow clearing of active filters like queue mode, source, read status, sorting, and search. It also includes significant UI refinements to the toolbar, such as adding descriptive labels to control groups and badges for item counts, alongside corresponding CSS updates for both standard and premium layouts. Feedback focuses on optimizing performance by memoizing the context chips array to prevent unnecessary re-renders and addressing a misleading UI state where the same item count is displayed for different queue modes.

Comment on lines +5368 to +5436
const readerContextChips: ReaderBrowseContextChip[] = [
...(libraryView === "inbox"
? [
{
id: "queue",
label: "Kolejka",
value: readerQueueModeLabel,
tone: "accent" as const,
...(readerQueueMode !== "for_you"
? {
onRemove: () => navigateReaderQueueMode("for_you"),
removeLabel: "Wróć do kolejki Dla mnie",
}
: {}),
},
]
: [
{
id: "library-view",
label: "Widok",
value: getLibraryViewLabel(libraryView),
tone: "accent" as const,
},
]),
{
id: "source",
label: activeSourceContextLabel,
value: activeFeedScopeBaseLabel,
...(feedFilter.kind !== "all"
? {
onRemove: () => setReaderFeedFilter({ kind: "all" }),
removeLabel: `Usuń filtr ${activeSourceContextLabel.toLowerCase()}: ${activeFeedScopeBaseLabel}`,
}
: { tone: "muted" as const }),
},
{
id: "read-scope",
label: "Zakres",
value: readerScopeLabel,
...(!showReadItems
? {
onRemove: () => setReaderShowReadItems(true),
removeLabel: "Pokaż także przeczytane artykuły",
}
: { tone: "muted" as const }),
},
{
id: "sort",
label: "Sortowanie",
value: readerSortLabel,
...(itemSortMode !== "newest"
? {
onRemove: () => setReaderItemSortMode("newest"),
removeLabel: "Przywróć sortowanie od najnowszych",
}
: { tone: "muted" as const }),
},
...(readerSearchLabel
? [
{
id: "search",
label: "Szukaj",
value: readerSearchLabel,
onRemove: () => setReaderItemSearch(""),
removeLabel: `Wyczyść wyszukiwanie: ${readerSearchLabel}`,
},
]
: []),
];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The readerContextChips array is recreated on every render of the ChannelLab component, which is a very large component with frequent state updates. Since this array is passed as a prop to ReaderBrowseView, it will cause that component to re-render unnecessarily even if the underlying filter values haven't changed. Consider memoizing this array using useMemo and wrapping the onRemove callbacks in useCallback to improve performance.

Comment on lines +181 to +188
<span className="reader-control-badge">{items.length}</span>
</button>
<button className={readerQueueMode === "latest" ? "segment-active" : ""} onClick={() => onReaderQueueModeChange("latest")} type="button">
Najnowsze
</button>
<button className={readerQueueMode === "all" ? "segment-active" : ""} onClick={() => onReaderQueueModeChange("all")} type="button">
<span>Wszystkie</span>
<span className="reader-control-badge">{items.length}</span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The items.length count is used for both the 'Dla mnie' and 'Wszystkie' queue mode buttons. Since items represents the current filtered queue, both buttons will display the same count regardless of which one is active. This is misleading for users who expect to see the total count of items available in each mode. Consider passing separate counts for each queue mode from the parent component.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P1-UI-002] Reader filter model simplification

1 participant