Skip to content

Commit

Permalink
Added tournament
Browse files Browse the repository at this point in the history
  • Loading branch information
osztenkurden committed Aug 17, 2020
1 parent 26153bf commit 2ad093f
Show file tree
Hide file tree
Showing 11 changed files with 392 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lexogrine_hud",
"version": "1.3.1",
"version": "1.4.0",
"homepage": "./",
"private": true,
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion public/hud.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name":"Lexogrine HUD",
"version":"1.3.1",
"version":"1.4.0",
"author":"Lexogrine",
"legacy": false,
"radar": true,
Expand Down
14 changes: 14 additions & 0 deletions public/panel.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@
"type": "checkbox",
"name": "match_preview_toggle",
"label": "Show upcoming match"
},
{
"type": "action",
"name": "showTournament",
"values": [
{
"name": "show",
"label": "Show tournament"
},
{
"name": "hide",
"label": "Hide tournament"
}
]
}

]
Expand Down
3 changes: 3 additions & 0 deletions src/HUD/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import UtilityLevel from '../SideBoxes/UtilityLevel';
import Killfeed from "../Killfeed/Killfeed";
import MapSeries from "./../MatchBar/MapSeries";
import Overview from "../Overview/Overview";
import Tournament from "../Tournament/Tournament";

interface Props {
game: CSGO,
Expand Down Expand Up @@ -72,6 +73,8 @@ export default class Layout extends React.Component<Props, State> {

<SeriesBox map={game.map} phase={game.phase_countdowns} match={match} />

<Tournament />

<Observed player={game.player} />

<TeamBox team={left} players={leftPlayers} side="left" current={game.player} isFreezetime={isFreezetime}/>
Expand Down
137 changes: 137 additions & 0 deletions src/HUD/Styles/tournament.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
.ladder-container {
position: absolute;
margin-left: 50%;
transform: translateX(-50%);
background-color: rgba(0,0,0,0.85);
top: 200px;
opacity: 0;
transition: opacity 1s;
color: white;
}
.ladder-container.show {
opacity:1;
}

.bracket {
display: flex;
justify-content: flex-end;
position: relative;
}
.parent-brackets {
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.empty-bracket {
position: relative;
}
.empty-bracket > .bracket {
padding-right: 240px;
}
.empty-bracket > .connector {
width: 240px;
height: 1px;
top: 50%;
}
.loser-parent-indicator {
position: absolute;
width: 15px;
height: 15px;
left: 5px;

top: calc(50% - 20px);
/*background-image: url('./loser-indicator.png');*/
background-size:contain;
opacity:0.2;
}
.connector {
position: absolute;
right: 0;
height: 50%;
background-color: #ffd700;
width: 1px;
}
.bracket:first-child > .connector {
top: 50%;
}
.bracket:nth-child(2) > .connector, .empty-bracket:nth-child(2) > .bracket > .connector {
top: 0%;
}
.ladder-container > .bracket > .connector {
display: none;
}
.bracket-details .match-details .team-data:first-child {
border-bottom: 1px solid transparent;
}
.match-connector {
width: 100%;
position: absolute;
height: 1px;
background: #ffd700;
}
.match-connector.last-match {
width: 220px;
left:0;
}
.match-connector.first-match {
width: 220px;
right: 0;
}
.bracket-details {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.bracket-details .match-details{
display: flex;
flex-direction: column;
width: 200px;
margin: 10px 20px;
background: rgba(0,0,0,0.5);
border-radius: 2px;
padding: 5px;
z-index: 1;
cursor: pointer;
}
.bracket-details .match-details .team-data {
display: flex;
}
.bracket-details .match-details .team-data .team-name {
flex:1;
display: flex;
align-items: center;
}
.bracket-details .match-details .team-data .team-score {
width: 10px;
display: flex;
align-items: center;
}
.bracket-details .match-details .team-data .team-logo {
width:30px;
height:24px;
display: flex;
align-items: center;
justify-content: center;
}
.bracket-details .match-details .team-data .team-logo img {
height: 20px;
}
.tournament-data img {
max-height: 64px;
}
.tournament-data {
display: flex;
padding: 10px;
align-items: center;
justify-content: center;
}
.tournament-name {
text-transform: uppercase;
font-size: 45px;
padding-left: 22px;
}
.match-details.current {
border: 1px solid gold;
}
145 changes: 145 additions & 0 deletions src/HUD/Tournament/Ladder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import React from 'react';
import * as I from './../../api/interfaces';

interface MatchData {
left: { name: string; score: string | number; logo: string };
right: { name: string; score: string | number; logo: string };
}
interface Props {
tournament: I.Tournament,
matches: I.Match[],
teams: I.Team[]
}

export default class Ladder extends React.Component<Props> {
joinParents = (matchup: I.TournamentMatchup, matchups: I.TournamentMatchup[]) => {
const { tournament } = this.props;
if (!tournament || !matchup) return matchup;

if (matchup.parents.length) return matchup;

const parents = matchups.filter(m => m.winner_to === matchup._id || m.loser_to === matchup._id);
if (!parents.length) return matchup;
matchup.parents.push(...parents.map(parent => this.joinParents(parent, matchups)));

return matchup;
};

copyMatchups = (): I.DepthTournamentMatchup[] => {
if (!this.props.tournament) return [];
const matchups = JSON.parse(JSON.stringify(this.props.tournament.matchups)) as I.DepthTournamentMatchup[];
return matchups;
};

setDepth = (matchups: I.DepthTournamentMatchup[], matchup: I.DepthTournamentMatchup, depth: number, force = false) => {
const getParents = (matchup: I.DepthTournamentMatchup) => {
return matchups.filter(parent => parent.loser_to === matchup._id || parent.winner_to === matchup._id);
};

if (!matchup.depth || force) {
matchup.depth = depth;
getParents(matchup).forEach(matchup => this.setDepth(matchups, matchup, depth + 1));
}
if (matchup.depth <= depth - 1) {
this.setDepth(matchups, matchup, depth - 1, true);
}
return matchup;
};

getMatch = (matchup: I.TournamentMatchup) => {
const { matches } = this.props;
const matchData: MatchData = {
left: { name: 'TBD', score: '-', logo: '' },
right: { name: 'TBD', score: '-', logo: '' }
};
const match = matches.find(match => match.id === matchup.matchId);
if (!match) return matchData;
const teams = [
this.props.teams.find(team => team._id === match.left.id),
this.props.teams.find(team => team._id === match.right.id)
];
if (teams[0]) {
matchData.left.name = teams[0].name;
matchData.left.score = match.left.wins;
matchData.left.logo = teams[0].logo;
}
if (teams[1]) {
matchData.right.name = teams[1].name;
matchData.right.score = match.right.wins;
matchData.right.logo = teams[1].logo;
}
return matchData;
};

renderBracket = (
matchup: I.DepthTournamentMatchup | null | undefined,
depth: number,
fromChildId: string | undefined,
childVisibleParents: number,
isLast = false
) => {
const { tournament, matches } = this.props;
if (!matchup || !tournament) return null;
const match = this.getMatch(matchup);

if (fromChildId === matchup.loser_to) return null;
const parentsToRender = matchup.parents.filter(matchupParent => matchupParent.loser_to !== matchup._id);
if (matchup.depth > depth) {
return (
<div className="empty-bracket">
{this.renderBracket(matchup, depth + 1, fromChildId, parentsToRender.length)}
<div className="connector"></div>
</div>
);
}
const currentMatch = matches.find(mtch => mtch.current);
const isCurrent = currentMatch && currentMatch.id === matchup.matchId;
return (
<div className={`bracket depth-${depth}`}>
<div className="parent-brackets">
{this.renderBracket(matchup.parents[0], depth + 1, matchup._id, parentsToRender.length)}
{this.renderBracket(matchup.parents[1], depth + 1, matchup._id, parentsToRender.length)}
</div>
<div className="bracket-details">
<div
className={`match-connector ${
!matchup.parents.length || parentsToRender.length === 0 ? 'first-match' : ''
} ${isLast ? 'last-match' : ''}`}
></div>
{parentsToRender.length === 1 ? <div className="loser-parent-indicator"></div> : null}
<div className={`match-details ${isCurrent ? 'current':''}`}>
<div className="team-data">
<div className="team-logo">
{match.left.logo ? <img src={match.left.logo} alt="Logo" /> : null}
</div>
<div className="team-name">{match.left.name}</div>
<div className="team-score">{match.left.score}</div>
</div>
<div className="team-data">
<div className="team-logo">
{match.right.logo ? <img src={match.right.logo} alt="Logo" /> : null}
</div>
<div className="team-name">{match.right.name}</div>
<div className="team-score">{match.right.score}</div>
</div>
</div>
</div>

{childVisibleParents === 2 ? (
<div className={`connector amount-${parentsToRender.length}`}></div>
) : null}
</div>
);
};

render() {
const { tournament } = this.props;
if (!tournament) return null;
const matchups = this.copyMatchups();
const gf = matchups.find(matchup => matchup.winner_to === null);
if (!gf) return null;
const joinedParents = this.joinParents(gf, matchups);
const matchupWithDepth = this.setDepth(matchups, joinedParents as I.DepthTournamentMatchup, 0);
return this.renderBracket(matchupWithDepth, 0, undefined, 2, true);
}
}
Loading

0 comments on commit 2ad093f

Please sign in to comment.