diff --git a/backend/common/src/searching.py b/backend/common/src/searching.py index 27b1e651..f613f003 100644 --- a/backend/common/src/searching.py +++ b/backend/common/src/searching.py @@ -231,18 +231,26 @@ class QueryBuilder: def _build_tag_query(tag): """build per-tag query clause""" if "?" in tag: - raise ValueError("unsupported wildcard for tag: only trailing * is supported") + raise ValueError( + "unsupported wildcard for tag: only trailing * is supported" + ) if "*" in tag: - if tag.count("*") != 1 or not tag.endswith("*") or tag.startswith("*"): + if ( + tag.count("*") != 1 + or not tag.endswith("*") + or tag.startswith("*") + ): raise ValueError( - "unsupported wildcard for tag: only trailing * is supported" + "unsupported wildcard for tag: " + "only trailing * is supported" ) prefix_value = tag[:-1] if not prefix_value: raise ValueError( - "unsupported wildcard for tag: only trailing * is supported" + "unsupported wildcard for tag: " + "only trailing * is supported" ) return {"prefix": {"tags.keyword": {"value": prefix_value}}} diff --git a/backend/common/tests/test_src/test_searching_dsl.py b/backend/common/tests/test_src/test_searching_dsl.py index 1e787a68..e8949776 100644 --- a/backend/common/tests/test_src/test_searching_dsl.py +++ b/backend/common/tests/test_src/test_searching_dsl.py @@ -1,7 +1,6 @@ """tests for search DSL parsing/building""" import pytest - from common.src.searching import SearchParser @@ -52,9 +51,7 @@ def test_tag_prefix_wildcard_builds_prefix_query(): def test_tag_invalid_wildcard_rejected(): """leading wildcard is not supported""" - with pytest.raises( - ValueError, match=r"only trailing \* is supported" - ): + with pytest.raises(ValueError, match=r"only trailing \* is supported"): SearchParser("tag:*music").run() diff --git a/backend/common/views.py b/backend/common/views.py index 8ab3e446..7dba162f 100644 --- a/backend/common/views.py +++ b/backend/common/views.py @@ -18,7 +18,11 @@ from common.src.searching import SearchForm from common.src.ta_redis import RedisArchivist from common.src.watched import WatchState from common.views_base import AdminOnly, ApiBaseView -from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema +from drf_spectacular.utils import ( + OpenApiParameter, + OpenApiResponse, + extend_schema, +) from rest_framework.response import Response from rest_framework.views import APIView from task.tasks import check_reindex diff --git a/frontend/src/pages/Search.tsx b/frontend/src/pages/Search.tsx index df5b5fab..edc9dfe1 100644 --- a/frontend/src/pages/Search.tsx +++ b/frontend/src/pages/Search.tsx @@ -25,18 +25,20 @@ const EmptySearchResponse: ApiResponseType = { status: 200, }; -const Search = () => { +type SearchInnerProps = { + queryParam: string | null; + videoId: string | null; +}; + +const SearchInner = ({ queryParam, videoId }: SearchInnerProps) => { const { userConfig } = useUserConfigStore(); - const [searchParams] = useSearchParams(); - const videoId = searchParams.get('videoId'); - const queryParam = searchParams.get('query'); const viewVideos = userConfig.view_style_home; const viewChannels = userConfig.view_style_channel; const viewPlaylists = userConfig.view_style_playlist; const gridItems = userConfig.grid_items || 3; - const [searchTerm, setSearchTerm] = useState(''); + const [searchTerm, setSearchTerm] = useState(() => queryParam ?? ''); const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(''); const [searchResults, setSearchResults] = useState>(); @@ -73,12 +75,6 @@ const Search = () => { setRefresh(false); }; - useEffect(() => { - if (queryParam !== null) { - setSearchTerm(queryParam); - } - }, [queryParam]); - useEffect(() => { const handler = setTimeout(() => { setDebouncedSearchTerm(searchTerm); @@ -177,4 +173,14 @@ const Search = () => { ); }; +const Search = () => { + const [searchParams] = useSearchParams(); + const videoId = searchParams.get('videoId'); + const queryParam = searchParams.get('query'); + + return ( + + ); +}; + export default Search;