refactor: make api call only when needed for each view

This commit is contained in:
Valentin Kaelin 2019-12-27 18:38:43 +01:00
parent cecd6115a0
commit 526611a517
10 changed files with 154 additions and 119 deletions

View file

@ -105,7 +105,7 @@ export default {
return this.stats.champion.reduce((a, b) => a.count > b.count ? a : b).count return this.stats.champion.reduce((a, b) => a.count > b.count ? a : b).count
}, },
...mapState({ ...mapState({
stats: state => state.summoner.infos.stats stats: state => state.summoner.overview.stats
}), }),
}, },

View file

@ -82,7 +82,7 @@ export default {
return this.mates.length > 0 return this.mates.length > 0
}, },
...mapState({ ...mapState({
mates: state => state.summoner.infos.stats.mates mates: state => state.summoner.overview.stats.mates
}), }),
}, },

View file

@ -248,7 +248,7 @@ export default {
return rest return rest
}, },
...mapState({ ...mapState({
stats: state => state.summoner.infos.stats stats: state => state.summoner.overview.stats
}), }),
}, },

View file

@ -15,7 +15,7 @@ export function createMatchData(matches) {
const date = new Date(match.date) const date = new Date(match.date)
const dateOptions = { day: '2-digit', month: '2-digit', year: 'numeric' } const dateOptions = { day: '2-digit', month: '2-digit', year: 'numeric' }
const timeOptions = { hour12: false, hour: '2-digit', minute:'2-digit' } const timeOptions = { hour12: false, hour: '2-digit', minute: '2-digit' }
match.fullDate = { date: date.toLocaleString('fr', dateOptions), time: date.toLocaleString('fr', timeOptions) } match.fullDate = { date: date.toLocaleString('fr', dateOptions), time: date.toLocaleString('fr', timeOptions) }
match.date = timeDifference(match.date) match.date = timeDifference(match.date)
@ -28,10 +28,10 @@ export function createMatchData(matches) {
} }
/** /**
* Return all the infos about a summoner built with the Riot API data * Return the basic infos about a summoner built with the Riot API data
* @param {Object} RiotData : all data from the Riot API * @param {Object} RiotData : all data from the Riot API
*/ */
export function createSummonerData(RiotData) { export function createBasicSummonerData(RiotData) {
// Ranked Stats // Ranked Stats
RiotData.ranked.soloQ = getLeagueData(RiotData.ranked.soloQ, 'Solo/Duo') RiotData.ranked.soloQ = getLeagueData(RiotData.ranked.soloQ, 'Solo/Duo')
if (!RiotData.ranked.soloQ) delete RiotData.ranked.soloQ if (!RiotData.ranked.soloQ) delete RiotData.ranked.soloQ
@ -57,11 +57,9 @@ export function createSummonerData(RiotData) {
return { return {
account: RiotData.account, account: RiotData.account,
ranked: RiotData.ranked,
matchList: RiotData.allMatches, matchList: RiotData.allMatches,
matches: createMatchData(RiotData.matchesDetails), ranked: RiotData.ranked,
playing: RiotData.playing, playing: RiotData.playing,
stats: RiotData.stats,
} }
} }
@ -82,7 +80,7 @@ export function getRankImg(leagueData) {
} }
function getSummonerLink(id) { function getSummonerLink(id) {
if(id === 0) return null if (id === 0) return null
const spellName = summonersJSON.find(s => s.id === id).iconPath.split('/assets/')[1].toLowerCase() 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}` return `https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/${spellName}`
} }

View file

@ -24,8 +24,8 @@
<div> <div>
<div class="flex items-center"> <div class="flex items-center">
<h1 class="text-4xl font-extrabold uppercase"> <h1 class="text-4xl font-extrabold uppercase">
<span class="text-5xl">{{ summonerInfos.account.name[0] }}</span> <span class="text-5xl">{{ basic.account.name[0] }}</span>
<span>{{ summonerInfos.account.name.substring(1) }}</span> <span>{{ basic.account.name.substring(1) }}</span>
</h1> </h1>
<div <div
v-if="playing" v-if="playing"
@ -40,23 +40,23 @@
<div <div
:class="{'border-2': !playing}" :class="{'border-2': !playing}"
class="relative z-10 w-24 h-24 rounded-full bg-blue-1000 bg-center bg-cover border-teal-400" class="relative z-10 w-24 h-24 rounded-full bg-blue-1000 bg-center bg-cover border-teal-400"
:style="{backgroundImage: `url('https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/v1/profile-icons/${summonerInfos.account.profileIconId}.jpg')`}" :style="{backgroundImage: `url('https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/v1/profile-icons/${basic.account.profileIconId}.jpg')`}"
> >
<div <div
class="absolute left-0 bottom-0 w-8 h-8 flex items-center justify-center bg-blue-900 rounded-full text-xs text-teal-500 font-extrabold border-2 border-teal-400" class="absolute left-0 bottom-0 w-8 h-8 flex items-center justify-center bg-blue-900 rounded-full text-xs text-teal-500 font-extrabold border-2 border-teal-400"
>{{ summonerInfos.account.summonerLevel }}</div> >{{ basic.account.summonerLevel }}</div>
</div> </div>
</div> </div>
<SummonerRanked <SummonerRanked
v-if="Object.entries(summonerInfos.ranked).length !== 0" v-if="Object.entries(basic.ranked).length !== 0"
:ranked="summonerInfos.ranked" :ranked="basic.ranked"
/> />
</div> </div>
</div> </div>
<div> <div>
<RecentActivity :matches="summonerInfos.matchList" /> <RecentActivity :matches="basic.matchList" />
</div> </div>
</div> </div>
<!-- NAVIGATION --> <!-- NAVIGATION -->
@ -128,7 +128,7 @@ export default {
return `${this.summoner}|${this.region}` return `${this.summoner}|${this.region}`
}, },
...mapState({ ...mapState({
summonerInfos: state => state.summoner.infos basic: state => state.summoner.basic
}), }),
...mapGetters('summoner', ['playing', 'summonerFound', 'summonerNotFound', 'summonerLoading']) ...mapGetters('summoner', ['playing', 'summonerFound', 'summonerNotFound', 'summonerLoading'])
}, },
@ -148,13 +148,13 @@ export default {
methods: { methods: {
apiCall() { apiCall() {
this.summonerRequest({ summoner: this.summoner, region: this.region }) this.basicRequest({ summoner: this.summoner, region: this.region })
}, },
redirect(summoner, region) { redirect(summoner, region) {
this.$router.push(`/summoner/${region}/${summoner}`) this.$router.push(`/summoner/${region}/${summoner}`)
}, },
...mapActions(['updateCurrentRegion']), ...mapActions(['updateCurrentRegion']),
...mapActions('summoner', ['summonerRequest']), ...mapActions('summoner', ['basicRequest']),
} }
} }
</script> </script>

View file

@ -1,96 +1,76 @@
import { axios } from '@/plugins/axios' import { axios } from '@/plugins/axios'
import { createMatchData, createSummonerData } from '@/helpers/summoner' import { createMatchData, createBasicSummonerData } from '@/helpers/summoner'
export const namespaced = true export const namespaced = true
export const state = { export const state = {
infos: { basic: {
account: {}, account: {},
champions: [],
matchIndex: 0,
matchList: [], matchList: [],
matches: [],
mates: [],
ranked: {}, ranked: {},
stats: {}, playing: false,
playing: false
},
championsLoaded: false,
matchesLoading: false,
status: '', status: '',
},
overview: {
matchIndex: 0,
matches: [],
stats: {},
loaded: false,
matchesLoading: false,
},
champions: {
list: [],
championsLoaded: false
},
} }
export const mutations = { export const mutations = {
BASIC_REQUEST(state) {
state.basic.status = 'loading'
},
CHAMPIONS_FOUND(state, { champions }) { CHAMPIONS_FOUND(state, { champions }) {
state.infos.champions = champions state.champions.list = champions
state.championsLoaded = true state.champions.championsLoaded = true
}, },
MATCHES_LOADING(state) { MATCHES_LOADING(state) {
state.matchesLoading = true state.overview.matchesLoading = true
}, },
MATCHES_FOUND(state, { newMatches, stats }) { MATCHES_FOUND(state, { newMatches, stats }) {
state.matchesLoading = false state.overview.matchesLoading = false
state.overview.matches = [...state.infos.matches, ...newMatches]
state.infos.matches = [...state.infos.matches, ...newMatches] state.overview.matchIndex += newMatches.length
state.overview.stats = stats
state.infos.matchIndex += newMatches.length state.champions.championsLoaded = false
state.infos.stats = stats
state.championsLoaded = false
}, },
SUMMONER_REQUEST(state) { OVERVIEW_FOUND(state, infos) {
state.status = 'loading' state.overview.matches = infos.matches
state.overview.matchIndex = infos.matches.length
state.overview.stats = infos.stats
state.overview.loaded = true
}, },
SUMMONER_FOUND(state, infos) { SUMMONER_FOUND(state, infos) {
state.infos.account = infos.account state.basic.account = infos.account
state.infos.matchList = infos.matchList state.basic.matchList = infos.matchList
state.infos.matches = infos.matches state.basic.ranked = infos.ranked
state.infos.ranked = infos.ranked state.basic.playing = infos.playing
state.infos.matchIndex = infos.matches.length state.basic.status = 'found'
state.infos.playing = infos.playing state.champions.championsLoaded = false
state.infos.stats = infos.stats
state.status = 'found'
state.championsLoaded = false
}, },
SUMMONER_NOT_FOUND(state) { SUMMONER_NOT_FOUND(state) {
state.status = 'error' state.basic.status = 'error'
} },
} }
export const actions = { export const actions = {
async championStats({ commit }, queue = null) { async basicRequest({ commit, dispatch, rootState }, { summoner, region }) {
if (Number(queue) === -1)
queue = null
const resp = await axios(({ url: 'champions', data: { puuid: state.infos.account.puuid, queue: queue }, method: 'POST' })).catch(() => { })
console.log('CHAMPIONS STATS')
console.log('queue: ', queue)
console.log(resp.data)
commit('CHAMPIONS_FOUND', { champions: resp.data })
},
async moreMatches({ commit }) {
commit('MATCHES_LOADING')
const account = state.infos.account
const gameIds = state.infos.matchList.slice(state.infos.matchIndex, state.infos.matchIndex + 10).map(({ gameId }) => gameId)
const resp = await axios(({ url: 'match', data: { account, gameIds }, method: 'POST' })).catch(() => { })
console.log('--- MATCHES INFOS ---')
console.log(resp.data)
const newMatches = createMatchData(resp.data.matches)
commit('MATCHES_FOUND', { newMatches, stats: resp.data.stats })
},
async summonerRequest({ commit, dispatch, rootState }, { summoner, region }) {
region = rootState.regionsList[region] region = rootState.regionsList[region]
commit('SUMMONER_REQUEST') commit('BASIC_REQUEST')
try { try {
const resp = await axios(({ url: 'api', data: { summoner, region }, method: 'POST' })) const resp = await axios(({ url: 'summoner-basic', data: { summoner, region }, method: 'POST' }))
if (resp.data) { if (resp.data) {
console.log('--- SUMMONER INFOS ---') console.log('--- SUMMONER INFOS ---')
console.log(resp.data) console.log(resp.data)
dispatch('ddragon/getVersion', resp.data.version, { root: true }) const infos = createBasicSummonerData(resp.data)
const infos = createSummonerData(resp.data)
commit('SUMMONER_FOUND', infos) commit('SUMMONER_FOUND', infos)
} else { } else {
commit('SUMMONER_NOT_FOUND') commit('SUMMONER_NOT_FOUND')
@ -105,14 +85,42 @@ export const actions = {
commit('SUMMONER_NOT_FOUND') commit('SUMMONER_NOT_FOUND')
console.log(error) console.log(error)
} }
},
async championStats({ commit }, queue = null) {
const resp = await axios(({ url: 'summoner-champions', data: { puuid: state.basic.account.puuid, queue: queue }, method: 'POST' })).catch(() => { })
console.log('CHAMPIONS STATS')
console.log('queue: ', queue)
console.log(resp.data)
commit('CHAMPIONS_FOUND', { champions: resp.data })
},
async moreMatches({ commit }) {
commit('MATCHES_LOADING')
const account = state.basic.account
const gameIds = state.basic.matchList.slice(state.overview.matchIndex, state.overview.matchIndex + 10).map(({ gameId }) => gameId)
const resp = await axios(({ url: 'match', data: { account, gameIds }, method: 'POST' })).catch(() => { })
console.log('--- MATCHES INFOS ---')
console.log(resp.data)
const newMatches = createMatchData(resp.data.matches)
commit('MATCHES_FOUND', { newMatches, stats: resp.data.stats })
},
async overviewRequest({ commit }) {
const resp = await axios(({ url: 'summoner-overview', data: { account: state.basic.account }, method: 'POST' })).catch(() => { })
console.log('OVERVIEW')
console.log(resp.data)
resp.data.matches = createMatchData(resp.data.matchesDetails)
commit('OVERVIEW_FOUND', resp.data)
} }
} }
export const getters = { export const getters = {
matchesLoading: state => state.matchesLoading, matchesLoading: state => state.overview.matchesLoading,
moreMatchesToFetch: state => state.infos.matchIndex < state.infos.matchList.length, moreMatchesToFetch: state => state.overview.matchIndex < state.basic.matchList.length,
playing: state => state.infos.playing, overviewLoaded: state => state.overview.loaded,
summonerFound: state => state.status === 'found', playing: state => state.basic.playing,
summonerNotFound: state => state.status === 'error', summonerFound: state => state.basic.status === 'found',
summonerLoading: state => state.status === 'loading', summonerNotFound: state => state.basic.status === 'error',
summonerLoading: state => state.basic.status === 'loading',
} }

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="mt-3 flex text-center"> <div v-if="overviewLoaded" class="mt-3 flex text-center">
<div class="mt-4 w-3/12"> <div class="mt-4 w-3/12">
<SummonerChampions /> <SummonerChampions />
<SummonerStats /> <SummonerStats />
@ -8,9 +8,9 @@
<div class="w-9/12"> <div class="w-9/12">
<ul> <ul>
<Match <Match
v-for="(match, index) in summonerInfos.matches" v-for="(match, index) in overview.matches"
:key="index" :key="index"
:data="summonerInfos.matches[index]" :data="overview.matches[index]"
/> />
</ul> </ul>
<LoadingButton <LoadingButton
@ -43,13 +43,17 @@ export default {
computed: { computed: {
...mapState({ ...mapState({
summonerInfos: state => state.summoner.infos overview: state => state.summoner.overview
}), }),
...mapGetters('summoner', ['matchesLoading', 'moreMatchesToFetch']) ...mapGetters('summoner', ['matchesLoading', 'moreMatchesToFetch', 'overviewLoaded'])
},
created() {
this.overviewRequest()
}, },
methods: { methods: {
...mapActions('summoner', ['moreMatches']), ...mapActions('summoner', ['moreMatches', 'overviewRequest']),
} }
} }
</script> </script>

View file

@ -54,9 +54,9 @@ export default {
return { '-1': { type: 'Normal', name: 'ALL QUEUES' }, ...queues } return { '-1': { type: 'Normal', name: 'ALL QUEUES' }, ...queues }
}, },
...mapState({ ...mapState({
champions: state => state.summoner.infos.champions, champions: state => state.summoner.champions.list,
championsLoaded: state => state.summoner.championsLoaded, championsLoaded: state => state.summoner.champions.championsLoaded,
matchList: state => state.summoner.infos.matchList matchList: state => state.summoner.basic.matchList
}) })
}, },
@ -69,6 +69,8 @@ export default {
methods: { methods: {
filterByQueue(queue) { filterByQueue(queue) {
queue = Number(queue)
queue = queue === -1 ? null : queue
this.championStats(queue) this.championStats(queue)
}, },
updateSearch(search) { updateSearch(search) {

View file

@ -9,9 +9,9 @@ const Summoner = use('App/Models/Summoner')
class SummonerController { class SummonerController {
/** /**
* POST Endpoint : get summoner data * POST: get basic summoner data
*/ */
async api({ request, response }) { async basic({ request, response }) {
console.time('all') console.time('all')
const summoner = request.input('summoner') const summoner = request.input('summoner')
const region = request.input('region') const region = request.input('region')
@ -38,6 +38,11 @@ class SummonerController {
{ puuid: account.puuid } { puuid: account.puuid }
) )
// MATCH LIST
await MatchService.updateMatchList(account, summonerDB)
const matchList = summonerDB.matchList
finalJSON.allMatches = matchList
// CURRENT GAME // CURRENT GAME
const currentGame = await Jax.Spectator.summonerID(account.id, region) const currentGame = await Jax.Spectator.summonerID(account.id, region)
finalJSON.playing = !!currentGame finalJSON.playing = !!currentGame
@ -45,23 +50,6 @@ class SummonerController {
// RANKED STATS // RANKED STATS
finalJSON.ranked = await SummonerService.getRanked(account, region) finalJSON.ranked = await SummonerService.getRanked(account, region)
// MATCH LIST
await MatchService.updateMatchList(account, summonerDB)
const matchList = summonerDB.matchList
finalJSON.allMatches = matchList
// MATCHES BASIC
const gameIds = matchList.slice(0, 10).map(({ gameId }) => gameId)
finalJSON.matchesDetails = await MatchService.getMatches(account, gameIds, summonerDB)
// PATCH VERSION
finalJSON.version = Jax.DDragon.Version
// STATS
console.time('STATS')
finalJSON.stats = await StatsService.getSummonerStats(account)
console.timeEnd('STATS')
// SAVE IN DB // SAVE IN DB
await summonerDB.save() await summonerDB.save()
} catch (error) { } catch (error) {
@ -74,6 +62,40 @@ class SummonerController {
return response.json(finalJSON) return response.json(finalJSON)
} }
/**
* POST: get overview view summoner data
*/
async overview({ request, response }) {
console.time('overview')
const account = request.input('account')
console.log(account)
const finalJSON = {}
// Summoner in DB
const summonerDB = await Summoner.findOrCreate(
{ puuid: account.puuid },
{ puuid: account.puuid }
)
// MATCHES BASIC
const gameIds = summonerDB.matchList.slice(0, 10).map(({ gameId }) => gameId)
finalJSON.matchesDetails = await MatchService.getMatches(account, gameIds, summonerDB)
// STATS
console.time('STATS')
finalJSON.stats = await StatsService.getSummonerStats(account)
console.timeEnd('STATS')
// SAVE IN DB
await summonerDB.save()
console.timeEnd('overview')
return response.json(finalJSON)
}
/**
* POST: get champions view summoner data
*/
async champions({ request, response }) { async champions({ request, response }) {
const puuid = request.input('puuid') const puuid = request.input('puuid')
const queue = request.input('queue') const queue = request.input('queue')

View file

@ -25,8 +25,9 @@ Route.get('/', async () => {
} }
}) })
Route.post('/api', 'SummonerController.api') Route.post('/summoner-basic', 'SummonerController.basic')
Route.post('/champions', 'SummonerController.champions') Route.post('/summoner-overview', 'SummonerController.overview')
Route.post('/summoner-champions', 'SummonerController.champions')
Route.post('/ddragon', 'DDragonController.index') Route.post('/ddragon', 'DDragonController.index')
Route.post('/match', 'MatchController.index') Route.post('/match', 'MatchController.index')
Route.post('/match-details', 'MatchController.show') Route.post('/match-details', 'MatchController.show')