Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 228 additions & 0 deletions schemas/visual-config.schema.json

Large diffs are not rendered by default.

12 changes: 5 additions & 7 deletions src/frontend/overlay/src/components/atoms/ContestLabels.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const VerdictLabel = styled(ShrinkingBox)`
align-items: center;
justify-content: center;

font-size: 14px;
font-size: ${c.VERDICT_LABEL_FONT_SIZE};
font-weight: ${c.GLOBAL_DEFAULT_FONT_WEIGHT_BOLD};

background-color: ${({ color }) => color};
Expand Down Expand Up @@ -80,7 +80,7 @@ const VerdictCellProgressBar2 = styled.div.attrs(({ width }) => ({
}))`
height: 100%;
background-color: ${c.VERDICT_UNKNOWN};
transition: width 250ms linear;
transition: width ${c.VERDICT_CELL_TRANSITION_TIME} linear;
`;


Expand All @@ -93,7 +93,7 @@ const VerdictCellInProgressWrap2 = styled.div`
height: 100%;

border: 3px solid ${c.VERDICT_UNKNOWN};
border-radius: 0 16px 16px 0;
border-radius: 0 ${c.VERDICT_CELL_BRODER_RADIUS} ${c.VERDICT_CELL_BRODER_RADIUS} 0;
`;

const VerdictCellInProgress2 = ({ percentage, className }) => {
Expand Down Expand Up @@ -129,15 +129,13 @@ const AttemptsOrScoreLabelWrapper = styled.div`
position: absolute;
`;

const defaultColorForStar = "#F9A80D";

const ICPCTaskResultLabel2 = ({ problemColor, problemResult: r, ...props }) => {
const status = getStatus(r.isFirstToSolve, r.isSolved, r.pendingAttempts, r.wrongAttempts);
const attempts = r.wrongAttempts + r.pendingAttempts;
return <>
<TaskResultLabelWrapper2 color={TeamTaskColor[status]} {...props}>
{ status === TeamTaskStatus.first &&
<StarIcon color={problemColor === undefined ? defaultColorForStar : problemColor}/> }
<StarIcon color={problemColor === undefined ? c.STAR_DEFAULT_COLOR : problemColor}/> }
<AttemptsOrScoreLabelWrapper>
{TeamTaskSymbol[status]}
{status !== TeamTaskStatus.untouched && attempts > 0 && attempts}
Expand All @@ -148,7 +146,7 @@ const ICPCTaskResultLabel2 = ({ problemColor, problemResult: r, ...props }) => {

const IOITaskResultLabel2 = ({ problemColor, problemResult: r, minScore, maxScore, ...props }) => {
return <TaskResultLabelWrapper2 color={getIOIColor(r.score, minScore, maxScore)} { ...props}>
{ r.isFirstBest && <StarIcon color={problemColor === undefined ? defaultColorForStar : problemColor}/>}
{ r.isFirstBest && <StarIcon color={problemColor === undefined ? c.STAR_DEFAULT_COLOR : problemColor}/>}
<AttemptsOrScoreLabelWrapper>
{formatScore(r?.score)}
</AttemptsOrScoreLabelWrapper>
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/overlay/src/components/atoms/ProblemLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import styled from "styled-components";
import { isShouldUseDarkColor } from "../../utils/colors";
import c from "../../config";

const StyledProblemLabel = styled.div<{
backgroundColor: string;
Expand All @@ -12,7 +13,7 @@ const StyledProblemLabel = styled.div<{
align-items: center;
justify-content: center;

width: 28px;
width: ${c.PROBLEM_LABEL_WIDTH};
height: 100%;

color: ${({ darkText }) => darkText ? "#000" : "#FFF"};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const ContestantInfoLabel = styled(RankLabel)`
flex-shrink: 0;
align-self: stretch;
width: ${c.CONTESTER_INFO_RANK_WIDTH};
padding-left: 4px;
padding-left: ${c.CONTESTER_INFO_LEFT_PADDING};
`;

const ContestantInfoTeamNameLabel = styled(ShrinkingBox)`
Expand All @@ -25,7 +25,7 @@ const ContestantInfoTeamNameLabel = styled(ShrinkingBox)`
const ContestantInfoWrap = styled.div<{round: boolean, bg_color: string, color: string}>`
overflow: hidden;
display: flex;
gap: 5px;
gap: ${c.CONTESTER_INFO_GAP};
align-items: center;

width: 100%;
Expand All @@ -42,7 +42,7 @@ const ContestantInfoScoreLabel = styled(ShrinkingBox)`
flex-shrink: 0;
box-sizing: content-box;
width: ${c.CONTESTER_INFO_SCORE_WIDTH};
padding-right: 20px;
padding-right: ${c.CONTESTER_INFO_SCORE_RIGHT_PADDING};
`;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { isShouldUseDarkColor } from "@/utils/colors";
const ContestantViewCornerWrap = styled.div<{isSmall: boolean}>`
display: grid;
grid-template-rows: 1fr ${c.QUEUE_ROW_HEIGHT}px;
grid-template-columns: auto 150px;
grid-template-columns: auto ${c.CONTESTER_INFO_WIDTH};

width: auto;
/*transform: ${props => props.isSmall ? `scale(${c.TEAMVIEW_SMALL_FACTOR})` : ""};*/
Expand Down Expand Up @@ -44,7 +44,7 @@ const TasksContainer = styled.div`

const TaskRow = styled.div`
display: flex;
width: 150px;
width: ${c.CONTESTER_INFO_WIDTH};
flex: 0 0 ${c.QUEUE_ROW_HEIGHT}px;
/* css trick for perfect TaskRow overflowing: arrange the columns from bottom to top from right to left */
transform: scale(-1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,21 @@ interface ContestantViewLineProps {
isTop?: boolean
}

// TODO: DELETE!
function aboba<T>(x?: T[]) {
return x ? x : x;
}
export const ContestantViewLine = ({ teamId, tasksContainerY, className, isTop }: ContestantViewLineProps) => {
const scoreboardData = useAppSelector((state) =>
state.scoreboard[OptimismLevel.normal]?.ids && state.scoreboard[OptimismLevel.normal].ids[teamId]);
const tasks = aboba(useAppSelector(state => state.contestInfo?.info?.problems));
const tasks = useAppSelector(state => state.contestInfo?.info?.problems);
const contestData = useAppSelector((state) => state.contestInfo?.info);
const teamData = useAppSelector((state) => state.contestInfo.info?.teamsId[teamId]);

const [top, bottom] = isTop ? [null, "0"] : ["0", null];

const taskWidth = tasksContainerY ? Math.max(c.PVP_TEAM_STATUS_TASK_WIDTH, tasksContainerY / aboba(tasks)?.length) : c.PVP_TEAM_STATUS_TASK_WIDTH;
const taskWidth = tasksContainerY ? Math.max(c.PVP_TEAM_STATUS_TASK_WIDTH, tasksContainerY / tasks?.length) : c.PVP_TEAM_STATUS_TASK_WIDTH;

return (
<ContestantViewVerticalWrap className={className} tasks={aboba(scoreboardData?.problemResults)?.length} taskWidth={taskWidth} top={top} bottom={bottom}>
<ContestantViewVerticalWrap className={className} tasks={scoreboardData?.problemResults?.length} taskWidth={taskWidth} top={top} bottom={bottom}>
<CornerContestantInfo teamId={teamId} />
{aboba(scoreboardData?.problemResults)?.map((result, i) =>
{scoreboardData?.problemResults?.map((result, i) =>
<TaskRow
key={i}
start={i + 2} end={i + 3}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ import { isShouldUseDarkColor } from "@/utils/colors";


const TimeCell = styled.div`
flex-basis: 70%;
width: 50px;
flex-basis: ${c.TIME_CELL_FLEX_BASIS};
width: ${c.TIME_CELL_WIDTH};
text-align: center;

`;

const QueueProblemLabel = styled(ProblemLabel)`
flex-shrink: 0;
width: 28px;
width: ${c.QUEUE_ROW_PROBLEM_LABEL_WIDTH}px;
font-size: ${c.QUEUE_PROBLEM_LABEL_FONT_SIZE};
`;

Expand Down Expand Up @@ -55,7 +54,7 @@ const SubmissionColumnWrap = styled.div<{bg_color: string, darkText: boolean}>`

const SubmissionRowTaskResultLabel = styled(ScoreboardTaskResultLabel)`
flex-shrink: 0;
width: 40px;
width: ${c.SUBMISSION_ROW_TASK_RESULT_LABEL_WIDTH};
height: 100%;
text-align: center;
`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const LegendCardWrapper = styled.div`
`;

const LegendWrapper = styled.div`
margin: 8px 16px;
margin: ${c.LEGEND_VERTICAL_MARGIN} ${c.LEGEND_HORIZONTAL_MARGIN};

font-family: ${c.GLOBAL_DEFAULT_FONT_FAMILY};
font-size: ${c.GLOBAL_DEFAULT_FONT_SIZE};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ const CircleAtEnd = styled.div.attrs<CircleAtEndProps>(({ lineWidth, leftPadding
left: `calc(${lineWidth}% + ${leftPadding}px)`,
},
}))<CircleAtEndProps>`
width: 10px;
height: 10px;
width: ${c.TIMELINE_END_CIRCLE_RADIUS}px;
height: ${c.TIMELINE_END_CIRCLE_RADIUS}px;
border-radius: 50%;
position: absolute;
top: 50%;
Expand Down Expand Up @@ -159,7 +159,7 @@ const StaticText = styled.div`
const TimeBorder = styled.div<TimeBorderProps>`
height: ${props => props.isPvp ? c.TIMELINE_WRAP_HEIGHT_PVP : c.TIMELINE_WRAP_HEIGHT}px;
background-color: ${props => isShouldUseDarkColor(props.color) ? "#000" : "#fff"};
width: 2px;
width: ${c.TIMELINE_TIME_BORDER_WIDTH}px;
position: absolute;
left: ${props => props.left};
`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import styled from "styled-components";
import { image } from "@shared/api";
import c from "@/config";


export const ImageWrap = styled.div<{path: string}>`
Expand All @@ -9,7 +10,7 @@ export const ImageWrap = styled.div<{path: string}>`
max-height: 100%;
max-width: 100%;
display: flex;
padding: 0 16px;
padding: 0 ${c.IMAGE_TICKER_HORIZONTAL_PADDING};
box-sizing: border-box;
background: center / contain no-repeat url(${(props) => props.path});
`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const ScoreboardWrap = styled.div.attrs<ScoreboardWrapProps>(({ top }) => (
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(${props => props.nrows}, 1fr);
gap: 2px;
gap: ${c.TICKER_SCOREBOARD_GAP};

width: 100%;
height: 100%;
Expand All @@ -29,8 +29,7 @@ const ScoreboardWrap = styled.div.attrs<ScoreboardWrapProps>(({ top }) => (
`;

const TickerScoreboardContestantInfo = styled(ContestantInfo)`
height: 48px;

height: ${c.TICKER_SCOREBOARD_CONTESTANT_INFO_HEIGHT};
`;

export const Scoreboard = ({ tickerSettings, state }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ export const TextWrap = styled.div<{part: TickerPart}>`
display: flex;
justify-content: ${props => props.part === "long" ? "flex-start" : "center"};

box-sizing: border-box;
box-sizing: border-box;
width: 100%;
block-size: fit-content;
padding: 0 16px;
padding: 0 ${c.TICKER_TEXT_HORIZONTAL_PADDING};

font-size: ${c.TICKER_TEXT_FONT_SIZE};
`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const AdvertisementContainer = styled.div`

// TODO: move this to constants.js
const AdvertisementWrap = styled.div`
padding: 13px 20px;
padding: ${c.ADVERTISEMENT_VERTICAL_PADDING} ${c.ADVERTISEMENT_HORIZONTAL_PADDING};

font-family: ${c.ADVERTISEMENT_FONT_FAMILY}, serif;
font-size: 24pt;
font-size: ${c.ADVERTISEMENT_FONT_SIZE};
font-weight: ${c.GLOBAL_DEFAULT_FONT_WEIGHT_BOLD};
color: ${c.ADVERTISEMENT_COLOR};

background-color: ${c.ADVERTISEMENT_BACKGROUND};
border-radius: 12px;
border-radius: ${c.ADVERTISEMENT_BORDER_RADIUS};
text-align: center;
`;

Expand Down
20 changes: 10 additions & 10 deletions src/frontend/overlay/src/components/organisms/widgets/Locator.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,26 +69,26 @@ export const Locator = ({ widgetData, transitionState }) => {
{circles.map((circle, index) => {
let left = circle.x - c.LOCATOR_MAGIC_CONSTANT / 2;
let top;
if (circle.y - circle.radius - 50 > 10) {
top = circle.y - circle.radius - 50;
if (circle.y - circle.radius - c.LOCATOR_TOP_OFFSET > c.LOCATOR_TOP_THRESHOLD) {
top = circle.y - circle.radius - c.LOCATOR_TOP_OFFSET;
} else {
top = circle.y + circle.radius + 16;
top = circle.y + circle.radius + c.LOCATOR_BOTTOM_OFFSET;
}
if (left < 0) {
left = 0;
} else if (left + c.LOCATOR_MAGIC_CONSTANT > 1920) {
left = 1920 - c.LOCATOR_MAGIC_CONSTANT;
} else if (left + c.LOCATOR_MAGIC_CONSTANT > c.LOCATOR_MAX_WIDTH) {
left = c.LOCATOR_MAX_WIDTH - c.LOCATOR_MAGIC_CONSTANT;
}
const len = Math.sqrt((left + c.LOCATOR_MAGIC_CONSTANT / 2 - circle.x) * (left + c.LOCATOR_MAGIC_CONSTANT / 2 - circle.x) +
(top + 10 - circle.y) * (top + 10 - circle.y));
(top + c.LOCATOR_TOP_THRESHOLD - circle.y) * (top + c.LOCATOR_TOP_THRESHOLD - circle.y));
return <div style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }}
key={circle.teamId}>
<TeamViewWrapper
top={top}
left={left}
animation={transitionState === "exiting" ? slideOut : slideIn}
animationStyle={transitionState === "exiting" ? "ease-in" : "ease-out"}
duration={(index + 1) * 1500}>
duration={(index + 1) * c.LOCATOR_ANIMATION_DURATION}>
{/* FIXME: This needs readdressing for overlay2 */}
{/*<TeamInfo key={index + "teamInfo"} teamId={circle.teamId}/>*/}
<CornerContestantInfo teamId={circle.teamId} />
Expand All @@ -97,10 +97,10 @@ export const Locator = ({ widgetData, transitionState }) => {

<LineWrapper animation={transitionState === "exiting" ? slideOut : slideIn}
animationStyle={transitionState === "exiting" ? "ease-in" : "ease-out"}
duration={(index + 1) * 1500 - 500}>
<svg key={index + "path"} height="100%" width="100%" stroke="white" strokeWidth="5" fill="none">
duration={(index + 1) * c.LOCATOR_ANIMATION_DURATION - c.LOCATOR_ANIMATION_DELAY}>
<svg key={index + "path"} height="100%" width="100%" stroke={c.LOCATOR_LINE_STROKE_COLOR} strokeWidth={c.LOCATOR_LINE_STROKE_WIDTH} fill="none">
<path
d={`M ${circle.x + (left + c.LOCATOR_MAGIC_CONSTANT / 2 - circle.x) / len * circle.radius} ${circle.y + (top + 10 - circle.y) / len * circle.radius} L ${left + c.LOCATOR_MAGIC_CONSTANT / 2} ${top + 10}`}/>
d={`M ${circle.x + (left + c.LOCATOR_MAGIC_CONSTANT / 2 - circle.x) / len * circle.radius} ${circle.y + (top + c.LOCATOR_TOP_THRESHOLD - circle.y) / len * circle.radius} L ${left + c.LOCATOR_MAGIC_CONSTANT / 2} ${top + c.LOCATOR_TOP_THRESHOLD}`}/>
</svg>
</LineWrapper>
</div>;
Expand Down
Loading
Loading