1+ import { useMemo } from "react" ;
2+ import useSWR from "swr" ;
13import { fetchSubmissionsFromDatabaseAndServer } from "../database/SubmissionsDB" ;
24import Contest , { isContest } from "../interfaces/Contest" ;
35import { isContestParticipation } from "../interfaces/ContestParticipation" ;
@@ -15,9 +17,9 @@ import { isSubmission } from "../interfaces/Submission";
1517import { isUserRankEntry , UserRankEntry } from "../interfaces/UserRankEntry" ;
1618import { clipDifficulty , isValidResult } from "../utils" ;
1719import { toChunks } from "../utils/Chunk" ;
20+ import { classifyContest } from "../utils/ContestClassifier" ;
1821import { ratingInfoOf } from "../utils/RatingInfo" ;
1922import { hasPropertyAsType , isString } from "../utils/TypeUtils" ;
20- import { useSWRData } from "./index" ;
2123
2224const STATIC_API_BASE_URL = "https://kenkoooo.com/atcoder/resources" ;
2325const PROXY_API_URL = "https://kenkoooo.com/atcoder/proxy" ;
@@ -65,9 +67,7 @@ function fetchTypedArray<T>(
6567}
6668
6769const useRankingV3 = ( url : string ) => {
68- return useSWRData ( url , ( u ) =>
69- fetchTypedArray < RankingEntry > ( u , isRankingEntry )
70- ) ;
70+ return useSWR ( url , ( u ) => fetchTypedArray < RankingEntry > ( u , isRankingEntry ) ) ;
7171} ;
7272
7373export const useACRanking = ( from : number , to : number ) => {
@@ -79,7 +79,7 @@ export const useUserACRank = (user: string) => {
7979 const url = `${ ATCODER_API_URL } /v3/user/ac_rank?user=${ encodeURIComponent (
8080 user
8181 ) } `;
82- return useSWRData ( url , ( url ) =>
82+ return useSWR ( url , ( url ) =>
8383 fetchTypedValue < UserRankEntry > ( url , isUserRankEntry )
8484 ) ;
8585} ;
@@ -93,7 +93,7 @@ export const useUserStreakRank = (user: string) => {
9393 const url = `${ ATCODER_API_URL } /v3/user/streak_rank?user=${ encodeURIComponent (
9494 user
9595 ) } `;
96- return useSWRData ( url , ( url ) =>
96+ return useSWR ( url , ( url ) =>
9797 fetchTypedValue < UserRankEntry > ( url , isUserRankEntry )
9898 ) ;
9999} ;
@@ -107,26 +107,40 @@ export const useUserSumRank = (user: string) => {
107107 const url = `${ ATCODER_API_URL } /v3/user/rated_point_sum_rank?user=${ encodeURIComponent (
108108 user
109109 ) } `;
110- return useSWRData ( url , ( url ) =>
110+ return useSWR ( url , ( url ) =>
111111 fetchTypedValue < UserRankEntry > ( url , isUserRankEntry )
112112 ) ;
113113} ;
114114
115115export const useMergedProblemMap = ( ) => {
116+ const fetcher = ( url : string ) => fetchTypedArray ( url , isMergedProblem ) ;
116117 const url = STATIC_API_BASE_URL + "/merged-problems.json" ;
117- return useSWRData ( url , ( url ) =>
118- fetchTypedArray ( url , isMergedProblem ) . then ( ( problems ) =>
119- problems . reduce ( ( map , problem ) => {
118+ const problems = useSWR ( url , fetcher ) ;
119+ const contests = useContestMap ( ) ;
120+
121+ const map = useMemo ( ( ) => {
122+ const map = new Map < ProblemId , MergedProblem > ( ) ;
123+ problems . data ?. forEach ( ( problem ) => {
124+ const contest = contests ?. get ( problem . contest_id ) ;
125+ if ( ! contest ) {
126+ return ;
127+ }
128+
129+ const contestType = classifyContest ( contest ) ;
130+ if ( contestType === "AHC" ) {
131+ map . set ( problem . id , { ...problem , point : undefined } ) ;
132+ } else {
120133 map . set ( problem . id , problem ) ;
121- return map ;
122- } , new Map < ProblemId , MergedProblem > ( ) )
123- )
124- ) ;
134+ }
135+ } ) ;
136+ return map ;
137+ } , [ contests , problems ] ) ;
138+ return { data : map } ;
125139} ;
126140
127141export const useLangList = ( ) => {
128142 const url = `${ ATCODER_API_URL } /v3/language_list` ;
129- return useSWRData ( url , ( url ) => fetchTypedArray ( url , isString ) ) ;
143+ return useSWR ( url , ( url ) => fetchTypedArray ( url , isString ) ) ;
130144} ;
131145
132146export const useOneLangRanking = (
@@ -156,8 +170,8 @@ export const useFirstRanking = () => {
156170export const useRatingInfo = ( user : string ) => {
157171 const url = `${ PROXY_API_URL } /users/${ user } /history/json` ;
158172 const history =
159- useSWRData ( url , ( url ) => fetchTypedArray ( url , isContestParticipation ) )
160- ?. data ?? [ ] ;
173+ useSWR ( url , ( url ) => fetchTypedArray ( url , isContestParticipation ) ) ?. data ??
174+ [ ] ;
161175 return ratingInfoOf ( history ) ;
162176} ;
163177
@@ -171,26 +185,24 @@ export const useMultipleUserSubmissions = (userIds: UserId[]) => {
171185 const arrays = await Promise . all ( promises ) ;
172186 return arrays . flat ( ) ;
173187 } ;
174- const users = userIds . join ( "," ) ;
175- return useSWRData ( `multiple-user-submission ${ users } ` , ( s ) => {
176- const users = s . split ( " " ) [ 1 ] ;
177- return fetcher ( users . split ( "," ) ) ;
178- } ) ;
188+ return useSWR ( { key : "multiple-user-submission" , userIds } , ( { userIds } ) =>
189+ fetcher ( userIds )
190+ ) ;
179191} ;
180192
181193export const useContests = ( ) => {
182194 const url = STATIC_API_BASE_URL + "/contests.json" ;
183- return useSWRData ( url , ( url ) => fetchTypedArray ( url , isContest ) ) ;
195+ return useSWR ( url , ( url ) => fetchTypedArray ( url , isContest ) ) ;
184196} ;
185197
186198export const useProblems = ( ) => {
187199 const url = STATIC_API_BASE_URL + "/problems.json" ;
188- return useSWRData ( url , ( url ) => fetchTypedArray ( url , isProblem ) ) . data ;
200+ return useSWR ( url , ( url ) => fetchTypedArray ( url , isProblem ) ) . data ;
189201} ;
190202
191203const useContestProblemList = ( ) => {
192204 const url = STATIC_API_BASE_URL + "/contest-problem.json" ;
193- return useSWRData ( url , ( url ) =>
205+ return useSWR ( url , ( url ) =>
194206 fetchTypedArray (
195207 url ,
196208 (
@@ -258,29 +270,58 @@ export const useProblemMap = () => {
258270} ;
259271
260272export const useProblemModelMap = ( ) => {
261- const fetcher = ( url : string ) =>
262- fetch ( url )
263- . then ( ( r ) => r . json ( ) )
264- . then ( ( obj : { [ p : string ] : unknown } ) =>
265- Object . entries ( obj )
266- . filter ( ( entry ) : entry is [ string , ProblemModel ] =>
267- isProblemModel ( entry [ 1 ] )
268- )
269- . reduce ( ( map , [ problemId , problemModel ] ) => {
270- if ( problemModel . difficulty === undefined ) {
271- map . set ( problemId , problemModel ) ;
272- } else {
273- map . set ( problemId , {
274- ...problemModel ,
275- difficulty : clipDifficulty ( problemModel . difficulty ) ,
276- rawDifficulty : problemModel . difficulty ,
277- } ) ;
278- }
279- return map ;
280- } , new Map < ProblemId , ProblemModel > ( ) )
281- ) ;
273+ const fetcher = async ( url : string ) => {
274+ const response = await fetch ( url ) ;
275+ const result : unknown = await response . json ( ) ;
276+ if ( typeof result !== "object" || ! result ) {
277+ return [ ] as { problemId : ProblemId ; model : ProblemModel } [ ] ;
278+ }
279+
280+ const models = [ ] as { problemId : ProblemId ; model : ProblemModel } [ ] ;
281+ Object . entries ( result ) . forEach ( ( [ key , value ] ) => {
282+ if ( isProblemModel ( value ) ) {
283+ models . push ( { problemId : key , model : value } ) ;
284+ }
285+ } ) ;
286+ return models ;
287+ } ;
288+
282289 const url = STATIC_API_BASE_URL + "/problem-models.json" ;
283- return useSWRData ( url , fetcher ) . data ;
290+ const problemModels = useSWR ( url , fetcher ) ;
291+ const contests = useContestMap ( ) ;
292+ const problems = useProblemMap ( ) ;
293+
294+ const modelMap = useMemo ( ( ) => {
295+ const map = new Map < ProblemId , ProblemModel > ( ) ;
296+ problemModels . data ?. forEach ( ( { problemId, model } ) => {
297+ const problem = problems ?. get ( problemId ) ;
298+ if ( ! problem ) {
299+ return ;
300+ }
301+ const contest = contests ?. get ( problem . contest_id ) ;
302+ if ( ! contest ) {
303+ return ;
304+ }
305+ const contestType = classifyContest ( contest ) ;
306+ if ( contestType === "AHC" ) {
307+ return ;
308+ }
309+
310+ if ( model . difficulty === undefined ) {
311+ map . set ( problemId , model ) ;
312+ } else {
313+ map . set ( problemId , {
314+ ...model ,
315+ difficulty : clipDifficulty ( model . difficulty ) ,
316+ rawDifficulty : model . difficulty ,
317+ } ) ;
318+ }
319+ } ) ;
320+
321+ return map ;
322+ } , [ problemModels , problems , contests ] ) ;
323+
324+ return modelMap ;
284325} ;
285326
286327export const useVirtualContestSubmissions = (
@@ -348,10 +389,10 @@ export const useVirtualContestSubmissions = (
348389 : 1_000_000_000 ;
349390
350391 const customKey = serialize ( users , problems ) ;
351- return useSWRData ( customKey , fetcher , { refreshInterval } ) ;
392+ return useSWR ( customKey , fetcher , { refreshInterval } ) ;
352393} ;
353394
354395export const useRecentSubmissions = ( ) => {
355396 const url = `${ ATCODER_API_URL } /v3/recent` ;
356- return useSWRData ( url , ( url ) => fetchTypedArray ( url , isSubmission ) ) ;
397+ return useSWR ( url , ( url ) => fetchTypedArray ( url , isSubmission ) ) ;
357398} ;
0 commit comments