From fa9c94f7ad0923125077fba2967ca551fdf29498 Mon Sep 17 00:00:00 2001 From: ashim-hq Date: Sat, 18 Apr 2026 11:34:22 +0800 Subject: [PATCH] fix: subscribe to bundles array reactively in ToolCard for download badge The previous selector returned the isToolInstalled function reference which never changes, so the component didn't re-render when bundles loaded. Now subscribes to the bundles array directly via useMemo. --- apps/web/src/components/common/tool-card.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/web/src/components/common/tool-card.tsx b/apps/web/src/components/common/tool-card.tsx index 32a817ab..8714fab2 100644 --- a/apps/web/src/components/common/tool-card.tsx +++ b/apps/web/src/components/common/tool-card.tsx @@ -1,6 +1,7 @@ import type { Tool } from "@ashim/shared"; -import { PYTHON_SIDECAR_TOOLS } from "@ashim/shared"; +import { PYTHON_SIDECAR_TOOLS, TOOL_BUNDLE_MAP } from "@ashim/shared"; import { Download, FileImage, Star } from "lucide-react"; +import { useMemo } from "react"; import { Link } from "react-router-dom"; import { ICON_MAP } from "@/lib/icon-map"; import { cn } from "@/lib/utils"; @@ -15,7 +16,14 @@ export function ToolCard({ tool }: ToolCardProps) { (ICON_MAP[tool.icon] as React.ComponentType<{ className?: string }>) ?? FileImage; const isAiTool = (PYTHON_SIDECAR_TOOLS as readonly string[]).includes(tool.id); - const isInstalled = useFeaturesStore((s) => s.isToolInstalled)(tool.id); + const bundles = useFeaturesStore((s) => s.bundles); + const isInstalled = useMemo(() => { + if (!isAiTool) return true; + const bundleId = TOOL_BUNDLE_MAP[tool.id]; + if (!bundleId) return true; + const bundle = bundles.find((b) => b.id === bundleId); + return bundle?.status === "installed"; + }, [isAiTool, tool.id, bundles]); const showDownloadBadge = isAiTool && !isInstalled; return (