From a8a50dcc8958465cb858a2646c2443f55847a6d4 Mon Sep 17 00:00:00 2001 From: Jared Schoeny Date: Sat, 3 Oct 2026 19:10:58 -0600 Subject: [PATCH] Discover: let players hide hacks without an AI label, and show the November 2 deadline (#105) --- src/components/Discover/DiscoverFilters.tsx | 19 +++++-- src/components/Hack/HackDetailView.tsx | 18 +++++- src/utils/aiDisclosure.ts | 63 +++++++++++++-------- 3 files changed, 71 insertions(+), 29 deletions(-) diff --git a/src/components/Discover/DiscoverFilters.tsx b/src/components/Discover/DiscoverFilters.tsx index d25a302..b0bddae 100644 --- a/src/components/Discover/DiscoverFilters.tsx +++ b/src/components/Discover/DiscoverFilters.tsx @@ -9,7 +9,7 @@ import { baseGameLabel, baseRoms, PLATFORM_NAMES, type Platform } from "@/data/b const RAIL_PLATFORMS: Platform[] = ["GBA", "GBC", "GB", "NDS"]; import { DISCOVER_COMPLETION_STATUSES } from "@/app/discover/search-params"; import type { DiscoverHack } from "@/types/discover"; -import { AI_AREAS, AI_PRESETS, aiFilterActive, aiPresetOf, matchesAiFilter, normalizeAiFilter, NO_AI_FILTER, type AiArea, type AiFilter } from "@/utils/aiDisclosure"; +import { AI_AREAS, AI_DISCLOSURE_DEADLINE, AI_PRESETS, aiFilterActive, aiPresetOf, matchesAiFilter, normalizeAiFilter, NO_AI_FILTER, type AiArea, type AiFilter } from "@/utils/aiDisclosure"; import { useCloseOnDesktop, useDialog } from "@/hooks/useDialog"; /** The filterable part of the Discover URL state. The sheet edits a draft copy of this. */ @@ -124,7 +124,7 @@ export function FilterFields({ value, onChange, tagGroups, counts, readyCount, o // Ticking code yourself allows small use by default; only the presets are strict about it. // Ticking an area leaves Minor, since it's a limit across all areas rather than a pick of them. const toggleAiArea = (k: AiArea) => - setAi({ hide: toggleValue(value.ai.hide, k), smallCode: k === "code" ? !value.ai.hide.includes("code") : value.ai.smallCode, minor: false }); + setAi({ ...value.ai, hide: toggleValue(value.ai.hide, k), smallCode: k === "code" ? !value.ai.hide.includes("code") : value.ai.smallCode, minor: false }); const visibleGames = ROM_GAMES.map((g) => ({ ...g, dumps: g.dumps.filter((d) => !romQuery || g.label.toLowerCase().includes(romQuery) || d.label.toLowerCase().includes(romQuery)) })).filter((g) => g.dumps.length > 0); const visibleGroups = tagGroups @@ -228,9 +228,9 @@ export function FilterFields({ value, onChange, tagGroups, counts, readyCount, o className={rowH} label={p.label} hint={"hint" in p ? p.hint : undefined} - count={counts.ai(p.filter)} + count={counts.ai({ ...p.filter, disclosedOnly: value.ai.disclosedOnly })} checked={aiPreset === p.value} - onChange={() => setAi(p.filter)} + onChange={() => setAi({ ...p.filter, disclosedOnly: value.ai.disclosedOnly })} /> ))} {/* Shows while the areas match no preset; ticking back to a preset's areas selects it again. */} @@ -266,6 +266,14 @@ export function FilterFields({ value, onChange, tagGroups, counts, readyCount, o ))} + setAi({ ...value.ai, disclosedOnly: !value.ai.disclosedOnly })} + /> @@ -389,7 +397,8 @@ function Check({ label, hint, count, checked, onChange, className = "", ready =