Spaces:
Running
Running
import React, { | |
createContext, | |
useContext, | |
useState, | |
useCallback, | |
useMemo, | |
} from "react"; | |
const LeaderboardContext = createContext(); | |
export const LeaderboardProvider = ({ children }) => { | |
const [leaderboards, setLeaderboards] = useState([]); | |
const [searchQuery, setSearchQuery] = useState(""); | |
const [arenaOnly, setArenaOnly] = useState(false); | |
// Calculate total number of unique leaderboards (excluding duplicates) | |
const totalLeaderboards = useMemo(() => { | |
const uniqueIds = new Set(leaderboards.map((board) => board.id)); | |
return uniqueIds.size; | |
}, [leaderboards]); | |
// Filter functions for categories | |
const filterByTag = useCallback((tag, boards) => { | |
return ( | |
boards?.filter( | |
(board) => | |
board.tags?.includes(tag) || board.consolidated_tags?.includes(tag) | |
) || [] | |
); | |
}, []); | |
const filterByLanguage = useCallback((boards) => { | |
return ( | |
boards?.filter( | |
(board) => | |
board.tags?.some((tag) => tag.startsWith("language:")) || | |
board.consolidated_tags?.some((tag) => tag.startsWith("language:")) | |
) || [] | |
); | |
}, []); | |
const filterByVision = useCallback((boards) => { | |
return ( | |
boards?.filter( | |
(board) => | |
board.tags?.some( | |
(tag) => tag === "modality:video" || tag === "modality:image" | |
) || | |
board.consolidated_tags?.some( | |
(tag) => tag === "modality:video" || tag === "modality:image" | |
) | |
) || [] | |
); | |
}, []); | |
const filterUncategorized = useCallback((boards) => { | |
const categorizedTags = [ | |
"eval:code", | |
"eval:math", | |
"modality:video", | |
"modality:image", | |
"modality:audio", | |
"modality:tools", | |
"domain:financial", | |
"domain:medical", | |
"domain:legal", | |
]; | |
return ( | |
boards?.filter((board) => { | |
if ( | |
(!board.tags || board.tags.length === 0) && | |
(!board.consolidated_tags || board.consolidated_tags.length === 0) | |
) { | |
return true; | |
} | |
const hasNoTagsInCategory = !board.tags?.some( | |
(tag) => categorizedTags.includes(tag) || tag.startsWith("language:") | |
); | |
const hasNoConsolidatedTagsInCategory = !board.consolidated_tags?.some( | |
(tag) => categorizedTags.includes(tag) || tag.startsWith("language:") | |
); | |
return hasNoTagsInCategory && hasNoConsolidatedTagsInCategory; | |
}) || [] | |
); | |
}, []); | |
// Define sections | |
const allSections = useMemo(() => { | |
if (!leaderboards) return []; | |
return [ | |
{ | |
id: "code", | |
title: "Code", | |
data: filterByTag("eval:code", leaderboards), | |
}, | |
{ | |
id: "math", | |
title: "Math", | |
data: filterByTag("eval:math", leaderboards), | |
}, | |
{ | |
id: "language", | |
title: "Language Specific", | |
data: filterByLanguage(leaderboards), | |
}, | |
{ id: "vision", title: "Vision", data: filterByVision(leaderboards) }, | |
{ | |
id: "audio", | |
title: "Audio", | |
data: filterByTag("modality:audio", leaderboards), | |
}, | |
{ | |
id: "agentic", | |
title: "Agentic", | |
data: filterByTag("modality:tools", leaderboards), | |
}, | |
{ | |
id: "financial", | |
title: "Financial", | |
data: filterByTag("domain:financial", leaderboards), | |
}, | |
{ | |
id: "medical", | |
title: "Medical", | |
data: filterByTag("domain:medical", leaderboards), | |
}, | |
{ | |
id: "legal", | |
title: "Legal", | |
data: filterByTag("domain:legal", leaderboards), | |
}, | |
{ | |
id: "uncategorized", | |
title: "Uncategorized", | |
data: filterUncategorized(leaderboards), | |
}, | |
]; | |
}, [ | |
leaderboards, | |
filterByTag, | |
filterByLanguage, | |
filterByVision, | |
filterUncategorized, | |
]); | |
// Get sections with data | |
const sections = useMemo(() => { | |
return allSections.filter((section) => section.data.length > 0); | |
}, [allSections]); | |
// Filter leaderboards based on search query and arena toggle | |
const filterLeaderboards = useCallback( | |
(boards) => { | |
if (!boards) return []; | |
let filtered = [...boards]; | |
// Filter by search query | |
if (searchQuery) { | |
const query = searchQuery.toLowerCase(); | |
const searchableTagPrefixes = [ | |
"domain:", | |
"language:", | |
"judge:", | |
"test:", | |
"modality:", | |
"submission:", | |
]; | |
filtered = filtered.filter((board) => { | |
const isTagSearch = searchableTagPrefixes.some((prefix) => | |
query.startsWith(prefix) | |
); | |
if (isTagSearch) { | |
return ( | |
board.tags?.some((tag) => tag.toLowerCase().includes(query)) || | |
board.consolidated_tags?.some((tag) => | |
tag.toLowerCase().includes(query) | |
) | |
); | |
} | |
return board.card_data?.title?.toLowerCase().includes(query); | |
}); | |
} | |
// Filter arena only | |
if (arenaOnly) { | |
filtered = filtered.filter( | |
(board) => | |
board.tags?.includes("judge:humans") || | |
board.consolidated_tags?.includes("judge:humans") | |
); | |
} | |
return filtered; | |
}, | |
[searchQuery, arenaOnly] | |
); | |
// Get filtered count | |
const filteredCount = useMemo(() => { | |
return filterLeaderboards(leaderboards).length; | |
}, [filterLeaderboards, leaderboards]); | |
// Function to get highlighted parts of text | |
const getHighlightedText = useCallback((text, searchTerm) => { | |
if (!searchTerm || !text) return { text, shouldHighlight: false }; | |
const query = searchTerm.toLowerCase(); | |
const searchableTagPrefixes = [ | |
"domain:", | |
"language:", | |
"judge:", | |
"test:", | |
"modality:", | |
"submission:", | |
]; | |
// Si c'est une recherche par tag, on ne highlight rien | |
if (searchableTagPrefixes.some((prefix) => query.startsWith(prefix))) { | |
return { text, shouldHighlight: false }; | |
} | |
// Sinon on highlight les parties qui matchent | |
const index = text.toLowerCase().indexOf(query); | |
if (index === -1) return { text, shouldHighlight: false }; | |
return { | |
text, | |
shouldHighlight: true, | |
highlightStart: index, | |
highlightEnd: index + query.length, | |
}; | |
}, []); | |
const value = { | |
leaderboards, | |
setLeaderboards, | |
searchQuery, | |
setSearchQuery, | |
arenaOnly, | |
setArenaOnly, | |
totalLeaderboards, | |
filteredCount, | |
filterLeaderboards, | |
sections, | |
allSections, | |
getHighlightedText, | |
}; | |
return ( | |
<LeaderboardContext.Provider value={value}> | |
{children} | |
</LeaderboardContext.Provider> | |
); | |
}; | |
export const useLeaderboard = () => { | |
const context = useContext(LeaderboardContext); | |
if (!context) { | |
throw new Error("useLeaderboard must be used within a LeaderboardProvider"); | |
} | |
return context; | |
}; | |