diff --git a/client/src/assets/css/match.css b/client/src/assets/css/match.css index 045afe8..bd9f24a 100644 --- a/client/src/assets/css/match.css +++ b/client/src/assets/css/match.css @@ -22,4 +22,31 @@ rgba(44, 82, 130, 0) 45% ); } + +.ban::after { + content: ""; + position: absolute; + left: 0px; + top: 50%; + width: calc(100% + 1px); + height: 2px; + transform: rotate(-45deg); +} + +.ban-blue::after { + background: #38b2ac; +} + +.ban-red::after { + background: #f56565; +} + +.ban-img { + filter: grayscale(100%); +} + +.ban-order { + left: -7px; + top: -5px; +} /* purgecss end ignore */ diff --git a/client/src/components/Match/DetailedMatchGlobalStats.vue b/client/src/components/Match/DetailedMatchGlobalStats.vue index 16ec5c1..3b90eff 100644 --- a/client/src/components/Match/DetailedMatchGlobalStats.vue +++ b/client/src/components/Match/DetailedMatchGlobalStats.vue @@ -104,32 +104,3 @@ export default { } } - - diff --git a/client/src/components/Match/LiveMatch.vue b/client/src/components/Match/LiveMatch.vue index 70d2fab..8518a9c 100644 --- a/client/src/components/Match/LiveMatch.vue +++ b/client/src/components/Match/LiveMatch.vue @@ -51,46 +51,10 @@ diff --git a/client/src/components/Summoner/Live/LiveTeam.vue b/client/src/components/Summoner/Live/LiveTeam.vue new file mode 100644 index 0000000..f5ef22e --- /dev/null +++ b/client/src/components/Summoner/Live/LiveTeam.vue @@ -0,0 +1,226 @@ + + + + + diff --git a/client/src/helpers/summoner.js b/client/src/helpers/summoner.js index 666408a..e181c33 100644 --- a/client/src/helpers/summoner.js +++ b/client/src/helpers/summoner.js @@ -92,7 +92,7 @@ export function getRankImg(leagueData) { return `https://res.cloudinary.com/kln/image/upload/v1571671133/ranks/${leagueData.tier}_${leaguesNumbers[leagueData.rank]}.png` } -function getSummonerLink(id) { +export function getSummonerLink(id) { if (id === 0) return null const spellName = summonersJSON.find(s => s.id === id).iconPath.split('/assets/')[1].toLowerCase() return `https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/${spellName}` diff --git a/client/src/layouts/Default.vue b/client/src/layouts/Default.vue index 90e8e9d..72d9fd7 100644 --- a/client/src/layouts/Default.vue +++ b/client/src/layouts/Default.vue @@ -78,6 +78,11 @@ class="ml-4 pb-2 border-b-2 border-transparent text-blue-300 cursor-pointer hover:text-blue-100" exact >records + live game diff --git a/client/src/mixins/liveGame.js b/client/src/mixins/liveGame.js new file mode 100644 index 0000000..6b8b3a6 --- /dev/null +++ b/client/src/mixins/liveGame.js @@ -0,0 +1,42 @@ +import { compareSummonernames } from '@/helpers/functions.js' +import { gameModes } from '@/data/data.js' +import { mapState } from 'vuex' + +export const liveGame = { + data() { + return { + gameLength: 0 + } + }, + + computed: { + allyTeam() { + return this.current.participants.filter(p => p.teamId === this.teamColor) + }, + enemyTeam() { + return this.current.participants.filter(p => p.teamId !== this.teamColor) + }, + gamemode() { + return gameModes[this.current.gameQueueConfigId] + }, + teamColor() { + return this.current.participants.find(p => p.summonerId === this.account.id).teamId + }, + ...mapState({ + account: state => state.summoner.basic.account, + current: state => state.summoner.basic.current, + }) + }, + + created() { + this.gameLength = this.current ? this.current.gameLength : 0 + + setInterval(() => { + this.gameLength++ + }, 1000) + }, + + methods: { + compareSummonernames, + } +} diff --git a/client/src/router.js b/client/src/router.js index 90d422a..7b78ea4 100644 --- a/client/src/router.js +++ b/client/src/router.js @@ -5,6 +5,7 @@ import { axios } from './plugins/axios' import Home from '@/views/Home.vue' import Summoner from '@/views/Summoner.vue' import SummonerChampions from '@/views/SummonerChampions.vue' +import SummonerLive from '@/views/SummonerLive.vue' import SummonerRecords from '@/views/SummonerRecords.vue' Vue.use(Router) @@ -36,6 +37,11 @@ const router = new Router({ name: 'summonerRecords', component: SummonerRecords }, + { + path: '/summoner/:region/:name/live', + name: 'summonerLive', + component: SummonerLive + }, ] }) diff --git a/client/src/store/modules/summoner.js b/client/src/store/modules/summoner.js index 139b7cc..bc8aa4d 100644 --- a/client/src/store/modules/summoner.js +++ b/client/src/store/modules/summoner.js @@ -27,6 +27,10 @@ export const state = { list: [], recordsLoaded: false }, + live: { + match: {}, + liveLoaded: false + }, } export const mutations = { @@ -43,6 +47,10 @@ export const mutations = { state.champions.list = champions state.champions.championsLoaded = true }, + LIVE_FOUND(state, { live }) { + state.live.match = live + state.live.liveLoaded = true + }, MATCHES_LOADING(state) { state.overview.matchesLoading = true }, @@ -114,6 +122,13 @@ export const actions = { commit('CHAMPIONS_FOUND', { champions: resp.data }) }, + async liveMatchRequest({ commit, rootState }) { + const resp = await axios(({ url: 'summoner-live', data: { account: state.basic.account, region: rootState.currentRegion }, method: 'POST' })).catch(() => { }) + console.log('---LIVE---') + console.log(resp.data) + + commit('LIVE_FOUND', { live: resp.data }) + }, async moreMatches({ commit }) { commit('MATCHES_LOADING') diff --git a/client/src/views/SummonerLive.vue b/client/src/views/SummonerLive.vue new file mode 100644 index 0000000..633eeea --- /dev/null +++ b/client/src/views/SummonerLive.vue @@ -0,0 +1,75 @@ + + + diff --git a/server/app/Controllers/Http/SummonerController.js b/server/app/Controllers/Http/SummonerController.js index 87336df..4804aac 100644 --- a/server/app/Controllers/Http/SummonerController.js +++ b/server/app/Controllers/Http/SummonerController.js @@ -1,6 +1,7 @@ 'use strict' const Jax = use('Jax') +const LiveMatchTransformer = use('App/Transformers/LiveMatchTransformer') const MatchRepository = make('App/Repositories/MatchRepository') const MatchService = use('App/Services/MatchService') const SummonerService = use('App/Services/SummonerService') @@ -115,6 +116,27 @@ class SummonerController { console.timeEnd('recordsRequest') return response.json(records[0]) } + + /** + * POST - Return live match details + */ + async liveMatchDetails({ request, response }) { + console.time('liveMatchDetails') + const account = request.input('account') + const region = request.input('region') + + // CURRENT GAME + let currentGame = await Jax.Spectator.summonerID(account.id, region) + + if (!currentGame) { + response.json(null) + } + + currentGame = await LiveMatchTransformer.transform(currentGame, { region }) + console.timeEnd('liveMatchDetails') + + return response.json(currentGame) + } } module.exports = SummonerController diff --git a/server/app/Transformers/LiveMatchTransformer.js b/server/app/Transformers/LiveMatchTransformer.js new file mode 100644 index 0000000..7433d68 --- /dev/null +++ b/server/app/Transformers/LiveMatchTransformer.js @@ -0,0 +1,44 @@ +'use strict' + +const MatchTransformer = use('App/Transformers/MatchTransformer') +const SummonerService = use('App/Services/SummonerService') + +/** + * LiveMatchTransformer class + * + * @class LiveMatchTransformer + */ +class LiveMatchTransformer extends MatchTransformer { + async _getPlayerDatq(participant, region) { + const account = await SummonerService.getAccount(participant.summonerName, region) + if (account) { + participant.level = account.summonerLevel + const ranked = await SummonerService.getRanked(account, region) + participant.rank = ranked + } else { + participant.rank = null + } + + return participant + } + + /** + * Transform raw data from Riot API + * @param match data from Riot API, one live match + */ + async transform(match, { region }) { + await super.getContext() + + // Perks + for (const participant of match.participants) { + participant.runes = super.getPerksImages(participant.perks.perkIds[0], participant.perks.perkSubStyle) + } + + const requestsParticipants = match.participants.map(p => this._getPlayerDatq(p, region)) + match.participants = await Promise.all(requestsParticipants) + + return match + } +} + +module.exports = new LiveMatchTransformer() diff --git a/server/app/Transformers/MatchTransformer.js b/server/app/Transformers/MatchTransformer.js index 4741fcc..b8782ac 100644 --- a/server/app/Transformers/MatchTransformer.js +++ b/server/app/Transformers/MatchTransformer.js @@ -111,13 +111,7 @@ class MatchTransformer { let primaryRune = null let secondaryRune = null if (player.stats.perkPrimaryStyle) { - const firstRune = this.perks.find(p => p.id === player.stats.perk0) - const firstRuneUrl = firstRune.iconPath.split('/assets/')[1].toLowerCase() - primaryRune = `https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/${firstRuneUrl}` - - const secondRuneStyle = this.perkstyles.find(p => p.id === player.stats.perkSubStyle) - const secondRuneStyleUrl = secondRuneStyle.iconPath.split('/assets/')[1].toLowerCase() - secondaryRune = `https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/${secondRuneStyleUrl}` + ({ primaryRune, secondaryRune } = this.getPerksImages(player.stats.perk0, player.stats.perkSubStyle)) } const items = [] @@ -157,6 +151,23 @@ class MatchTransformer { } } + /** + * Return the icons of the primary rune and secondary category + * @param perk0 primary perks id + * @param perkSubStyle secondary perks category + */ + getPerksImages(perk0, perkSubStyle) { + const firstRune = this.perks.find(p => p.id === perk0) + const firstRuneUrl = firstRune.iconPath.split('/assets/')[1].toLowerCase() + const primaryRune = `https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/${firstRuneUrl}` + + const secondRuneStyle = this.perkstyles.find(p => p.id === perkSubStyle) + const secondRuneStyleUrl = secondRuneStyle.iconPath.split('/assets/')[1].toLowerCase() + const secondaryRune = `https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/${secondRuneStyleUrl}` + + return { primaryRune, secondaryRune } + } + /** * Return the lane of the summoner according to timeline * @param timeline from Riot Api diff --git a/server/start/routes.js b/server/start/routes.js index 3aadc76..6492e87 100644 --- a/server/start/routes.js +++ b/server/start/routes.js @@ -29,6 +29,7 @@ Route.post('/summoner-basic', 'SummonerController.basic') Route.post('/summoner-overview', 'SummonerController.overview') Route.post('/summoner-champions', 'SummonerController.champions') Route.post('/summoner-records', 'SummonerController.records') +Route.post('/summoner-live', 'SummonerController.liveMatchDetails') Route.post('/ddragon', 'DDragonController.index') Route.post('/match', 'MatchController.index') Route.post('/match-details', 'MatchController.show')