mirror of
https://github.com/lexogrine/dota2-react-hud.git
synced 2026-05-04 20:43:10 +02:00
Fixed naming
This commit is contained in:
+17
-168
@@ -1,10 +1,7 @@
|
||||
import React from "react";
|
||||
import * as I from "csgogsi-socket";
|
||||
import * as I from "dotagsi";
|
||||
import "./matchbar.scss";
|
||||
import TeamScore from "./TeamScore";
|
||||
import Bomb from "./../Timers/BombTimer";
|
||||
import Countdown from "./../Timers/Countdown";
|
||||
import { GSI } from "../../App";
|
||||
import { Match } from "../../api/interfaces";
|
||||
|
||||
function stringToClock(time: string | number, pad = true) {
|
||||
@@ -23,179 +20,31 @@ function stringToClock(time: string | number, pad = true) {
|
||||
interface IProps {
|
||||
match: Match | null;
|
||||
map: I.Map;
|
||||
phase: I.PhaseRaw,
|
||||
bomb: I.Bomb | null,
|
||||
players: I.Player[];
|
||||
time: number;
|
||||
}
|
||||
|
||||
export interface Timer {
|
||||
width: number;
|
||||
active: boolean;
|
||||
countdown: number;
|
||||
side: "left"|"right";
|
||||
type: "defusing" | "planting";
|
||||
player: I.Player | null;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
defusing: Timer,
|
||||
planting: Timer,
|
||||
winState: {
|
||||
side: "left"|"right",
|
||||
show: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export default class TeamBox extends React.Component<IProps, IState> {
|
||||
constructor(props: IProps){
|
||||
super(props);
|
||||
this.state = {
|
||||
defusing: {
|
||||
width: 0,
|
||||
active: false,
|
||||
countdown: 10,
|
||||
side: "left",
|
||||
type: "defusing",
|
||||
player: null
|
||||
},
|
||||
planting: {
|
||||
width: 0,
|
||||
active: false,
|
||||
countdown: 10, // Fake
|
||||
side: "right",
|
||||
type: "planting",
|
||||
player: null
|
||||
},
|
||||
winState: {
|
||||
side: 'left',
|
||||
show: false
|
||||
}
|
||||
}
|
||||
}
|
||||
plantStop = () => this.setState(state => {
|
||||
state.planting.active = false;
|
||||
return state;
|
||||
});
|
||||
|
||||
setWidth = (type: 'defusing' | 'planting', width: number) => {
|
||||
this.setState(state => {
|
||||
state[type].width = width;
|
||||
return state;
|
||||
})
|
||||
}
|
||||
|
||||
initPlantTimer = () => {
|
||||
const bomb = new Countdown(time => {
|
||||
let width = time * 100;
|
||||
this.setWidth("planting", width/3);
|
||||
});
|
||||
GSI.on("bombPlantStart", player => {
|
||||
if(!player || !player.team) return;
|
||||
this.setState(state => {
|
||||
state.planting.active = true;
|
||||
state.planting.side = player.team.orientation;
|
||||
state.planting.player = player;
|
||||
})
|
||||
})
|
||||
GSI.on("data", data => {
|
||||
if(!data.bomb || !data.bomb.countdown || data.bomb.state !== "planting") return this.plantStop();
|
||||
this.setState(state => {
|
||||
state.planting.active = true;
|
||||
})
|
||||
return bomb.go(data.bomb.countdown);
|
||||
});
|
||||
}
|
||||
|
||||
defuseStop = () => this.setState(state => {
|
||||
state.defusing.active = false;
|
||||
state.defusing.countdown = 10;
|
||||
return state;
|
||||
});
|
||||
|
||||
initDefuseTimer = () => {
|
||||
const bomb = new Countdown(time => {
|
||||
let width = time > this.state.defusing.countdown ? this.state.defusing.countdown*100 : time * 100;
|
||||
this.setWidth("defusing", width/this.state.defusing.countdown);
|
||||
});
|
||||
GSI.on("defuseStart", player => {
|
||||
if(!player || !player.team) return;
|
||||
this.setState(state => {
|
||||
state.defusing.active = true;
|
||||
state.defusing.countdown = !Boolean(player.state.defusekit) ? 10 : 5;
|
||||
state.defusing.side = player.team.orientation;
|
||||
state.defusing.player = player;
|
||||
return state;
|
||||
})
|
||||
})
|
||||
GSI.on("data", data => {
|
||||
if(!data.bomb || !data.bomb.countdown || data.bomb.state !== "defusing") return this.defuseStop();
|
||||
this.setState(state => {
|
||||
state.defusing.active = true;
|
||||
return state;
|
||||
})
|
||||
return bomb.go(data.bomb.countdown);
|
||||
});
|
||||
}
|
||||
|
||||
resetWin = () => {
|
||||
setTimeout(() => {
|
||||
this.setState(state => {
|
||||
state.winState.show = false;
|
||||
return state;
|
||||
})
|
||||
}, 6000);
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.initDefuseTimer();
|
||||
this.initPlantTimer();
|
||||
GSI.on("roundEnd", score => {
|
||||
this.setState(state => {
|
||||
state.winState.show = true;
|
||||
state.winState.side = score.winner.orientation;
|
||||
return state;
|
||||
}, this.resetWin);
|
||||
});
|
||||
}
|
||||
getRoundLabel = () => {
|
||||
const { map } = this.props;
|
||||
const round = map.round + 1;
|
||||
if (round <= 30) {
|
||||
return `Round ${round}/30`;
|
||||
}
|
||||
const additionalRounds = round - 30;
|
||||
const OT = Math.ceil(additionalRounds/6);
|
||||
return `OT ${OT} (${additionalRounds - (OT - 1)*6}/6)`;
|
||||
}
|
||||
export default class TeamBox extends React.Component<IProps> {
|
||||
render() {
|
||||
const { defusing, planting, winState } = this.state;
|
||||
const { bomb, match, map, phase } = this.props;
|
||||
const time = stringToClock(phase.phase_ends_in);
|
||||
const left = map.team_ct.orientation === "left" ? map.team_ct : map.team_t;
|
||||
const right = map.team_ct.orientation === "left" ? map.team_t : map.team_ct;
|
||||
const isPlanted = bomb && (bomb.state === "defusing" || bomb.state === "planted");
|
||||
const { match, map, players, time } = this.props;
|
||||
const left = map.radiant;
|
||||
const right = map.dire;
|
||||
const bo = (match && Number(match.matchType.substr(-1))) || 0;
|
||||
let leftTimer: Timer | null = null, rightTimer: Timer | null = null;
|
||||
if(defusing.active || planting.active){
|
||||
if(defusing.active){
|
||||
if(defusing.side === "left") leftTimer = defusing;
|
||||
else rightTimer = defusing;
|
||||
} else {
|
||||
if(planting.side === "left") leftTimer = planting;
|
||||
else rightTimer = planting;
|
||||
}
|
||||
}
|
||||
|
||||
const leftScore = players.filter(player => player.team_name === 'radiant').map(player => player.kills).reduce((a, b) => a + b, 0);
|
||||
const rightScore = players.filter(player => player.team_name === 'dire').map(player => player.kills).reduce((a, b) => a + b, 0);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id={`matchbar`}>
|
||||
<TeamScore team={left} orientation={"left"} timer={leftTimer} showWin={winState.show && winState.side === "left"} />
|
||||
<div className={`score left ${left.side}`}>{left.score}</div>
|
||||
<TeamScore team={left} orientation={"left"} type={'radiant'} />
|
||||
<div className={`score left radiant`}>{leftScore}</div>
|
||||
<div id="timer" className={bo === 0 ? 'no-bo' : ''}>
|
||||
<div id={`round_timer_text`} className={isPlanted ? "hide":""}>{time}</div>
|
||||
<div id="round_now" className={isPlanted ? "hide":""}>{this.getRoundLabel()}</div>
|
||||
<Bomb />
|
||||
</div>
|
||||
<div className={`score right ${right.side}`}>{right.score}</div>
|
||||
<TeamScore team={right} orientation={"right"} timer={rightTimer} showWin={winState.show && winState.side === "right"} />
|
||||
<div id={`round_timer_text`}>{stringToClock(time)}</div>
|
||||
</div>
|
||||
<div className={`score right dire`}>{rightScore}</div>
|
||||
<TeamScore team={right} orientation={"right"} type={'dire'} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import React from "react";
|
||||
import * as I from "csgogsi-socket";
|
||||
import * as I from "dotagsi";
|
||||
import { Match } from "../../api/interfaces";
|
||||
|
||||
interface Props {
|
||||
map: I.Map;
|
||||
phase: I.PhaseRaw;
|
||||
match: Match | null;
|
||||
}
|
||||
|
||||
@@ -13,15 +12,15 @@ export default class SeriesBox extends React.Component<Props> {
|
||||
const { match, map } = this.props;
|
||||
const amountOfMaps = (match && Math.floor(Number(match.matchType.substr(-1)) / 2) + 1) || 0;
|
||||
const bo = (match && Number(match.matchType.substr(-1))) || 0;
|
||||
const left = map.team_ct.orientation === "left" ? map.team_ct : map.team_t;
|
||||
const right = map.team_ct.orientation === "left" ? map.team_t : map.team_ct;
|
||||
const left = map.radiant;
|
||||
const right = map.dire;
|
||||
return (
|
||||
<div id="encapsulator">
|
||||
<div className="container left">
|
||||
<div className={`series_wins left `}>
|
||||
<div className={`wins_box_container`}>
|
||||
{new Array(amountOfMaps).fill(0).map((_, i) => (
|
||||
<div key={i} className={`wins_box ${left.matches_won_this_series > i ? "win" : ""} ${left.side}`} />
|
||||
<div key={i} className={`wins_box ${left.map_score > i ? "win" : ""} radiant`} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,7 +32,7 @@ export default class SeriesBox extends React.Component<Props> {
|
||||
<div className={`series_wins right `}>
|
||||
<div className={`wins_box_container`}>
|
||||
{new Array(amountOfMaps).fill(0).map((_, i) => (
|
||||
<div key={i} className={`wins_box ${right.matches_won_this_series > i ? "win" : ""} ${right.side}`} />
|
||||
<div key={i} className={`wins_box ${right.map_score > i ? "win" : ""} dire`} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Team } from 'csgogsi-socket';
|
||||
import { Team } from 'dotagsi';
|
||||
import * as I from '../../api/interfaces';
|
||||
import { apiUrl } from './../../api/api';
|
||||
|
||||
|
||||
@@ -1,29 +1,22 @@
|
||||
import React from "react";
|
||||
import * as I from "csgogsi-socket";
|
||||
import WinIndicator from "./WinIndicator";
|
||||
import { Timer } from "./MatchBar";
|
||||
import * as I from "dotagsi";
|
||||
import TeamLogo from './TeamLogo';
|
||||
import PlantDefuse from "../Timers/PlantDefuse"
|
||||
|
||||
interface IProps {
|
||||
team: I.Team;
|
||||
orientation: "left" | "right";
|
||||
timer: Timer | null;
|
||||
showWin: boolean;
|
||||
type: I.Faction
|
||||
}
|
||||
|
||||
export default class TeamScore extends React.Component<IProps> {
|
||||
render() {
|
||||
const { orientation, timer, team, showWin } = this.props;
|
||||
const { orientation, team, type } = this.props;
|
||||
return (
|
||||
<>
|
||||
<div className={`team ${orientation} ${team.side}`}>
|
||||
<div className={`team ${orientation} ${type}`}>
|
||||
<div className="team-name">{team.name}</div>
|
||||
<TeamLogo team={team} />
|
||||
<div className="round-thingy"><div className="inner"></div></div>
|
||||
</div>
|
||||
<PlantDefuse timer={timer} side={orientation} />
|
||||
<WinIndicator team={team} show={showWin}/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Team } from 'csgogsi-socket';
|
||||
|
||||
export default class WinAnnouncement extends React.Component<{ team: Team | null, show: boolean }> {
|
||||
render() {
|
||||
const { team, show } = this.props;
|
||||
if(!team) return null;
|
||||
return <div className={`win_text ${show ? 'show' : ''} ${team.orientation} ${team.side}`}>
|
||||
WINS THE ROUND!
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -24,36 +24,18 @@
|
||||
width: 1148px;
|
||||
height: 70px;
|
||||
top: 10px;
|
||||
color: white;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
.CT {
|
||||
color: var(--color-new-ct);
|
||||
.round-thingy {
|
||||
.inner {
|
||||
background-color: #28abff;
|
||||
}
|
||||
background-color: #28abff80;
|
||||
}
|
||||
}
|
||||
.T {
|
||||
color: var(--color-new-t);
|
||||
.round-thingy {
|
||||
.inner {
|
||||
background-color: #ffc600;
|
||||
}
|
||||
background-color: #ffc60080;
|
||||
}
|
||||
}
|
||||
|
||||
#timer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
width: 126px;
|
||||
height: 115px;
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
background-color: var(--sub-panel-color);
|
||||
top: -10px;
|
||||
&.no-bo {
|
||||
height: 87px;
|
||||
}
|
||||
@@ -200,84 +182,10 @@
|
||||
flex-direction: row;
|
||||
width: 10px;
|
||||
height: 70px;
|
||||
&.CT {
|
||||
background-color: var(--color-new-ct);
|
||||
}
|
||||
&.T {
|
||||
background-color: var(--color-new-t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.win_text {
|
||||
position: fixed;
|
||||
display: none;
|
||||
opacity: 1;
|
||||
width: 503px;
|
||||
height: 50px;
|
||||
top: 70px;
|
||||
align-items: center;
|
||||
color: black;
|
||||
justify-content: center;
|
||||
background-color: white;
|
||||
font-size: 20px;
|
||||
font-family: Montserrat;
|
||||
font-weight: 600;
|
||||
&.show {
|
||||
display: flex;
|
||||
animation: ShowWinCycle 5s linear 1;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&.right {
|
||||
left: calc(50% + 71px);
|
||||
}
|
||||
&.left {
|
||||
right: calc(50% + 71px);
|
||||
}
|
||||
}
|
||||
|
||||
.defuse_plant_container {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
opacity: 1;
|
||||
width: 503px;
|
||||
height: 49px;
|
||||
top: 70px;
|
||||
align-items: center;
|
||||
color: white;
|
||||
justify-content: center;
|
||||
background-color: rgba(0,0,0,0.65);
|
||||
.defuse_plant_bar {
|
||||
height: 49px;
|
||||
background-color: #3c3c3c;
|
||||
position: absolute;
|
||||
width: 0%;
|
||||
}
|
||||
.defuse_plant_caption {
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
text-transform: uppercase;
|
||||
align-items: flex-end;
|
||||
svg {
|
||||
margin-right: 13px;
|
||||
}
|
||||
}
|
||||
&.right {
|
||||
left: calc(50% + 71px);
|
||||
.defuse_plant_bar {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
&.left {
|
||||
right: calc(50% + 71px);
|
||||
.defuse_plant_bar {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
&.hide {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
#encapsulator {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
@@ -289,31 +197,16 @@
|
||||
height: 50px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
.CT {
|
||||
color: var(--color-new-ct);
|
||||
}
|
||||
.T {
|
||||
color: var(--color-new-t);
|
||||
}
|
||||
|
||||
.wins_bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 10px;
|
||||
height: 30px;
|
||||
}
|
||||
.wins_bar.CT {
|
||||
background-color: var(--color-new-ct);
|
||||
}
|
||||
.wins_bar.T {
|
||||
background-color: var(--color-new-t);
|
||||
}
|
||||
}
|
||||
.alert_bar.CT {
|
||||
background-color: var(--color-new-ct);
|
||||
}
|
||||
.alert_bar.T {
|
||||
background-color: var(--color-new-t);
|
||||
|
||||
}
|
||||
|
||||
#series_container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -376,16 +269,8 @@
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.wins_box.CT {
|
||||
background-color: rgba(0,0,0,0.6);
|
||||
}
|
||||
.wins_box.CT.win {
|
||||
background-color: var(--color-new-ct);
|
||||
}
|
||||
.wins_box.T {
|
||||
background-color: rgba(0,0,0,0.6);
|
||||
}
|
||||
.wins_box.T.win {
|
||||
background-color: var(--color-new-t);
|
||||
background-color:rgba(0,0,0,0.25);
|
||||
&.win {
|
||||
background-color: rgba(255,255,255,1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user