From 0a99b7b2533c28c10ee97ec3c4ae6d18bff079ed Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Sun, 15 Feb 2026 13:48:45 -0800 Subject: Frontend: Fix additive filtering logic and preserve search query during navigation (NK-r8rs7m) --- frontend/src/components/FeedList.tsx | 46 ++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 12 deletions(-) (limited to 'frontend/src/components') diff --git a/frontend/src/components/FeedList.tsx b/frontend/src/components/FeedList.tsx index 1ab5246..4e6738e 100644 --- a/frontend/src/components/FeedList.tsx +++ b/frontend/src/components/FeedList.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Link, useNavigate, useSearchParams, useLocation, useParams } from 'react-router-dom'; +import { Link, useNavigate, useSearchParams, useLocation, useMatch } from 'react-router-dom'; import type { Feed, Category } from '../types'; import './FeedList.css'; import './FeedListVariants.css'; @@ -26,7 +26,13 @@ export default function FeedList({ const navigate = useNavigate(); const [searchParams] = useSearchParams(); const location = useLocation(); - const { feedId, tagName } = useParams(); + const feedMatch = useMatch('/feed/:feedId'); + const tagMatch = useMatch('/tag/:tagName'); + const isRoot = useMatch('/'); + const isStreamPage = !!(isRoot || feedMatch || tagMatch); + + const feedId = feedMatch?.params.feedId; + const tagName = tagMatch?.params.tagName; const sidebarVariant = searchParams.get('sidebar') || localStorage.getItem('neko-sidebar-variant') || 'glass'; @@ -37,15 +43,31 @@ export default function FeedList({ } }, [searchParams]); - const currentFilter = - searchParams.get('filter') || - (location.pathname === '/' && !feedId && !tagName ? 'unread' : ''); + const currentFilter = searchParams.get('filter') || (isStreamPage ? 'unread' : ''); + + const getFilterLink = (filter: string) => { + const baseStreamPath = isStreamPage ? location.pathname : '/'; + const params = new URLSearchParams(searchParams); + params.set('filter', filter); + return `${baseStreamPath}?${params.toString()}`; + }; + + const getNavPath = (path: string) => { + const params = new URLSearchParams(searchParams); + if (!params.has('filter') && currentFilter) { + params.set('filter', currentFilter); + } + const qs = params.toString(); + return `${path}${qs ? '?' + qs : ''}`; + }; const handleSearch = (e: React.FormEvent) => { e.preventDefault(); if (searchQuery.trim()) { - const filterPart = currentFilter ? `&filter=${currentFilter}` : ''; - navigate(`/?q=${encodeURIComponent(searchQuery.trim())}${filterPart}`); + const params = new URLSearchParams(searchParams); + params.set('q', searchQuery.trim()); + if (currentFilter) params.set('filter', currentFilter); + navigate(`/?${params.toString()}`); } }; @@ -114,7 +136,7 @@ export default function FeedList({