Skip to content

Commit fce3fb8

Browse files
Merge branch 'master' of https://github.com/shaubby/usaco-guide into shaubby-master
2 parents 023b5e0 + 87bfb42 commit fce3fb8

File tree

3 files changed

+119
-87
lines changed

3 files changed

+119
-87
lines changed

src/components/markdown/FocusProblem.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { ExternalLinkIcon } from '@heroicons/react/solid';
22
import * as React from 'react';
3+
import { Instance } from 'tippy.js';
4+
import { useDarkMode } from '../../context/DarkModeContext';
35
import { useMarkdownProblemLists } from '../../context/MarkdownProblemListsContext';
46
import { getProblemURL, ProblemInfo } from '../../models/problem';
7+
import ProblemsListItemDropdown from './ProblemsList/ProblemsListItemDropdown';
58
import ProblemStatusCheckbox from './ProblemsList/ProblemStatusCheckbox';
69

710
export default function FocusProblem({
@@ -22,9 +25,13 @@ export default function FocusProblem({
2225
`The focus problem list ${problemID} should have exactly one problem.`
2326
);
2427
}
28+
const darkMode = useDarkMode();
2529

2630
const problem: ProblemInfo = problemList.problems[0];
2731

32+
const tippyRef = React.useRef<Instance>();
33+
const [isDropdownShown, setIsDropdownShown] = React.useState(false);
34+
2835
// transform must go in the isHovered condition
2936
// See https://github.com/thecodingwizard/usaco-guide/issues/198
3037
// transform creates a new stacking context :(
@@ -65,6 +72,17 @@ export default function FocusProblem({
6572
</div>
6673
</div>
6774
<div className="flex-shrink-0 flex items-center justify-center mt-1 sm:mr-2 ml-2">
75+
<div className="mr-2">
76+
<ProblemsListItemDropdown
77+
onShowSolutionSketch={(problem: ProblemInfo) => {
78+
return problem;
79+
}}
80+
problem={problem}
81+
showTags={true}
82+
showDifficulty={true}
83+
isFocusProblem={true}
84+
/>
85+
</div>
6886
<ProblemStatusCheckbox problem={problem} size="large" />
6987
</div>
7088
</div>

src/components/markdown/ProblemsList/ProblemsListItem.tsx

+3-49
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import Tippy from '@tippyjs/react';
2-
import { navigate } from 'gatsby';
31
import * as React from 'react';
42
import styled, { css } from 'styled-components';
53
import { Instance } from 'tippy.js';
@@ -167,52 +165,6 @@ export default function ProblemsListItem(
167165
const tippyRef = React.useRef<Instance>();
168166
const [isDropdownShown, setIsDropdownShown] = React.useState(false);
169167

170-
const more = (
171-
<div>
172-
<Tippy
173-
onCreate={tippy => (tippyRef.current = tippy)}
174-
content={
175-
isDropdownShown ? (
176-
<ProblemsListItemDropdown
177-
{...props}
178-
onViewProblemSolutions={() => {
179-
tippyRef.current.hide();
180-
navigate('/problem-solutions/', {
181-
state: {
182-
problem,
183-
},
184-
});
185-
}}
186-
/>
187-
) : (
188-
''
189-
)
190-
}
191-
theme={darkMode ? 'dark' : 'light'}
192-
placement="bottom-end"
193-
arrow={true}
194-
animation="fade"
195-
trigger="click"
196-
interactive={true}
197-
onShow={() => setIsDropdownShown(true)}
198-
onHidden={() => setIsDropdownShown(false)}
199-
>
200-
<button className="focus:outline-none w-8 h-8 inline-flex items-center justify-center text-gray-400 rounded-full bg-transparent hover:text-gray-500 dark:hover:text-gray-300">
201-
{/* Heroicon name: solid/dots-vertical */}
202-
<svg
203-
className="w-5 h-5"
204-
xmlns="http://www.w3.org/2000/svg"
205-
viewBox="0 0 20 20"
206-
fill="currentColor"
207-
aria-hidden="true"
208-
>
209-
<path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
210-
</svg>
211-
</button>
212-
</Tippy>
213-
</div>
214-
);
215-
216168
return (
217169
<StyledProblemRow id={id} isActive={isActive}>
218170
{statusCol}
@@ -252,7 +204,9 @@ export default function ProblemsListItem(
252204
)}
253205
</td>
254206
)}
255-
<td className="text-center pr-2 md:pr-3">{more}</td>
207+
<td className="text-center pr-2 md:pr-3">
208+
<ProblemsListItemDropdown {...props} isFocusProblem={false} />
209+
</td>
256210
</StyledProblemRow>
257211
);
258212
}

src/components/markdown/ProblemsList/ProblemsListItemDropdown.tsx

+98-38
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
1+
import Tippy from '@tippyjs/react';
2+
import { navigate } from 'gatsby';
13
import React from 'react';
4+
import { Instance } from 'tippy.js';
5+
import { useDarkMode } from '../../../context/DarkModeContext';
26
import useUserSolutionsForProblem from '../../../hooks/useUserSolutionsForProblem';
37
import { isUsaco } from '../../../models/problem';
48
import TextTooltip from '../../Tooltip/TextTooltip';
59
import ProblemListItemSolution from './ProblemListItemSolution';
610
import { ProblemsListItemProps } from './ProblemsListItem';
711

812
export default function ProblemsListItemDropdown(
9-
props: ProblemsListItemProps & { onViewProblemSolutions: () => void }
13+
props: ProblemsListItemProps & { isFocusProblem: boolean }
1014
) {
1115
const [copied, setCopied] = React.useState(false);
1216

1317
const problem = props.problem;
18+
const isFocusProblem = props.isFocusProblem;
19+
console.log(isFocusProblem);
1420
const { solutions, currentUserSolutions } =
1521
useUserSolutionsForProblem(problem);
1622

1723
let viewSolutionsContent = (
1824
<>View User Solutions ({solutions?.length ?? '...'})</>
1925
);
26+
27+
const darkMode = useDarkMode();
2028
if (currentUserSolutions?.length) {
2129
viewSolutionsContent = (
2230
<>
@@ -40,47 +48,99 @@ export default function ProblemsListItemDropdown(
4048
</>
4149
);
4250
}
51+
let solutionContent = <></>;
52+
if (!isFocusProblem) {
53+
solutionContent = (
54+
<ProblemListItemSolution
55+
problem={props.problem}
56+
onShowSolutionSketch={props.onShowSolutionSketch}
57+
/>
58+
);
59+
}
60+
61+
const tippyRef = React.useRef<Instance>();
62+
const [isDropdownShown, setIsDropdownShown] = React.useState(false);
63+
64+
const onViewProblemSolutions = () => {
65+
tippyRef.current.hide();
66+
navigate('/problem-solutions/', {
67+
state: {
68+
problem,
69+
},
70+
});
71+
};
72+
4373
return (
4474
<div className="-mx-2 text-left">
4575
<div>
46-
<ProblemListItemSolution
47-
problem={props.problem}
48-
onShowSolutionSketch={props.onShowSolutionSketch}
49-
/>
50-
<button
51-
type="button"
52-
className="focus:outline-none block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-gray-900"
53-
onClick={props.onViewProblemSolutions}
54-
>
55-
{viewSolutionsContent}
56-
</button>
57-
<button
58-
type="button"
59-
className="focus:outline-none block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-gray-900"
60-
onClick={e => {
61-
e.preventDefault();
62-
setCopied(true);
63-
navigator.clipboard.writeText(
64-
window.location.href.split(/[?#]/)[0] +
65-
'#problem-' +
66-
problem.uniqueId
67-
);
68-
}}
76+
<Tippy
77+
onCreate={tippy => (tippyRef.current = tippy)}
78+
content={
79+
isDropdownShown ? (
80+
<div>
81+
{solutionContent}
82+
83+
<button
84+
type="button"
85+
className="focus:outline-none block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-gray-900"
86+
onClick={onViewProblemSolutions}
87+
>
88+
{viewSolutionsContent}
89+
</button>
90+
<button
91+
type="button"
92+
className="focus:outline-none block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-gray-900"
93+
onClick={e => {
94+
e.preventDefault();
95+
setCopied(true);
96+
navigator.clipboard.writeText(
97+
window.location.href.split(/[?#]/)[0] +
98+
'#problem-' +
99+
problem.uniqueId
100+
);
101+
}}
102+
>
103+
{copied ? 'Copied!' : 'Copy Permalink'}
104+
</button>
105+
{isUsaco(problem.source) && (
106+
<a
107+
className="!font-normal focus:outline-none block w-full text-left px-4 py-2 text-sm !text-gray-700 dark:!text-gray-300 hover:!bg-gray-100 dark:hover:!bg-gray-800 hover:!text-gray-900"
108+
href={`https://ide.usaco.guide/usaco/${problem.uniqueId.substring(
109+
problem.uniqueId.indexOf('-') + 1
110+
)}`}
111+
target="_blank"
112+
rel="noreferrer"
113+
>
114+
Open in IDE
115+
</a>
116+
)}
117+
</div>
118+
) : (
119+
''
120+
)
121+
}
122+
theme={darkMode ? 'dark' : 'light'}
123+
placement="bottom-end"
124+
arrow={true}
125+
animation="fade"
126+
trigger="click"
127+
interactive={true}
128+
onShow={() => setIsDropdownShown(true)}
129+
onHidden={() => setIsDropdownShown(false)}
69130
>
70-
{copied ? 'Copied!' : 'Copy Permalink'}
71-
</button>
72-
{isUsaco(problem.source) && (
73-
<a
74-
className="!font-normal focus:outline-none block w-full text-left px-4 py-2 text-sm !text-gray-700 dark:!text-gray-300 hover:!bg-gray-100 dark:hover:!bg-gray-800 hover:!text-gray-900"
75-
href={`https://ide.usaco.guide/usaco/${problem.uniqueId.substring(
76-
problem.uniqueId.indexOf('-') + 1
77-
)}`}
78-
target="_blank"
79-
rel="noreferrer"
80-
>
81-
Open in IDE
82-
</a>
83-
)}
131+
<button className="focus:outline-none w-8 h-8 inline-flex items-center justify-center text-gray-400 rounded-full bg-transparent hover:text-gray-500 dark:hover:text-gray-300">
132+
{/* Heroicon name: solid/dots-vertical */}
133+
<svg
134+
className="w-5 h-5"
135+
xmlns="http://www.w3.org/2000/svg"
136+
viewBox="0 0 20 20"
137+
fill="currentColor"
138+
aria-hidden="true"
139+
>
140+
<path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
141+
</svg>
142+
</button>
143+
</Tippy>
84144
</div>
85145
</div>
86146
);

0 commit comments

Comments
 (0)