import React, { Component } from 'react';
import { connect } from 'react-redux';
import Constants, { SVG_ICONS, GAME_TYPE } from '../../constants';
import { parseCompetitors } from '../../utils/parser';
import SVGComponent from '../../components/SVG/SVGComponent';
import { changePage, setSelectedLeague, resetLiveData } from '../../reducers';
import {
getLeagues, getSelectedLeagueIndex, getSelectedLeague, getGameType, getRoundId, getLiveId,
} from '../../store/bets';
import { getCurrentPage, getUser, getCnt } from '../../store/common';
import {
getScores, getBlink, getLiveCountdown,
} from '../../store/live';
import { getPlacedSelections, getPlacedSelectionsTurbo } from '../../store/placebet';
const mapToProps = (state) => ({
currentPage: getCurrentPage(state),
leagues: getLeagues(state),
selectedLeagueIndex: getSelectedLeagueIndex(state),
selectedLeague: getSelectedLeague(state),
user: getUser(state),
placedSelections: getPlacedSelections(state),
placedSelectionsTurbo: getPlacedSelectionsTurbo(state),
scores: getScores(state),
blink: getBlink(state),
cnt: getCnt(state),
gameType: getGameType(state),
liveCountdown: getLiveCountdown(state),
roundId: getRoundId(state),
liveId: getLiveId(state),
});
const actionsToProps = (dispatch) => ({
changePage: (payload) => dispatch(changePage(payload)),
setSelectedLeague: (payload) => dispatch(setSelectedLeague(payload)),
resetLiveData: (payload) => dispatch(resetLiveData(payload)),
});
/**
* @class
* @property {object} props
* @property {string} props.currentPage Indicate current page
* @property {object} props.selectedLeague Selected league information
* @property {number} props.selectedLeagueIndex Indicate selected league index in leagues array
* @property {object} props.user User information
* @property {Array} props.leagues All leagues information
* @property {Array} props.placedSelections Array of selections showed on My Live page
* @property {Array} props.placedSelectionsTurbo Array of selections Turbo
* showed on My Live page
* @property {string} props.cnt CNT path
*
* @property {Function} props.setSelectedLeague Change selected league
* @property {Function} props.changePage Change page
*/
class Live extends Component {
constructor(props) {
super(props);
/**
* @member {object}
* @property {object} collapsedMatches Key (league-match) indicate is it collapsed or expanded
*/
this.state = {
collapsedMatches: {},
};
this.lastReveal = {};
this.COLOR_ID_CLASSES = {};
this.COLOR_ID_CLASSES[Constants.COLOR_IDS.ALWAYS_LOSE] = 'txt-r';
this.COLOR_ID_CLASSES[Constants.COLOR_IDS.LOSE] = '';
this.COLOR_ID_CLASSES[Constants.COLOR_IDS.WIN] = '';
this.COLOR_ID_CLASSES[Constants.COLOR_IDS.ALWAYS_WIN] = 'txt-g';
}
/**
* Clear all intervals and timeouts
*
* @returns {void}
*/
componentWillUnmount() {
this.props.resetLiveData();
}
/**
* Toggle collapse/expand placed selections
*
* @function
* @param {number} index
* @param {number} leagueId
* @returns {void}
*/
expandSelections = (index, leagueId) => {
if (!this.state.collapsedMatches[`${leagueId}-${index}`]) {
this.state.collapsedMatches[`${leagueId}-${index}`] = true;
} else {
this.state.collapsedMatches[`${leagueId}-${index}`] = false;
}
this.setState({ collapsedMatches: this.state.collapsedMatches });
}
/**
* Render live matches table view depend on current Live page
*
* @function
* @param {Array} liveMatches
* @returns {view}
*/
renderLive = (liveMatches) => {
switch (this.props.currentPage) {
case Constants.PAGES.ALL_LIVE:
return this.props.leagues.map((league) => (league.liveEnabled ? (
league.liveMatches.map((match, ind) => this.renderLiveMatch(match, ind, [], true, league))
) : (null)));
case Constants.PAGES.MY_LIVE: {
const placedSelectionsLive = this.props.gameType === GAME_TYPE.TURBO
? this.props.placedSelectionsTurbo[this.props.liveId]
: this.props.placedSelections[this.props.liveId];
return placedSelectionsLive
&& this.props.leagues.map((league) => (league.liveEnabled ? (
league.liveMatches.map((match, ind) => (placedSelectionsLive[league.id]
&& placedSelectionsLive[league.id][ind]
? this.renderLiveMatch(
match,
ind,
placedSelectionsLive[league.id][ind],
true,
league,
)
: null))
) : (null)));
}
default:
return liveMatches.map((el, ind) => (
this.renderLiveMatch(el, ind, null, false, this.props.selectedLeague)));
}
}
/**
* Render one row view
*
* @function
* @param {string} match
* @param {number} index
* @param {Array} placedSelectionsLive
* @param {boolean} showLeague
* @param {object} league
* @returns {view}
*/
renderLiveMatch = (match, index, placedSelectionsLive, showLeague, league) => {
const teams = parseCompetitors(match);
const HIndex = index * 2;
const AIndex = (index * 2) + 1;
const blink = this.props.blink[league.id] || [];
const score = this.props.scores[league.id] || [];
const totalGoals = parseInt(score[AIndex]) + parseInt(score[HIndex]);
const collapse = this.state.collapsedMatches[`${league.id}-${index}`];
// we are using pulse0, pulse1, reveal0 and reveal1 to fix bad animation of near goals
let reveal = blink[HIndex] === true || blink[AIndex] === true ? ` reveal${totalGoals % 2} ` : ' ';
if (reveal === ' ') {
reveal = this.lastReveal[`${league}-${match}`] || ' ';
} else {
this.lastReveal[`${league}-${match}`] = reveal;
}
const pulseClass = ` pulse${totalGoals % 2} `;
return (
<div
className={`live__matches-row ${showLeague && !collapse ? '' : 'collapsed'}`}
data-toggle="collapse"
href="#match1"
role="button"
onClick={this.expandSelections.bind(this, index, league.id)}
key={match}
>
<div className="live__matches-toggle">
{showLeague && (
<div className="live__matches-league">
<SVGComponent
className="live__matches-team-flag"
src={`${SVG_ICONS.flags}#${league.flag}`}
/>
</div>
)}
<div className={`live__matches-goal ${reveal}`}>
<div className="txt">Goal!</div>
</div>
<div className="live__matches-team home">
<SVGComponent
key={league.id}
className="live__matches-team-flag mr-3"
src={`${SVG_ICONS.shirts}${league.name.toLowerCase().replace(/\s/g, '')}.svg#${league.flag}-${teams[0].toLowerCase()}-home`}
/>
<span className="live__matches-team-name text-right">
{teams[0]}
</span>
</div>
<div className="live__matches-result">
<span className={`${blink[HIndex] === true ? pulseClass : ''}`}>{score[HIndex]}</span>
<span>-</span>
<span className={`${blink[AIndex] === true ? pulseClass : ''}`}>{score[AIndex]}</span>
</div>
<div className="live__matches-team away">
<span className="live__matches-team-name">{teams[1]}</span>
<SVGComponent
key={league.id}
className="live__matches-team-flag ml-3"
src={`${SVG_ICONS.shirts}${league.name.toLowerCase().replace(/\s/g, '')}.svg#${league.flag}-${teams[1].toLowerCase()}-away`}
/>
</div>
{Constants.PAGES.MY_LIVE === this.props.currentPage && (
<div className="live__matches-arrow">
<SVGComponent
className="icon-m"
src={`${SVG_ICONS.utility}#icon__arrow`}
/>
</div>
)}
</div>
{this.renderColapse(placedSelectionsLive, showLeague && !collapse)}
</div>
);
}
/**
* Render placed selections view
*
* @function
* @param {Array} placedSelectionsLive
* @param {boolean} expand
* @returns {view}
*/
renderColapse = (placedSelectionsLive, expand) => (
<div className={`live__matches-content collapse ${expand && 'show'}`} id="match1">
<div className="live__matches-table">
{placedSelectionsLive && placedSelectionsLive.map((selection) => (
<div
className={`live__matches-table-row ${this.COLOR_ID_CLASSES[this.renderUpdatedColorId(selection.colorId)]}`}
key={selection.selection.fullName}
>
<div className="live__matches-odd-name">
{selection.selection.fullName}
</div>
<div className="live__matches-odd-value">
<span>{parseFloat(selection.odd).toFixed(2)}</span>
{this.renderSelctionStatus(selection.colorId)}
</div>
</div>
))}
</div>
</div>
)
/**
* Render updated color id on full time
*
* @function
* @param {number} colorId
* @returns {view}
*/
renderUpdatedColorId = (colorId) => {
let updatedColorId = colorId;
if ((this.props.liveCountdown <= 0 || this.props.liveCountdown === 'FULL TIME')
&& (colorId === Constants.COLOR_IDS.LOSE || colorId === Constants.COLOR_IDS.WIN)) {
updatedColorId += 1;
}
return updatedColorId;
}
/**
* Render selectionStatus
*
* @function
* @param {number} colorId
* @returns {view}
*/
renderSelctionStatus = (colorId) => {
const updatedColorId = this.renderUpdatedColorId(colorId);
switch (updatedColorId) {
case Constants.COLOR_IDS.WIN:
return (<span className="live__matches-status t-win">W</span>);
case Constants.COLOR_IDS.LOSE:
return (<span className="live__matches-status t-lost">L</span>);
case Constants.COLOR_IDS.ALWAYS_WIN:
return (<span className="live__matches-status won">W</span>);
case Constants.COLOR_IDS.ALWAYS_LOSE:
return (<span className="live__matches-status lost">L</span>);
default:
return null;
}
}
/**
* Render
*
* @see module:LiveLeagueNavigation
* @returns {view}
*/
render() {
const liveMatches = this.props.selectedLeague && this.props.selectedLeague.liveMatches;
return (
<div className="scroll-area">
<div className="live">
<div className="live__matches">
{liveMatches ? this.renderLive(liveMatches) : null}
</div>
</div>
</div>
);
}
}
export default connect(
mapToProps,
actionsToProps,
)(Live);