Skip to content

Commit 9c57f46

Browse files
authored
Merge pull request #1272 from kenkoooo/staging
publish changes
2 parents c2d4da5 + c7423be commit 9c57f46

File tree

6 files changed

+104
-9
lines changed

6 files changed

+104
-9
lines changed

atcoder-problems-frontend/src/pages/TablePage/Options.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ interface Props {
2727
selectableLanguages: Set<string>;
2828
selectedLanguages: Set<string>;
2929
toggleLanguage: (language: string) => void;
30+
mergeLikeContest: boolean;
31+
setMergeLikeContest: (mergeLikeContest: boolean) => void;
3032
}
3133

3234
export const Options: React.FC<Props> = (props) => {
@@ -38,7 +40,7 @@ export const Options: React.FC<Props> = (props) => {
3840
<CustomInput
3941
type="switch"
4042
id="hideCompletedContest"
41-
label="Hide Completed Contest"
43+
label="Hide Completed Contests"
4244
checked={props.hideCompletedContest}
4345
onChange={props.toggleHideCompletedContest}
4446
/>
@@ -59,6 +61,19 @@ export const Options: React.FC<Props> = (props) => {
5961
Internal rating to have 50% Solve Probability
6062
</HelpBadgeTooltip>
6163
</FormGroup>
64+
<FormGroup check inline class="my-4">
65+
<Label check>
66+
<CustomInput
67+
type="switch"
68+
id="mergeLikeContest"
69+
label='Merge "-Like" Contests'
70+
checked={props.mergeLikeContest}
71+
onChange={() => {
72+
props.setMergeLikeContest(!props.mergeLikeContest);
73+
}}
74+
/>
75+
</Label>
76+
</FormGroup>
6277
{props.colorMode === ColorMode.ContestResult && (
6378
<FormGroup check inline>
6479
<Label check>

atcoder-problems-frontend/src/pages/TablePage/TableTab.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
1-
import React from "react";
1+
import React, { useMemo } from "react";
22
import { Row, ButtonGroup, Button } from "reactstrap";
33
import {
44
ContestCategories,
55
ContestCategory,
66
} from "../../utils/ContestClassifier";
7+
import { isLikeContest } from "../../utils/LikeContestUtils";
78

89
interface Props {
910
active: ContestCategory;
1011
setActive: (next: ContestCategory) => void;
12+
mergeLikeContest: boolean;
1113
}
1214

1315
export const TableTabButtons: React.FC<Props> = (props) => {
14-
const { active, setActive } = props;
16+
const { active, setActive, mergeLikeContest } = props;
17+
18+
const filteredCategories = useMemo(() => {
19+
return ContestCategories.filter(
20+
(category) => !mergeLikeContest || !isLikeContest(category)
21+
);
22+
}, [mergeLikeContest]);
23+
1524
return (
1625
<Row>
1726
<ButtonGroup className="table-tab">
18-
{ContestCategories.map((category, i) => (
27+
{filteredCategories.map((category) => (
1928
<Button
20-
key={i}
29+
key={category}
2130
color="secondary"
2231
onClick={(): void => {
2332
setActive(category);

atcoder-problems-frontend/src/pages/TablePage/index.tsx

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from "react";
1+
import React, { useMemo, useState } from "react";
22
import { List } from "immutable";
33
import {
44
useContests,
@@ -21,6 +21,7 @@ import {
2121
classifyContest,
2222
ContestCategory,
2323
} from "../../utils/ContestClassifier";
24+
import { getLikeContestCategory } from "../../utils/LikeContestUtils";
2425
import { TableTabButtons } from "./TableTab";
2526
import { Options } from "./Options";
2627
import { ContestTable } from "./ContestTable";
@@ -52,6 +53,10 @@ export const TablePage: React.FC<OuterProps> = (props) => {
5253
"showPenalties",
5354
false
5455
);
56+
const [mergeLikeContest, setMergeLikeContest] = useLocalStorage(
57+
"MergeLikeContest",
58+
false
59+
);
5560
const [selectedLanguages, setSelectedLanguages] = useState(new Set<string>());
5661
const userRatingInfo = useRatingInfo(props.userId);
5762
const contestToProblems =
@@ -76,8 +81,21 @@ export const TablePage: React.FC<OuterProps> = (props) => {
7681
filteredSubmissions,
7782
props.userId
7883
);
79-
const filteredContests =
80-
contests?.filter((c) => classifyContest(c) === activeTab) ?? [];
84+
85+
const filteredContests = useMemo(() => {
86+
if (!contests) {
87+
return [];
88+
}
89+
return contests.filter((contest) => {
90+
const contestType = classifyContest(contest);
91+
if (contestType === activeTab) {
92+
return true;
93+
}
94+
return (
95+
mergeLikeContest && getLikeContestCategory(activeTab) === contestType
96+
);
97+
});
98+
}, [contests, activeTab, mergeLikeContest]);
8199

82100
return (
83101
<div>
@@ -99,8 +117,14 @@ export const TablePage: React.FC<OuterProps> = (props) => {
99117
newSet.has(language) ? newSet.delete(language) : newSet.add(language);
100118
setSelectedLanguages(newSet);
101119
}}
120+
mergeLikeContest={mergeLikeContest}
121+
setMergeLikeContest={setMergeLikeContest}
122+
/>
123+
<TableTabButtons
124+
active={activeTab}
125+
setActive={setActiveTab}
126+
mergeLikeContest={mergeLikeContest}
102127
/>
103-
<TableTabButtons active={activeTab} setActive={setActiveTab} />
104128
{[
105129
"ABC",
106130
"ARC",
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { getLikeContestCategory } from "./LikeContestUtils";
2+
import { ContestCategory } from "./ContestClassifier";
3+
4+
type GetLikeContestTestType = [ContestCategory, ContestCategory | undefined];
5+
test.each<GetLikeContestTestType>([
6+
["ABC", "ABC-Like"],
7+
["ARC", "ARC-Like"],
8+
["AGC", "AGC-Like"],
9+
["ABC-Like", undefined],
10+
["ARC-Like", undefined],
11+
["AGC-Like", undefined],
12+
["PAST", undefined],
13+
["JOI", undefined],
14+
["JAG", undefined],
15+
["AHC", undefined],
16+
["Marathon", undefined],
17+
["Other Sponsored", undefined],
18+
["Other Contests", undefined],
19+
])("Get Like Contest", (contest, result) => {
20+
expect(getLikeContestCategory(contest)).toBe(result);
21+
});
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { ContestCategory } from "./ContestClassifier";
2+
3+
export const getLikeContestCategory = (
4+
contestCategory: ContestCategory
5+
): ContestCategory | undefined => {
6+
switch (contestCategory) {
7+
case "ABC":
8+
return "ABC-Like";
9+
case "ARC":
10+
return "ARC-Like";
11+
case "AGC":
12+
return "AGC-Like";
13+
default:
14+
break;
15+
}
16+
};
17+
18+
const LikeContestCategories: readonly ContestCategory[] = [
19+
"ABC-Like",
20+
"ARC-Like",
21+
"AGC-Like",
22+
];
23+
export const isLikeContest = (category: ContestCategory) => {
24+
return LikeContestCategories.includes(category);
25+
};

atcoder-problems-frontend/src/utils/LocalStorage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const LocalStorageKeys = [
1717
"recommendOption",
1818
"recommendExperimental",
1919
"recoomendExcludeOption",
20+
"MergeLikeContest",
2021
] as const;
2122
type LocalStorageKey = typeof LocalStorageKeys[number];
2223

0 commit comments

Comments
 (0)