From 5dbfb2a0116ac8c1a3bca89677375744a61568f4 Mon Sep 17 00:00:00 2001 From: cc Date: Mon, 18 May 2026 18:19:04 +0200 Subject: [PATCH] Fix platform filter toggle behavior --- src/components/oslist.tsx | 93 +++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 42 deletions(-) diff --git a/src/components/oslist.tsx b/src/components/oslist.tsx index 1df9261..9802d7c 100644 --- a/src/components/oslist.tsx +++ b/src/components/oslist.tsx @@ -1,16 +1,15 @@ "use client"; -import Link from "next/link"; -import { useEffect, useState, useMemo } from "react"; -import { useSearchParams } from "next/navigation"; import { Search, X } from "lucide-react"; +import Link from "next/link"; +import { useSearchParams } from "next/navigation"; +import { useEffect, useMemo, useState } from "react"; -import { Group, OS } from "@/lib/types"; import { dataURL } from "@/lib/env"; -import { Skeleton } from "./ui/skeleton"; -import { Input } from "./ui/input"; -import { Button } from "./ui/button"; +import type { Group, OS } from "@/lib/types"; import { HeaderPortal } from "./header-portal"; +import { Button } from "./ui/button"; +import { Input } from "./ui/input"; function responseOK(r: Response) { if (!r.ok) { @@ -74,7 +73,7 @@ export default function OSList() { const [loading, setLoading] = useState(true); const [groups, setGroups] = useState([]); const [highlights, setHighlights] = useState>(new Set()); - const [selectedPlatforms, setSelectedPlatforms] = useState>(new Set()); + const [selectedPlatform, setSelectedPlatform] = useState(null); const [keyword, setKeyword] = useState(""); const [debouncedKeyword, setDebouncedKeyword] = useState(""); @@ -91,10 +90,12 @@ export default function OSList() { group.list.sort((a, b) => compareVersion(b.version, a.version)); if (group.name === "osx") { - group.list.forEach((item) => set.add(item.build)); + for (const item of group.list) { + set.add(item.build); + } } else { const bucket: Map = new Map(); - group.list.forEach((item) => { + for (const item of group.list) { const [major] = item.version.split(".", 1); const key = major.toString(); if (!bucket.has(key)) { @@ -102,7 +103,7 @@ export default function OSList() { } else { bucket.get(key)!.push(item); } - }); + } const isIOSOrMac = group.name === "iOS" || group.name === "mac"; let latestTwoMajors = new Set(); if (isIOSOrMac) { @@ -114,16 +115,20 @@ export default function OSList() { latestTwoMajors = new Set(sortedMajors); } - bucket.forEach((items, major) => { + for (const [major, items] of bucket) { items.sort((a, b) => compareVersion(b.version, a.version)); if (isIOSOrMac && latestTwoMajors.has(major)) { - items.forEach((item) => set.add(item.build)); + for (const item of items) { + set.add(item.build); + } } else { const [first] = items; - set.add(first?.build); + if (first) { + set.add(first.build); + } } - }); + } } } setHighlights(set); @@ -138,9 +143,9 @@ export default function OSList() { .then(async (groupList: string[]) => Promise.all( groupList.map(async (group) => { - const response = await fetch( - `${dataURL}/${group}/list.json`, - ).then(responseOK); + const response = await fetch(`${dataURL}/${group}/list.json`).then( + responseOK, + ); const data = await response.json(); @@ -153,41 +158,30 @@ export default function OSList() { ) .then((groups) => { setGroups(groups); - // Enable all platforms by default - setSelectedPlatforms(new Set(groups.map((g) => g.name))); }) .finally(() => setLoading(false)); }, []); const togglePlatform = (name: string) => { - setSelectedPlatforms((prev) => { - const next = new Set(prev); - if (next.has(name)) { - // Don't allow deselecting all - if (next.size > 1) next.delete(name); - } else { - next.add(name); - } - return next; - }); + setSelectedPlatform((prev) => (prev === name ? null : name)); }; const filteredGroups = useMemo(() => { const kw = debouncedKeyword.toLowerCase(); return groups - .filter((g) => selectedPlatforms.has(g.name)) + .filter((g) => selectedPlatform === null || g.name === selectedPlatform) .map((g) => { if (!kw) return g; // Filter OS entries by product name or version const filteredList = g.list.filter( (os) => os.name.toLowerCase().includes(kw) || - os.version.toLowerCase().includes(kw) + os.version.toLowerCase().includes(kw), ); return { ...g, list: filteredList }; }) .filter((g) => g.list.length > 0); - }, [groups, selectedPlatforms, debouncedKeyword]); + }, [groups, selectedPlatform, debouncedKeyword]); const totalCount = useMemo(() => { return groups.reduce((sum, g) => sum + g.list.length, 0); @@ -197,7 +191,7 @@ export default function OSList() { return filteredGroups.reduce((sum, g) => sum + g.list.length, 0); }, [filteredGroups]); - const isFiltering = debouncedKeyword.length > 0; + const isFiltering = debouncedKeyword.length > 0 || selectedPlatform !== null; return (
@@ -208,7 +202,10 @@ export default function OSList() {
{[1, 2, 3, 4, 5, 6].map((item) => ( -
+
@@ -235,10 +232,12 @@ export default function OSList() {
{groups.map((group) => (