diff --git a/backend/app/routes/search.py b/backend/app/routes/search.py index 139b6f7..d744714 100644 --- a/backend/app/routes/search.py +++ b/backend/app/routes/search.py @@ -253,8 +253,6 @@ def search_youtube( page = yt.search_videos(term, page_token=next_cursor) else: page = search_scrape.search(term, continuation=next_cursor) - # Zero-cost, but logged so the per-user daily cap above keeps counting it. - quota.log_action(db, user.id, quota.QuotaAction.VIDEOS_SEARCH) except (YouTubeError, search_scrape.ScrapeError) as exc: if collected: break # keep what we already gathered @@ -274,6 +272,14 @@ def search_youtube( if source == "api" or len(collected) >= limit or not next_cursor: break + # Count this as ONE per-user search against the daily cap. The scrape source spends no + # quota, so it never logs an event on its own; the API source already logged exactly one + # (via record_usage — it never auto-pages). Logging once here, after a search that produced + # at least one page (a total failure raises 502 above and never reaches this), keeps the cap + # counting user searches instead of internal continuation pages. + if source != "api": + quota.log_action(db, user.id, quota.QuotaAction.VIDEOS_SEARCH) + ordered = collected[:limit] if ordered: diff --git a/frontend/src/components/Feed.tsx b/frontend/src/components/Feed.tsx index 633df6d..37e0423 100644 --- a/frontend/src/components/Feed.tsx +++ b/frontend/src/components/Feed.tsx @@ -184,9 +184,18 @@ export default function Feed({ setOverrides({}); setSavedOverrides({}); }, [filters]); + // ...but NOT on infinite-scroll appends: fetchNextPage also bumps dataUpdatedAt while page 1's + // rows are unchanged, so clearing overrides there would make a just-hidden card flash back. + // Only a real refetch (page count doesn't grow) is authoritative. + const pagesLenRef = useRef(0); useEffect(() => { - setOverrides({}); - setSavedOverrides({}); + const len = query.data?.pages?.length ?? 0; + const appended = len > pagesLenRef.current; + pagesLenRef.current = len; + if (!appended) { + setOverrides({}); + setSavedOverrides({}); + } }, [query.dataUpdatedAt]); const countQuery = useQuery({