-
+
diff --git a/src/components/Heroes/index.jsx b/src/components/Heroes/index.jsx
index f46a72e3b1..5f34ffd36a 100644
--- a/src/components/Heroes/index.jsx
+++ b/src/components/Heroes/index.jsx
@@ -94,7 +94,7 @@ class RequestLayer extends React.Component {
route: '/heroes/public',
}];
- const tab = heroTabs.find(tab => tab.key.toLowerCase() === route);
+ const tab = heroTabs.find(tab => tab.key === route);
const loading = this.props.loading;
return (
@@ -104,7 +104,7 @@ class RequestLayer extends React.Component {
info={route}
tabs={heroTabs}
/>
- {heroTabs && tab.content(processedData, columns[route])}
+ {tab && tab.content(processedData, columns[route])}
}
);
}
diff --git a/src/components/Matches/Matches.css b/src/components/Matches/Matches.css
index e6a13b442d..325c3ac5c5 100644
--- a/src/components/Matches/Matches.css
+++ b/src/components/Matches/Matches.css
@@ -1 +1,19 @@
@import "../palette.css";
+
+.badge {
+ display: inline-block;
+
+ & svg {
+ width: 10px !important;
+ height: 10px !important;
+ margin-right: 5px;
+ }
+}
+
+.confirmed {
+ composes: badge;
+
+ & svg {
+ fill: var(--colorGolden);
+ }
+}
diff --git a/src/components/Matches/index.jsx b/src/components/Matches/index.jsx
index 588d7702a4..41e72429cd 100644
--- a/src/components/Matches/index.jsx
+++ b/src/components/Matches/index.jsx
@@ -1,15 +1,19 @@
+/* global API_HOST */
import React from 'react';
import { connect } from 'react-redux';
import Helmet from 'react-helmet';
-import { getProMatches } from 'actions';
+import { getProMatches, getPublicMatches } from 'actions';
import strings from 'lang';
import Table, { TableLink } from 'components/Table';
// import Heading from 'components/Heading';
import { transformations } from 'utility';
import subTextStyle from 'components/Visualizations/Table/subText.css';
-import { IconRadiant, IconDire } from 'components/Icons';
+import { IconRadiant, IconDire, IconTrophy } from 'components/Icons';
import matchStyles from 'components/Match/Match.css';
-import Container from 'components/Container';
+import Match from 'components/Match';
+import TabBar from 'components/TabBar';
+import heroes from 'dotaconstants/build/heroes.json';
+import styles from './Matches.css';
const matchesColumns = [{
displayName: strings.th_match_id,
@@ -31,33 +35,114 @@ const matchesColumns = [{
displayName:
{strings.general_radiant},
field: 'radiant_name',
color: matchStyles.green,
+ displayFn: (row, col, field) =>
{row.radiant_win && }{field}
,
}, {
displayName:
{strings.general_dire},
field: 'dire_name',
color: matchStyles.red,
+ displayFn: (row, col, field) =>
{!row.radiant_win && }{field}
,
}];
+const publicMatchesColumns = [
+ {
+ displayName: strings.th_match_id,
+ field: 'match_id',
+ sortFn: true,
+ displayFn: (row, col, field) =>
+
{field}
+
+ {row.avg_mmr} {strings.th_mmr}
+
+
,
+ }, {
+ displayName: strings.th_duration,
+ tooltip: strings.tooltip_duration,
+ field: 'duration',
+ sortFn: true,
+ displayFn: transformations.duration,
+ },
+ {
+ displayName:
{strings.general_radiant},
+ field: 'radiant_team',
+ displayFn: (row, col, field) => (field || '').split(',').map(heroId =>
+
),
+ },
+ {
+ displayName:
{strings.general_dire},
+ field: 'dire_team',
+ displayFn: (row, col, field) => (field || '').split(',').map(heroId =>
+
),
+ },
+];
+
+const matchTabs = [{
+ name: strings.hero_pro_tab,
+ key: 'pro',
+ content: props => (
),
+ route: '/matches/pro',
+}, {
+ name: strings.matches_highest_mmr,
+ key: 'highMmr',
+ content: props => (
),
+ route: '/matches/highMmr',
+}, {
+ name: strings.matches_lowest_mmr,
+ key: 'lowMmr',
+ content: props => (
),
+ route: '/matches/lowMmr',
+}];
+
+const getData = (props) => {
+ props.dispatchProMatches();
+ props.dispatchPublicMatches({ mmr_ascending: props.routeParams.matchId === 'lowMmr' ? '1' : '' });
+};
+
class RequestLayer extends React.Component {
componentDidMount() {
- this.props.dispatchProMatches();
+ getData(this.props);
+ }
+
+ componentWillUpdate(nextProps) {
+ if (this.props.routeParams.matchId !== nextProps.routeParams.matchId) {
+ getData(nextProps);
+ }
}
render() {
+ const route = this.props.routeParams.matchId || 'pro';
+
+ if (Number.isInteger(Number(route))) {
+ return
;
+ }
+
+ const tab = matchTabs.find(tab => tab.key === route);
return (
-
-
-
+
+
+ {tab && tab.content(this.props)}
+
);
}
}
const mapStateToProps = state => ({
- data: state.app.proMatches.list,
+ proData: state.app.proMatches.list,
+ publicData: state.app.publicMatches.list,
loading: state.app.proMatches.loading,
});
const mapDispatchToProps = dispatch => ({
dispatchProMatches: () => dispatch(getProMatches()),
+ dispatchPublicMatches: options => dispatch(getPublicMatches(options)),
});
export default connect(mapStateToProps, mapDispatchToProps)(RequestLayer);
diff --git a/src/components/Player/Pages/Rankings/Rankings.jsx b/src/components/Player/Pages/Rankings/Rankings.jsx
index 2a8c5bf34e..a5d1fa6c07 100644
--- a/src/components/Player/Pages/Rankings/Rankings.jsx
+++ b/src/components/Player/Pages/Rankings/Rankings.jsx
@@ -11,7 +11,7 @@ import playerRankingsColumns from './playerRankingsColumns';
const Rankings = ({ data, error, loading }) => (
diff --git a/src/components/Router/index.jsx b/src/components/Router/index.jsx
index 3bae6c3857..bf9ffc659d 100644
--- a/src/components/Router/index.jsx
+++ b/src/components/Router/index.jsx
@@ -8,7 +8,6 @@ import {
} from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import App from 'components/App';
-import Match from 'components/Match';
import Player from 'components/Player';
import Home from 'components/Home';
import Search from 'components/Search';
@@ -33,8 +32,7 @@ export default () => (
-
-
+
diff --git a/src/lang/en-US.json b/src/lang/en-US.json
index ad818f1928..9bd2ada684 100644
--- a/src/lang/en-US.json
+++ b/src/lang/en-US.json
@@ -330,6 +330,9 @@
"match_first_barracks": "First barracks",
"match_pick": "Pick",
"match_ban": "Ban",
+
+ "matches_highest_mmr": "High MMR",
+ "matches_lowest_mmr": "Low MMR",
"npc_dota_beastmaster_boar_#": "Boar",
"npc_dota_lesser_eidolon": "Eidolon",
@@ -416,7 +419,7 @@
"tab_wardmap": "Wardmap",
"tab_wordcloud": "Wordcloud",
"tab_mmr": "MMR",
- "tab_rankings": "Seasonal Rankings",
+ "tab_rankings": "Rankings",
"tab_benchmarks": "Benchmarks",
"tab_performances": "Performances",
"tab_damage": "Damage",
@@ -551,6 +554,7 @@
"th_party_mmr": "Party MMR",
"th_estimated_mmr": "Estimated MMR",
"th_permanent_buffs": "Buffs",
+ "th_winner": "Winner",
"ward_log_type": "Type",
"ward_log_owner": "Owner",
@@ -584,7 +588,7 @@
"title_default": "OpenDota - Dota 2 Statistics",
"title_template": "%s - OpenDota - Dota 2 Statistics",
- "title_matches": "Professional Matches",
+ "title_matches": "Matches",
"title_request": "Request a Parse",
"title_search": "Search",
"title_status": "Status",
@@ -698,11 +702,7 @@
"xp_reasons_2": "Hero",
"xp_reasons_3": "Roshan",
- "subheading_ranking": "Based on wins and average visible MMR in matches played",
- "teamfight_participation": "Radiant participation/Dire participation",
- "teamfight_score": "Radiant kills/Dire kills",
- "teamfight_radiant_gold_adv": "Net gold advantage for Radiant",
- "teamfight_radiant_xp_adv": "Net XP advantage for Radiant",
+ "rankings_description": "Based on visible MMR in matches won. Resets each quarter.",
"vision_expired": "Expired after",
"vision_destroyed": "Destroyed after",
diff --git a/src/reducers/index.js b/src/reducers/index.js
index b70acc5ac4..0c325965b6 100644
--- a/src/reducers/index.js
+++ b/src/reducers/index.js
@@ -6,6 +6,7 @@ import heroRanking, { getHeroRanking } from 'reducers/heroRanking';
import heroBenchmark, { getHeroBenchmark } from 'reducers/heroBenchmark';
import search from 'reducers/search';
import proPlayers, { getProPlayers } from 'reducers/proPlayers';
+import publicMatches, { getPublicMatches } from 'reducers/publicMatches';
import proMatches, { getProMatches } from 'reducers/proMatches';
import gotPlayer, {
player,
@@ -55,6 +56,7 @@ export {
getLocalization as localization,
pvgnaGuides,
getHeroStats as heroStats,
+ getPublicMatches as publicMatches,
};
export default combineReducers({
@@ -73,4 +75,5 @@ export default combineReducers({
localization,
pvgnaGuides,
heroStats,
+ publicMatches,
});
diff --git a/src/reducers/publicMatches.js b/src/reducers/publicMatches.js
new file mode 100644
index 0000000000..8c0db58893
--- /dev/null
+++ b/src/reducers/publicMatches.js
@@ -0,0 +1,15 @@
+import { publicMatchesActions } from 'actions';
+import { listData, selectors } from './reducerFactory';
+
+const initialState = {
+ loaded: false,
+ error: false,
+ loading: false,
+ list: [],
+};
+
+export default listData(initialState, publicMatchesActions);
+
+export const getPublicMatches = {
+ ...selectors(state => state.app.publicMatches),
+};