remove counter of selected feed
This commit is contained in:
@@ -10,6 +10,24 @@ const { sync, showModal, viewMode, toggleViewMode, layout, toggleLayout, markAll
|
|||||||
|
|
||||||
const headerRef = ref(null)
|
const headerRef = ref(null)
|
||||||
|
|
||||||
|
// Native <select>/<option> has no "is open" state — the closed box just shows
|
||||||
|
// the selected option's text verbatim, so per-option unread counts can only be
|
||||||
|
// toggled based on focus, since the popup is only ever shown while focused.
|
||||||
|
// @focus ~ opening (shows counts); @change (picking an option closes the
|
||||||
|
// popup but keeps focus, so no blur fires) and @blur (focus left without
|
||||||
|
// picking) ~ closed (counts hidden, so the closed box just shows the name).
|
||||||
|
const filterOpen = ref(false)
|
||||||
|
|
||||||
|
function onFilterFocus() {
|
||||||
|
filterOpen.value = true
|
||||||
|
refreshUnreadDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFilterChange(event) {
|
||||||
|
setFeedFilter(event.target.value || null)
|
||||||
|
filterOpen.value = false
|
||||||
|
}
|
||||||
|
|
||||||
// Scroll-driven show/hide: the header slides out of view on scroll-down and
|
// Scroll-driven show/hide: the header slides out of view on scroll-down and
|
||||||
// back in on scroll-up. This is show/hide via `transform` (not the old
|
// back in on scroll-up. This is show/hide via `transform` (not the old
|
||||||
// resize behaviour) — the header is position:fixed, so translating it never
|
// resize behaviour) — the header is position:fixed, so translating it never
|
||||||
@@ -165,11 +183,12 @@ function handleToggleLayout() {
|
|||||||
class="app-nav__filter"
|
class="app-nav__filter"
|
||||||
:value="feedFilter ?? ''"
|
:value="feedFilter ?? ''"
|
||||||
aria-label="Filter by feed"
|
aria-label="Filter by feed"
|
||||||
@focus="refreshUnreadDisplay"
|
@focus="onFilterFocus"
|
||||||
@change="setFeedFilter($event.target.value || null)"
|
@change="onFilterChange"
|
||||||
|
@blur="filterOpen = false"
|
||||||
>
|
>
|
||||||
<option value="">All feeds</option>
|
<option value="">All feeds</option>
|
||||||
<option v-for="title in feedTitles" :key="title" :value="title">{{ title }} ({{ displayedFeedUnreadCounts[title] ?? 0 }})</option>
|
<option v-for="title in feedTitles" :key="title" :value="title">{{ title }}<template v-if="filterOpen"> ({{ displayedFeedUnreadCounts[title] ?? 0 }})</template></option>
|
||||||
</select>
|
</select>
|
||||||
<button
|
<button
|
||||||
class="app-nav__hamburger"
|
class="app-nav__hamburger"
|
||||||
|
|||||||
@@ -239,13 +239,36 @@ describe('AppNav', () => {
|
|||||||
|
|
||||||
const wrapper = mountNav()
|
const wrapper = mountNav()
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
|
const select = wrapper.find('.app-nav__filter')
|
||||||
|
|
||||||
const options = wrapper.find('.app-nav__filter').findAll('option').map(o => o.text())
|
// Counts only show while the dropdown is open (focused) — see AppNav.vue.
|
||||||
|
await select.trigger('focus')
|
||||||
|
|
||||||
|
const options = select.findAll('option').map(o => o.text())
|
||||||
// "All feeds" first, then distinct titles sorted alphabetically, each with
|
// "All feeds" first, then distinct titles sorted alphabetically, each with
|
||||||
// its unread count.
|
// its unread count.
|
||||||
expect(options).toEqual(['All feeds', 'Feed A (2)', 'Feed B (1)'])
|
expect(options).toEqual(['All feeds', 'Feed A (2)', 'Feed B (1)'])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('hides the per-option unread count once the feed filter is closed', async () => {
|
||||||
|
const { allItems } = useFeeds()
|
||||||
|
allItems.value = [
|
||||||
|
{ id: 1, feedTitle: 'Feed A', title: 'a', url: 'https://example.test/1', timestamp: '2026-01-01' },
|
||||||
|
{ id: 2, feedTitle: 'Feed A', title: 'b', url: 'https://example.test/2', timestamp: '2026-01-02' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const wrapper = mountNav()
|
||||||
|
await flushPromises()
|
||||||
|
const select = wrapper.find('.app-nav__filter')
|
||||||
|
|
||||||
|
await select.trigger('focus')
|
||||||
|
await select.setValue('Feed A') // fires change, which closes the popup but keeps focus
|
||||||
|
await flushPromises()
|
||||||
|
|
||||||
|
const feedAOption = select.findAll('option').find(o => o.element.value === 'Feed A')
|
||||||
|
expect(feedAOption.text()).toBe('Feed A')
|
||||||
|
})
|
||||||
|
|
||||||
it('does not render the feed filter when there are no feeds', async () => {
|
it('does not render the feed filter when there are no feeds', async () => {
|
||||||
const wrapper = mountNav()
|
const wrapper = mountNav()
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
|
|||||||
Reference in New Issue
Block a user