From 08937c3b8bde7322ffdf4e4aa23ba1a59ff239f0 Mon Sep 17 00:00:00 2001 From: Junwei Zhao Date: Mon, 23 Feb 2026 17:29:29 +1100 Subject: [PATCH] feat: show cached badge in search stats when results from cache - Add 'cached' boolean field to SearchResponse model - Set cached=True when returning Redis-cached results - Display green 'cached' pill with database icon in stats header Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- backend/app/models.py | 1 + backend/app/search.py | 7 ++++--- backend/data/hey_search.db | Bin 12288 -> 20480 bytes frontend/src/App.tsx | 2 ++ frontend/src/components/SearchStats.tsx | 11 +++++++++-- frontend/src/lib/api.ts | 1 + 6 files changed, 17 insertions(+), 5 deletions(-) diff --git a/backend/app/models.py b/backend/app/models.py index 04b8c51..e5090c1 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -61,6 +61,7 @@ class SearchResponse(BaseModel): timestamp: str = Field(default_factory=lambda: datetime.now(timezone.utc).isoformat()) total_results: int = 0 has_next: bool = True + cached: bool = False class EngineInfo(BaseModel): diff --git a/backend/app/search.py b/backend/app/search.py index 1158028..89351ed 100644 --- a/backend/app/search.py +++ b/backend/app/search.py @@ -65,9 +65,10 @@ async def search( engines_key = ",".join(sorted(engines)) if engines else "" # Check cache first - cached = await cache.get_cached(query, category, page, image_size, engines_key) - if cached is not None: - resp = SearchResponse(**cached) + cached_data = await cache.get_cached(query, category, page, image_size, engines_key) + if cached_data is not None: + resp = SearchResponse(**cached_data) + resp.cached = True return resp enabled_engines = registry.get_enabled_engines() diff --git a/backend/data/hey_search.db b/backend/data/hey_search.db index 67769ad9d278450cafac9e23b70c3296b23ba7fe..2fcdcb644864e195514c8964a3e509c36c1e34bc 100644 GIT binary patch delta 276 zcmZojXjs5FL0XWRfq{V)h+%+fqK>gBGlO1L0Wbd#1{OXK2EKp%+xa~B&TcHc!t2?{ z#LO-(E6dmzUXqxUlUkfwQj(dMUJRpIoP%5)LtGU?9G!ez6=0$Y8e9rUAUm~EL1A(N zzr1o;VoqtQLWpZbh=QL#5QqBsz*TDMv#^Of%TC_QFCh#wDBcjpV%_|Yk4ce>7wBw8 z{?`oruQv-ST;ZP>z$-7z$gItuoS2-E8edY96Q7Y^T2ySt1y=W#f&VR39lx*;vo

delta 56 zcmZozz}S#5L0XWBfq{V;h+%+nqK+|8P_L?hm;VO?6W>1uzJL7NHwy~%@ooOc$D{}V D9G?s& diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 4828bfa..aee7016 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -300,6 +300,7 @@ function App() { errors={response.errors} page={page} totalResults={response.results.length} + cached={response.cached} initialCollapsed /> @@ -347,6 +348,7 @@ function App() { errors={response.errors} page={page} totalResults={response.results.length} + cached={response.cached} /> diff --git a/frontend/src/components/SearchStats.tsx b/frontend/src/components/SearchStats.tsx index b764061..fedea2f 100644 --- a/frontend/src/components/SearchStats.tsx +++ b/frontend/src/components/SearchStats.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { BarChart3, ChevronDown, ChevronUp, AlertCircle, CheckCircle2, Clock } from "lucide-react"; +import { BarChart3, ChevronDown, ChevronUp, AlertCircle, CheckCircle2, Clock, Database } from "lucide-react"; import type { EngineStat, EngineError } from "@/lib/api"; import { cn } from "@/lib/utils"; @@ -8,10 +8,11 @@ interface SearchStatsProps { errors: EngineError[]; page: number; totalResults: number; + cached?: boolean; initialCollapsed?: boolean; } -export function SearchStats({ stats, page, totalResults, initialCollapsed = false }: SearchStatsProps) { +export function SearchStats({ stats, page, totalResults, cached = false, initialCollapsed = false }: SearchStatsProps) { const [collapsed, setCollapsed] = useState(initialCollapsed); if (stats.length === 0) return null; @@ -32,6 +33,12 @@ export function SearchStats({ stats, page, totalResults, initialCollapsed = fals Search Stats + {cached && ( + + + )} {totalResults} result{totalResults !== 1 && "s"} ยท page {page} diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 04d6e92..5161d80 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -48,6 +48,7 @@ export interface SearchResponse { timestamp: string; total_results: number; has_next: boolean; + cached: boolean; } export interface EngineInfo {