mirror of
https://github.com/vkaelin/LeagueStats.git
synced 2026-03-25 12:57:28 +00:00
commit
f704d54622
21 changed files with 648 additions and 76 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
<div id="app" class="min-h-screen font-sans antialiased bg-blue-900">
|
<div id="app" class="min-h-screen font-sans antialiased bg-blue-900">
|
||||||
<SVGContainer />
|
<SVGContainer />
|
||||||
<NotificationsContainer />
|
<NotificationsContainer />
|
||||||
|
<RunesContainer />
|
||||||
<component :is="layout">
|
<component :is="layout">
|
||||||
<router-view />
|
<router-view />
|
||||||
</component>
|
</component>
|
||||||
|
|
@ -13,6 +14,7 @@ import { mapActions } from 'vuex'
|
||||||
import Default from '@/layouts/Default.vue'
|
import Default from '@/layouts/Default.vue'
|
||||||
import Home from '@/layouts/Home.vue'
|
import Home from '@/layouts/Home.vue'
|
||||||
import NotificationsContainer from '@/components/Global/NotificationsContainer.vue'
|
import NotificationsContainer from '@/components/Global/NotificationsContainer.vue'
|
||||||
|
import RunesContainer from '@/components/Match/Runes/RunesContainer.vue'
|
||||||
import SVGContainer from '@/components/Global/SVGContainer.vue'
|
import SVGContainer from '@/components/Global/SVGContainer.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -20,13 +22,14 @@ export default {
|
||||||
Default,
|
Default,
|
||||||
Home,
|
Home,
|
||||||
NotificationsContainer,
|
NotificationsContainer,
|
||||||
SVGContainer
|
RunesContainer,
|
||||||
|
SVGContainer,
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
layout() {
|
layout() {
|
||||||
return (this.$route.meta.layout || 'Default')
|
return this.$route.meta.layout || 'Default'
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
|
|
@ -38,6 +41,6 @@ export default {
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions('settings', ['updatePercent', 'updateSettings']),
|
...mapActions('settings', ['updatePercent', 'updateSettings']),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,11 @@
|
||||||
transition: opacity 2s;
|
transition: opacity 2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fade-fast-enter-active, .fade-fast-leave-active {
|
||||||
|
transition: opacity .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-fast-enter, .fade-fast-leave-to,
|
||||||
.fade-enter, .fade-leave-to {
|
.fade-enter, .fade-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
client/src/assets/img/runes/domination.jpg
Normal file
BIN
client/src/assets/img/runes/domination.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 84 KiB |
BIN
client/src/assets/img/runes/inspiration.jpg
Normal file
BIN
client/src/assets/img/runes/inspiration.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 94 KiB |
BIN
client/src/assets/img/runes/precision.jpg
Normal file
BIN
client/src/assets/img/runes/precision.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
BIN
client/src/assets/img/runes/resolve.jpg
Normal file
BIN
client/src/assets/img/runes/resolve.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
BIN
client/src/assets/img/runes/sorcery.jpg
Normal file
BIN
client/src/assets/img/runes/sorcery.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
|
|
@ -13,7 +13,7 @@
|
||||||
<span
|
<span
|
||||||
:class="allyTeam ? 'text-teal-400' : 'text-red-400'"
|
:class="allyTeam ? 'text-teal-400' : 'text-red-400'"
|
||||||
class="pl-2"
|
class="pl-2"
|
||||||
>{{ allyTeam ? 'Ally' : 'Enemy' }} Team</span>
|
>{{ allyTeam ? "Ally" : "Enemy" }} Team</span>
|
||||||
<div
|
<div
|
||||||
v-if="data.result === 'Win'"
|
v-if="data.result === 'Win'"
|
||||||
:class="allyTeam ? 'text-teal-400' : 'text-red-400'"
|
:class="allyTeam ? 'text-teal-400' : 'text-red-400'"
|
||||||
|
|
@ -29,12 +29,12 @@
|
||||||
<th class="px-2 py-5 text-sm font-medium w-kda">K</th>
|
<th class="px-2 py-5 text-sm font-medium w-kda">K</th>
|
||||||
<th class="px-2 py-5 text-sm font-medium w-kda">D</th>
|
<th class="px-2 py-5 text-sm font-medium w-kda">D</th>
|
||||||
<th class="px-2 py-5 text-sm font-medium w-kda">A</th>
|
<th class="px-2 py-5 text-sm font-medium w-kda">A</th>
|
||||||
<th
|
<th class="px-2 py-5 text-sm font-medium w-minions">
|
||||||
class="px-2 py-5 text-sm font-medium w-minions"
|
{{ statsFormat === "stats" ? "Cs" : "Cs/m" }}
|
||||||
>{{ statsFormat === 'stats' ? 'Cs' : 'Cs/m' }}</th>
|
</th>
|
||||||
<th
|
<th class="px-2 py-5 text-sm font-medium w-vision">
|
||||||
class="px-2 py-5 text-sm font-medium w-vision"
|
{{ statsFormat === "stats" ? "Vs" : "Vs/m" }}
|
||||||
>{{ statsFormat === 'stats' ? 'Vs' : 'Vs/m' }}</th>
|
</th>
|
||||||
<th class="px-2 py-5 text-sm font-medium w-gold-dmg-kp">Gold</th>
|
<th class="px-2 py-5 text-sm font-medium w-gold-dmg-kp">Gold</th>
|
||||||
<th class="px-2 py-5 text-sm font-medium w-gold-dmg-kp">
|
<th class="px-2 py-5 text-sm font-medium w-gold-dmg-kp">
|
||||||
Dmg
|
Dmg
|
||||||
|
|
@ -51,7 +51,10 @@
|
||||||
<th class="px-2 py-5 text-sm font-medium w-gold-dmg-kp">KP</th>
|
<th class="px-2 py-5 text-sm font-medium w-gold-dmg-kp">KP</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody :class="{'border-b border-blue-700': allyTeam}" class="leading-none">
|
<tbody
|
||||||
|
:class="{ 'border-b border-blue-700': allyTeam }"
|
||||||
|
class="leading-none"
|
||||||
|
>
|
||||||
<tr v-for="(player, index) in data.players" :key="player.name + index">
|
<tr v-for="(player, index) in data.players" :key="player.name + index">
|
||||||
<td class="py-2 border-r border-blue-700">
|
<td class="py-2 border-r border-blue-700">
|
||||||
<div class="flex justify-between px-1">
|
<div class="flex justify-between px-1">
|
||||||
|
|
@ -59,7 +62,11 @@
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div
|
<div
|
||||||
v-if="player.role !== 'NONE'"
|
v-if="player.role !== 'NONE'"
|
||||||
:style="{backgroundImage: `url(${require('@/assets/img/roles/' + player.role + '.png')})`}"
|
:style="{
|
||||||
|
backgroundImage: `url(${require('@/assets/img/roles/' +
|
||||||
|
player.role +
|
||||||
|
'.png')})`,
|
||||||
|
}"
|
||||||
class="w-4 h-4 bg-center bg-cover"
|
class="w-4 h-4 bg-center bg-cover"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -68,7 +75,11 @@
|
||||||
class="relative w-8 h-8 ml-2 bg-center bg-cover rounded-full bg-blue-1000"
|
class="relative w-8 h-8 ml-2 bg-center bg-cover rounded-full bg-blue-1000"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:class="allyTeam ? 'bg-teal-500 text-teal-100' : 'bg-red-500 text-red-100'"
|
:class="
|
||||||
|
allyTeam
|
||||||
|
? 'bg-teal-500 text-teal-100'
|
||||||
|
: 'bg-red-500 text-red-100'
|
||||||
|
"
|
||||||
class="absolute bottom-0 flex items-center justify-center w-4 h-4 rounded-full level-position text-xxs"
|
class="absolute bottom-0 flex items-center justify-center w-4 h-4 rounded-full level-position text-xxs"
|
||||||
>
|
>
|
||||||
<span>{{ player.level }}</span>
|
<span>{{ player.level }}</span>
|
||||||
|
|
@ -78,20 +89,32 @@
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<template v-slot:trigger>
|
<template v-slot:trigger>
|
||||||
<div
|
<div
|
||||||
:style="{backgroundImage: `url(${player.firstSum ? player.firstSum.icon : null})`}"
|
:style="{
|
||||||
|
backgroundImage: `url(${
|
||||||
|
player.firstSum ? player.firstSum.icon : null
|
||||||
|
})`,
|
||||||
|
}"
|
||||||
:class="{ 'cursor-pointer': player.firstSum }"
|
:class="{ 'cursor-pointer': player.firstSum }"
|
||||||
class="w-4 h-4 bg-center bg-cover rounded-md bg-blue-1000"
|
class="w-4 h-4 bg-center bg-cover rounded-md bg-blue-1000"
|
||||||
></div>
|
></div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="player.firstSum" v-slot:default>
|
<template v-if="player.firstSum" v-slot:default>
|
||||||
<div class="flex max-w-sm p-2 text-xs text-left text-white select-none">
|
|
||||||
<div
|
<div
|
||||||
:style="{backgroundImage: `url('${player.firstSum.icon}')`}"
|
class="flex max-w-sm p-2 text-xs text-left text-white select-none"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url('${player.firstSum.icon}')`,
|
||||||
|
}"
|
||||||
class="flex-shrink-0 w-12 h-12 ml-1 bg-center bg-cover rounded-md bg-blue-1000"
|
class="flex-shrink-0 w-12 h-12 ml-1 bg-center bg-cover rounded-md bg-blue-1000"
|
||||||
></div>
|
></div>
|
||||||
<div class="ml-2 leading-tight">
|
<div class="ml-2 leading-tight">
|
||||||
<div class="text-base leading-none">{{ player.firstSum.name }}</div>
|
<div class="text-base leading-none">
|
||||||
<div class="mt-1 font-light text-blue-200">{{ player.firstSum.description }}</div>
|
{{ player.firstSum.name }}
|
||||||
|
</div>
|
||||||
|
<div class="mt-1 font-light text-blue-200">
|
||||||
|
{{ player.firstSum.description }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -99,57 +122,111 @@
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<template v-slot:trigger>
|
<template v-slot:trigger>
|
||||||
<div
|
<div
|
||||||
:style="{backgroundImage: `url(${player.secondSum ? player.secondSum.icon : null})`}"
|
:style="{
|
||||||
|
backgroundImage: `url(${
|
||||||
|
player.secondSum ? player.secondSum.icon : null
|
||||||
|
})`,
|
||||||
|
}"
|
||||||
:class="{ 'cursor-pointer': player.secondSum }"
|
:class="{ 'cursor-pointer': player.secondSum }"
|
||||||
class="w-4 h-4 bg-center bg-cover rounded-md bg-blue-1000"
|
class="w-4 h-4 bg-center bg-cover rounded-md bg-blue-1000"
|
||||||
></div>
|
></div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="player.secondSum" v-slot:default>
|
<template v-if="player.secondSum" v-slot:default>
|
||||||
<div class="flex max-w-sm p-2 text-xs text-left text-white select-none">
|
|
||||||
<div
|
<div
|
||||||
:style="{backgroundImage: `url('${player.secondSum.icon}')`}"
|
class="flex max-w-sm p-2 text-xs text-left text-white select-none"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url('${player.secondSum.icon}')`,
|
||||||
|
}"
|
||||||
class="flex-shrink-0 w-12 h-12 ml-1 bg-center bg-cover rounded-md bg-blue-1000"
|
class="flex-shrink-0 w-12 h-12 ml-1 bg-center bg-cover rounded-md bg-blue-1000"
|
||||||
></div>
|
></div>
|
||||||
<div class="ml-2 leading-tight">
|
<div class="ml-2 leading-tight">
|
||||||
<div class="text-base leading-none">{{ player.secondSum.name }}</div>
|
<div class="text-base leading-none">
|
||||||
<div
|
{{ player.secondSum.name }}
|
||||||
class="mt-1 font-light text-blue-200"
|
</div>
|
||||||
>{{ player.secondSum.description }}</div>
|
<div class="mt-1 font-light text-blue-200">
|
||||||
|
{{ player.secondSum.description }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col justify-around ml-2px">
|
<Tooltip>
|
||||||
|
<template v-slot:trigger>
|
||||||
<div
|
<div
|
||||||
:style="[player.primaryRune ? {background: `url(${player.primaryRune}) center/cover`} : '']"
|
@click="selectRunes(player)"
|
||||||
|
:class="{ 'cursor-pointer': player.perks }"
|
||||||
|
class="flex flex-col justify-around cursor-pointer ml-2px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:style="[
|
||||||
|
player.primaryRune
|
||||||
|
? {
|
||||||
|
background: `url(${player.primaryRune}) center/cover`,
|
||||||
|
}
|
||||||
|
: '',
|
||||||
|
]"
|
||||||
class="w-4 h-4 rounded-md bg-blue-1000"
|
class="w-4 h-4 rounded-md bg-blue-1000"
|
||||||
></div>
|
></div>
|
||||||
<div
|
<div
|
||||||
:style="[player.secondaryRune ? {background: `url(${player.secondaryRune}) center/cover`} : '']"
|
:style="[
|
||||||
|
player.secondaryRune
|
||||||
|
? {
|
||||||
|
background: `url(${player.secondaryRune}) center/cover`,
|
||||||
|
}
|
||||||
|
: '',
|
||||||
|
]"
|
||||||
class="w-4 h-4 rounded-md bg-blue-1000"
|
class="w-4 h-4 rounded-md bg-blue-1000"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-start justify-center ml-1 leading-none">
|
</template>
|
||||||
|
<template v-if="player.perks" v-slot:default>
|
||||||
|
<div
|
||||||
|
class="px-2 text-sm leading-relaxed text-center text-white select-none"
|
||||||
|
>
|
||||||
|
<p>Click to display</p>
|
||||||
|
<p class="font-bold text-teal-400">full runes</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Tooltip>
|
||||||
|
<div
|
||||||
|
class="flex flex-col items-start justify-center ml-1 leading-none"
|
||||||
|
>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="player.firstSum"
|
v-if="player.firstSum"
|
||||||
:to="{ name: 'summoner', params: { region: $route.params.region, name: player.name }}"
|
:to="{
|
||||||
:class="{'font-semibold text-yellow-400': account.id === player.summonerId}"
|
name: 'summoner',
|
||||||
|
params: { region: $route.params.region, name: player.name },
|
||||||
|
}"
|
||||||
|
:class="{
|
||||||
|
'font-semibold text-yellow-400':
|
||||||
|
account.id === player.summonerId,
|
||||||
|
}"
|
||||||
class="overflow-hidden text-xs text-left text-white whitespace-no-wrap w-22 text-overflow hover:text-blue-200"
|
class="overflow-hidden text-xs text-left text-white whitespace-no-wrap w-22 text-overflow hover:text-blue-200"
|
||||||
>{{ player.name }}</router-link>
|
>{{ player.name }}</router-link>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="overflow-hidden text-xs text-left text-white whitespace-no-wrap w-22 text-overflow"
|
class="overflow-hidden text-xs text-left text-white whitespace-no-wrap w-22 text-overflow"
|
||||||
>{{ player.name }}</div>
|
>
|
||||||
<div class="text-teal-500 text-xxs">{{ player.champion.name }}</div>
|
{{ player.name }}
|
||||||
|
</div>
|
||||||
|
<div class="text-teal-500 text-xxs">
|
||||||
|
{{ player.champion.name }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div v-if="player.rank">
|
<div v-if="player.rank">
|
||||||
<svg class="w-5 h-5 ml-auto">
|
<svg class="w-5 h-5 ml-auto">
|
||||||
<use :xlink:href="`#rank-${player.rank.tier.toLowerCase()}`" />
|
<use
|
||||||
|
:xlink:href="`#rank-${player.rank.tier.toLowerCase()}`"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="text-blue-300 text-xxs">{{ player.rank.shortName }}</div>
|
<div class="text-blue-300 text-xxs">
|
||||||
|
{{ player.rank.shortName }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="player.rank === undefined">
|
<div v-else-if="player.rank === undefined">
|
||||||
<DotsLoader width="30px" dot-width="10px" />
|
<DotsLoader width="30px" dot-width="10px" />
|
||||||
|
|
@ -165,61 +242,81 @@
|
||||||
<div
|
<div
|
||||||
:style="bgColor(player, 'kills')"
|
:style="bgColor(player, 'kills')"
|
||||||
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
||||||
>{{ player.stats.kills }}</div>
|
>
|
||||||
|
{{ player.stats.kills }}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="relative">
|
<td class="relative">
|
||||||
<div
|
<div
|
||||||
:style="bgColor(player, 'deaths')"
|
:style="bgColor(player, 'deaths')"
|
||||||
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
||||||
>{{ player.stats.deaths }}</div>
|
>
|
||||||
|
{{ player.stats.deaths }}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="relative">
|
<td class="relative">
|
||||||
<div
|
<div
|
||||||
:style="bgColor(player, 'assists')"
|
:style="bgColor(player, 'assists')"
|
||||||
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
||||||
>{{ player.stats.assists }}</div>
|
>
|
||||||
|
{{ player.stats.assists }}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="relative">
|
<td class="relative">
|
||||||
<div
|
<div
|
||||||
:style="bgColor(player, 'minions')"
|
:style="bgColor(player, 'minions')"
|
||||||
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
||||||
>{{ player[statsFormat].minions }}</div>
|
>
|
||||||
|
{{ player[statsFormat].minions }}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="relative">
|
<td class="relative">
|
||||||
<div
|
<div
|
||||||
:style="bgColor(player, 'vision')"
|
:style="bgColor(player, 'vision')"
|
||||||
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
||||||
>{{ player[statsFormat].vision }}</div>
|
>
|
||||||
|
{{ player[statsFormat].vision }}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="relative">
|
<td class="relative">
|
||||||
<div
|
<div
|
||||||
:style="bgColor(player, 'gold')"
|
:style="bgColor(player, 'gold')"
|
||||||
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
||||||
>{{ roundStats(player[statsFormat].gold) }}</div>
|
>
|
||||||
|
{{ roundStats(player[statsFormat].gold) }}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="relative">
|
<td class="relative">
|
||||||
<div
|
<div
|
||||||
:style="bgColor(player, 'dmgChamp')"
|
:style="bgColor(player, 'dmgChamp')"
|
||||||
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
||||||
>{{ roundStats(player[statsFormat].dmgChamp) }}</div>
|
>
|
||||||
|
{{ roundStats(player[statsFormat].dmgChamp) }}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="relative">
|
<td class="relative">
|
||||||
<div
|
<div
|
||||||
:style="bgColor(player, 'dmgObj')"
|
:style="bgColor(player, 'dmgObj')"
|
||||||
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
||||||
>{{ roundStats(player[statsFormat].dmgObj) }}</div>
|
>
|
||||||
|
{{ roundStats(player[statsFormat].dmgObj) }}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="relative">
|
<td class="relative">
|
||||||
<div
|
<div
|
||||||
:style="bgColor(player, 'dmgTaken')"
|
:style="bgColor(player, 'dmgTaken')"
|
||||||
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
||||||
>{{ roundStats(player[statsFormat].dmgTaken) }}</div>
|
>
|
||||||
|
{{ roundStats(player[statsFormat].dmgTaken) }}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="relative">
|
<td class="relative">
|
||||||
<div
|
<div
|
||||||
:style="bgColor(player, 'kp')"
|
:style="bgColor(player, 'kp')"
|
||||||
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
class="absolute inset-0 flex items-center justify-center p-2 text-sm text-white"
|
||||||
>{{ player.stats.kp }}</div>
|
>
|
||||||
|
{{ player.stats.kp }}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
@ -228,7 +325,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { colors } from '@/data/data.js'
|
import { colors } from '@/data/data.js'
|
||||||
import { mapState } from 'vuex'
|
import { mapActions, mapState } from 'vuex'
|
||||||
import DotsLoader from '@/components/Common/DotsLoader.vue'
|
import DotsLoader from '@/components/Common/DotsLoader.vue'
|
||||||
import Tooltip from '@/components/Common/Tooltip.vue'
|
import Tooltip from '@/components/Common/Tooltip.vue'
|
||||||
import MatchItems from '@/components/Match/MatchItems.vue'
|
import MatchItems from '@/components/Match/MatchItems.vue'
|
||||||
|
|
@ -243,15 +340,15 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
allPlayers: {
|
allPlayers: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
allyTeam: {
|
allyTeam: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -260,28 +357,32 @@ export default {
|
||||||
return this.percentSettings ? 'percentStats' : 'stats'
|
return this.percentSettings ? 'percentStats' : 'stats'
|
||||||
},
|
},
|
||||||
...mapState({
|
...mapState({
|
||||||
account: state => state.summoner.basic.account,
|
account: (state) => state.summoner.basic.account,
|
||||||
percentSettings: state => state.settings.percent
|
percentSettings: (state) => state.settings.percent,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
bgColor(player, stats) {
|
bgColor(player, stats) {
|
||||||
const value = parseFloat(player.stats[stats])
|
const value = parseFloat(player.stats[stats])
|
||||||
const biggestValue = Math.max(...this.allPlayers.map(p => parseFloat(p.stats[stats])), 0)
|
const biggestValue = Math.max(
|
||||||
|
...this.allPlayers.map((p) => parseFloat(p.stats[stats])),
|
||||||
|
0
|
||||||
|
)
|
||||||
const opacity = (value / biggestValue).toFixed(2)
|
const opacity = (value / biggestValue).toFixed(2)
|
||||||
const biggestValueStyle = {}
|
const biggestValueStyle = {}
|
||||||
if (value === biggestValue && value !== 0) {
|
if (value === biggestValue && value !== 0) {
|
||||||
biggestValueStyle.boxShadow = 'rgba(181, 160, 122, 0.5) 0px 0px 10px'
|
biggestValueStyle.boxShadow = 'rgba(181, 160, 122, 0.5) 0px 0px 10px'
|
||||||
biggestValueStyle.border = '2px solid'
|
biggestValueStyle.border = '2px solid'
|
||||||
biggestValueStyle.borderImageSlice = '1'
|
biggestValueStyle.borderImageSlice = '1'
|
||||||
biggestValueStyle.borderImageSource = 'linear-gradient(to top, #edb457, #f9e9ce)'
|
biggestValueStyle.borderImageSource =
|
||||||
|
'linear-gradient(to top, #edb457, #f9e9ce)'
|
||||||
biggestValueStyle.borderCollapse = 'separate'
|
biggestValueStyle.borderCollapse = 'separate'
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
backgroundColor: `rgba(${colors[stats]}, ${opacity})`,
|
backgroundColor: `rgba(${colors[stats]}, ${opacity})`,
|
||||||
...biggestValueStyle
|
...biggestValueStyle,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
displayBorderbottom(index) {
|
displayBorderbottom(index) {
|
||||||
|
|
@ -290,17 +391,34 @@ export default {
|
||||||
getHeadingColor(result) {
|
getHeadingColor(result) {
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case 'Win':
|
case 'Win':
|
||||||
return { '--bg-img': 'linear-gradient(90deg, rgba(1, 97, 28, 0.3) 0%, rgba(44, 82, 130, 0) 45% )' }
|
return {
|
||||||
|
'--bg-img':
|
||||||
|
'linear-gradient(90deg, rgba(1, 97, 28, 0.3) 0%, rgba(44, 82, 130, 0) 45% )',
|
||||||
|
}
|
||||||
case 'Fail':
|
case 'Fail':
|
||||||
return { '--bg-img': 'linear-gradient(90deg, rgba(140, 0, 0, 0.3) 0%, rgba(44, 82, 130, 0) 45% )' }
|
return {
|
||||||
|
'--bg-img':
|
||||||
|
'linear-gradient(90deg, rgba(140, 0, 0, 0.3) 0%, rgba(44, 82, 130, 0) 45% )',
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return { '--bg-img': 'linear-gradient(90deg, rgba(233, 169, 75, 0.3) 0%, rgba(44, 82, 130, 0) 45% )' }
|
return {
|
||||||
|
'--bg-img':
|
||||||
|
'linear-gradient(90deg, rgba(233, 169, 75, 0.3) 0%, rgba(44, 82, 130, 0) 45% )',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
roundStats(value) {
|
roundStats(value) {
|
||||||
return this.percentSettings ? value : this.$options.filters.kilo(value)
|
return this.percentSettings ? value : this.$options.filters.kilo(value)
|
||||||
},
|
},
|
||||||
|
selectRunes(player) {
|
||||||
|
if (!player.perks) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.displayOrHideRunes(player.perks)
|
||||||
|
},
|
||||||
|
...mapActions('cdragon', ['displayOrHideRunes']),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
195
client/src/components/Match/Runes/RuneStyle.vue
Normal file
195
client/src/components/Match/Runes/RuneStyle.vue
Normal file
|
|
@ -0,0 +1,195 @@
|
||||||
|
<template>
|
||||||
|
<div class="flex">
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url('${createCategoryBorderUrl(runeStyle.name)}')`,
|
||||||
|
}"
|
||||||
|
class="flex items-center justify-center w-24 h-24 bg-cover"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url('${createCategoryUrl(runeStyle.name)}')`,
|
||||||
|
}"
|
||||||
|
style="filter: brightness(1.2)"
|
||||||
|
class="w-56 h-56 mt-4 bg-center bg-no-repeat bg-contain"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-24 space-y-4">
|
||||||
|
<div
|
||||||
|
v-for="(category, index) in slots"
|
||||||
|
:key="`secondary-category-${index}`"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div class="flex space-x-4">
|
||||||
|
<ul v-for="runeId in category" :key="`slot-${runeId}`">
|
||||||
|
<Tooltip>
|
||||||
|
<template v-slot:trigger>
|
||||||
|
<li
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url('${createCDragonAssetUrl(
|
||||||
|
runes.perks[runeId].icon
|
||||||
|
)}')`,
|
||||||
|
}"
|
||||||
|
:class="
|
||||||
|
selectedRunes.selected.includes(runeId)
|
||||||
|
? 'used-rune'
|
||||||
|
: 'not-used-rune'
|
||||||
|
"
|
||||||
|
class="w-12 h-12 bg-center bg-cover border-2 border-gray-700 rounded-full cursor-pointer"
|
||||||
|
></li>
|
||||||
|
</template>
|
||||||
|
<template v-slot:default>
|
||||||
|
<div
|
||||||
|
class="flex max-w-md p-2 text-sm text-left text-white select-none"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url('${createCDragonAssetUrl(
|
||||||
|
runes.perks[runeId].icon
|
||||||
|
)}')`,
|
||||||
|
}"
|
||||||
|
class="flex-shrink-0 w-12 h-12 ml-1 bg-center bg-cover rounded-md bg-blue-1000"
|
||||||
|
></div>
|
||||||
|
<div class="ml-2 leading-none">
|
||||||
|
<div class="text-base">{{ runes.perks[runeId].name }}</div>
|
||||||
|
<div
|
||||||
|
v-html="runes.perks[runeId].desc"
|
||||||
|
class="mt-3 font-light leading-tight text-blue-200 rune-description"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Tooltip>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="primary && index == 0"
|
||||||
|
class="w-full mt-4 bg-gray-500 bg-opacity-25 h-2px"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!primary">
|
||||||
|
<div class="mt-8 space-y-4">
|
||||||
|
<div
|
||||||
|
v-for="(row, index) in kStats"
|
||||||
|
:key="`row-${index}`"
|
||||||
|
class="flex px-3 space-x-8"
|
||||||
|
>
|
||||||
|
<ul v-for="(kStat, i) in row" :key="`${kStat}-${i}`">
|
||||||
|
<Tooltip>
|
||||||
|
<template v-slot:trigger>
|
||||||
|
<li
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url('${createCDragonAssetUrl(
|
||||||
|
runes.perks[kStat].icon
|
||||||
|
)}')`,
|
||||||
|
}"
|
||||||
|
:class="
|
||||||
|
selectedRunes.selected[index + 6] === kStat
|
||||||
|
? 'used-rune'
|
||||||
|
: 'not-used-rune'
|
||||||
|
"
|
||||||
|
class="w-8 h-8 bg-gray-900 bg-center bg-cover border-2 border-gray-700 rounded-full cursor-pointer"
|
||||||
|
></li>
|
||||||
|
</template>
|
||||||
|
<template v-slot:default>
|
||||||
|
<div
|
||||||
|
class="flex max-w-md p-2 text-sm text-left text-white select-none"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url('${createCDragonAssetUrl(
|
||||||
|
runes.perks[kStat].icon
|
||||||
|
)}')`,
|
||||||
|
}"
|
||||||
|
class="flex-shrink-0 w-8 h-8 ml-1 bg-center bg-cover rounded-md bg-blue-1000"
|
||||||
|
></div>
|
||||||
|
<div class="ml-2 leading-none">
|
||||||
|
<div class="text-base">{{ runes.perks[kStat].name }}</div>
|
||||||
|
<div
|
||||||
|
v-html="runes.perks[kStat].desc"
|
||||||
|
class="mt-3 font-light leading-tight text-blue-200 rune-description"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Tooltip>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
import { createCDragonAssetUrl } from '@/helpers/functions'
|
||||||
|
import Tooltip from '@/components/Common/Tooltip.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Tooltip,
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
primary: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
runeStyle: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
slots() {
|
||||||
|
return this.primary ? this.runeStyle.slots : this.runeStyle.slots.slice(1)
|
||||||
|
},
|
||||||
|
...mapState({
|
||||||
|
kStats: state => state.cdragon.kStats,
|
||||||
|
runes: state => state.cdragon.runes,
|
||||||
|
runesOpen: state => state.cdragon.runesOpen,
|
||||||
|
selectedRunes: state => state.cdragon.selectedRunes
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
createCategoryBorderUrl(name) {
|
||||||
|
const lower = name.toLowerCase()
|
||||||
|
return `http://raw.communitydragon.org/pbe/plugins/rcp-fe-lol-collections/global/default/perks/images/${lower}/vfx-${lower[0]}.png`
|
||||||
|
},
|
||||||
|
createCategoryUrl(name) {
|
||||||
|
const lower = name.toLowerCase()
|
||||||
|
return `http://raw.communitydragon.org/latest/plugins/rcp-fe-lol-collections/global/default/perks/images/${lower}/icon-${lower[0]}.png`
|
||||||
|
},
|
||||||
|
createCDragonAssetUrl,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.not-used-rune {
|
||||||
|
@apply opacity-50 transition-all duration-150 ease-in-out;
|
||||||
|
filter: grayscale(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-used-rune:hover {
|
||||||
|
@apply opacity-100;
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.used-rune {
|
||||||
|
@apply transition-all duration-75 ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.used-rune:hover {
|
||||||
|
filter: brightness(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rune-description >>> hr {
|
||||||
|
@apply border-blue-800;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
106
client/src/components/Match/Runes/RunesContainer.vue
Normal file
106
client/src/components/Match/Runes/RunesContainer.vue
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
<template>
|
||||||
|
<transition leave-active-class="duration-300">
|
||||||
|
<div
|
||||||
|
v-show="runesOpen"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<transition
|
||||||
|
enter-active-class="transition duration-300 ease-out"
|
||||||
|
enter-class="transform opacity-0"
|
||||||
|
enter-to-class="transform opacity-100"
|
||||||
|
leave-active-class="transition duration-200 ease-in"
|
||||||
|
leave-class="transform opacity-100"
|
||||||
|
leave-to-class="transform opacity-0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="runesOpen"
|
||||||
|
@click="close"
|
||||||
|
class="fixed inset-0 bg-gray-900 bg-opacity-75"
|
||||||
|
></div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<transition
|
||||||
|
enter-active-class="transition duration-300 ease-out"
|
||||||
|
enter-class="transform scale-95 opacity-0"
|
||||||
|
enter-to-class="transform scale-100 opacity-100"
|
||||||
|
leave-active-class="transition duration-200 ease-in"
|
||||||
|
leave-class="transform scale-100 opacity-100"
|
||||||
|
leave-to-class="transform scale-95 opacity-0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="runesOpen"
|
||||||
|
class="relative overflow-hidden rounded-md shadow-lg"
|
||||||
|
style="width: 800px; height: 500px"
|
||||||
|
>
|
||||||
|
<LazyBackground
|
||||||
|
:image-source="
|
||||||
|
require(`@/assets/img/runes/${primaryStyle.name.toLowerCase()}.jpg`)
|
||||||
|
"
|
||||||
|
image-class="absolute inset-0"
|
||||||
|
more-backgrounds="linear-gradient(rgba(26, 32, 44, 0.6), rgba(26, 32, 44, 0.8)),"
|
||||||
|
style="filter: blur(2px)"
|
||||||
|
transition-name="fade-fast"
|
||||||
|
>
|
||||||
|
</LazyBackground>
|
||||||
|
<div class="relative flex items-start h-full px-4 py-2">
|
||||||
|
<div class="w-1/2">
|
||||||
|
<RuneStyle :primary="true" :rune-style="primaryStyle" />
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2">
|
||||||
|
<RuneStyle :primary="false" :rune-style="secondaryStyle" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapActions, mapState } from 'vuex'
|
||||||
|
import { createCDragonAssetUrl } from '@/helpers/functions'
|
||||||
|
import LazyBackground from '@/components/Common/LazyBackgroundImage.vue'
|
||||||
|
import RuneStyle from '@/components/Match/Runes/RuneStyle.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
LazyBackground,
|
||||||
|
RuneStyle,
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
primaryStyle() {
|
||||||
|
return this.runes.perkstyles[this.selectedRunes.primaryStyle]
|
||||||
|
},
|
||||||
|
secondaryStyle() {
|
||||||
|
return this.runes.perkstyles[this.selectedRunes.secondaryStyle]
|
||||||
|
},
|
||||||
|
...mapState({
|
||||||
|
runes: state => state.cdragon.runes,
|
||||||
|
runesOpen: state => state.cdragon.runesOpen,
|
||||||
|
selectedRunes: state => state.cdragon.selectedRunes
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
document.addEventListener('keydown', this.handleEscape)
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
document.removeEventListener('keydown', this.handleEscape)
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
this.displayOrHideRunes({})
|
||||||
|
},
|
||||||
|
handleEscape(e) {
|
||||||
|
if (e.key === 'Esc' || e.key === 'Escape') {
|
||||||
|
this.displayOrHideRunes({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createCDragonAssetUrl,
|
||||||
|
...mapActions('cdragon', ['displayOrHideRunes'])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -43,3 +43,12 @@ export function sortTeamByRole(a, b) {
|
||||||
const sortingArr = ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'SUPPORT']
|
const sortingArr = ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'SUPPORT']
|
||||||
return sortingArr.indexOf(a.role) - sortingArr.indexOf(b.role)
|
return sortingArr.indexOf(a.role) - sortingArr.indexOf(b.role)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give the full CDragon image path from the iconPath field
|
||||||
|
* @param {String} iconPath
|
||||||
|
*/
|
||||||
|
export function createCDragonAssetUrl(iconPath) {
|
||||||
|
const name = iconPath.split('/assets/')[1].toLowerCase()
|
||||||
|
return `https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/${name}`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ axios.defaults.cancelToken = axiosSource.token
|
||||||
|
|
||||||
// Add season number to data if the route need it
|
// Add season number to data if the route need it
|
||||||
axios.interceptors.request.use(function (config) {
|
axios.interceptors.request.use(function (config) {
|
||||||
if (config.url !== 'summoner/basic' && router.currentRoute.meta.season) {
|
if (config.method === 'post' && config.url !== 'summoner/basic' && router.currentRoute.meta.season) {
|
||||||
config.data.season = store.state.summoner.basic.currentSeason
|
config.data.season = store.state.summoner.basic.currentSeason
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
|
import * as cdragon from '@/store/modules/cdragon'
|
||||||
import * as detailedMatch from '@/store/modules/detailedMatch'
|
import * as detailedMatch from '@/store/modules/detailedMatch'
|
||||||
import * as notification from '@/store/modules/notification'
|
import * as notification from '@/store/modules/notification'
|
||||||
import * as settings from '@/store/modules/settings'
|
import * as settings from '@/store/modules/settings'
|
||||||
|
|
@ -11,6 +12,7 @@ const debug = process.env.NODE_ENV !== 'production'
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
modules: {
|
modules: {
|
||||||
|
cdragon,
|
||||||
detailedMatch,
|
detailedMatch,
|
||||||
notification,
|
notification,
|
||||||
settings,
|
settings,
|
||||||
|
|
|
||||||
41
client/src/store/modules/cdragon.js
Normal file
41
client/src/store/modules/cdragon.js
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { axios } from '@/plugins/axios'
|
||||||
|
|
||||||
|
export const namespaced = true
|
||||||
|
|
||||||
|
export const state = {
|
||||||
|
kStats: [
|
||||||
|
[5008, 5005, 5007],
|
||||||
|
[5008, 5002, 5003],
|
||||||
|
[5001, 5002, 5003],
|
||||||
|
],
|
||||||
|
runes: null,
|
||||||
|
runesOpen: false,
|
||||||
|
selectedRunes: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
DISPLAY_HIDE_RUNES(state, selectedRunes) {
|
||||||
|
state.runesOpen = !state.runesOpen
|
||||||
|
state.selectedRunes = selectedRunes
|
||||||
|
},
|
||||||
|
SET_RUNES(state, runes) {
|
||||||
|
state.runes = runes
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
displayOrHideRunes({ commit }, selectedRunes) {
|
||||||
|
commit('DISPLAY_HIDE_RUNES', selectedRunes)
|
||||||
|
},
|
||||||
|
async getRunes({ commit, getters }) {
|
||||||
|
if (getters.runesLoaded) { return }
|
||||||
|
|
||||||
|
const { data } = await axios.get('cdragon/runes').catch((e) => { console.log(e) })
|
||||||
|
console.log(data)
|
||||||
|
commit('SET_RUNES', data)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getters = {
|
||||||
|
runesLoaded: state => state.runes,
|
||||||
|
}
|
||||||
|
|
@ -76,7 +76,7 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
current: state => state.summoner.live.match,
|
current: state => state.summoner.live.match,
|
||||||
overview: state => state.summoner.overview
|
overview: state => state.summoner.overview,
|
||||||
}),
|
}),
|
||||||
...mapGetters('summoner', ['matchesLoading', 'moreMatchesToFetch', 'overviewLoaded', 'summonerFound'])
|
...mapGetters('summoner', ['matchesLoading', 'moreMatchesToFetch', 'overviewLoaded', 'summonerFound'])
|
||||||
},
|
},
|
||||||
|
|
@ -92,6 +92,8 @@ export default {
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
|
|
||||||
|
this.getRunes()
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -104,6 +106,7 @@ export default {
|
||||||
this.sliceOverviewMatches(10)
|
this.sliceOverviewMatches(10)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
...mapActions('cdragon', ['getRunes']),
|
||||||
...mapActions('summoner', ['moreMatches', 'overviewRequest', 'sliceOverviewMatches']),
|
...mapActions('summoner', ['moreMatches', 'overviewRequest', 'sliceOverviewMatches']),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
27
server/app/Controllers/Http/CDragonController.ts
Normal file
27
server/app/Controllers/Http/CDragonController.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import Redis from '@ioc:Adonis/Addons/Redis'
|
||||||
|
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
||||||
|
import Jax from 'App/Services/Jax'
|
||||||
|
import RuneTransformer from 'App/Transformers/RuneTransformer'
|
||||||
|
|
||||||
|
export default class CDragonController {
|
||||||
|
public async runes ({ response }: HttpContextContract) {
|
||||||
|
const cacheUrl = 'cdragon-runes'
|
||||||
|
|
||||||
|
const requestCached = await Redis.get(cacheUrl)
|
||||||
|
if (requestCached) {
|
||||||
|
return response.json(requestCached)
|
||||||
|
}
|
||||||
|
|
||||||
|
const perks = await Jax.CDragon.perks()
|
||||||
|
const perkstyles = await Jax.CDragon.perkstyles()
|
||||||
|
|
||||||
|
const runesData = {
|
||||||
|
perks: RuneTransformer.transformPerks(perks),
|
||||||
|
perkstyles: RuneTransformer.transformStyles(perkstyles.styles),
|
||||||
|
}
|
||||||
|
|
||||||
|
await Redis.set(cacheUrl, JSON.stringify(runesData), 'EX', 36000)
|
||||||
|
|
||||||
|
return response.json(runesData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -29,7 +29,8 @@ export interface ParticipantDetails {
|
||||||
secondSum: SummonerSpell | number | null,
|
secondSum: SummonerSpell | number | null,
|
||||||
stats: Stats,
|
stats: Stats,
|
||||||
percentStats?: PercentStats
|
percentStats?: PercentStats
|
||||||
rank?: Rank | null
|
rank?: Rank | null,
|
||||||
|
perks?: Perks
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Champion<T = number, U = string> {
|
export interface Champion<T = number, U = string> {
|
||||||
|
|
@ -51,6 +52,12 @@ export interface Rank {
|
||||||
shortName: string | number
|
shortName: string | number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Perks {
|
||||||
|
primaryStyle: number;
|
||||||
|
secondaryStyle: number;
|
||||||
|
selected: number[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface ParticipantBasic {
|
export interface ParticipantBasic {
|
||||||
account_id: string,
|
account_id: string,
|
||||||
name: string,
|
name: string,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class MatchRepository {
|
||||||
return {
|
return {
|
||||||
summoner_puuid: puuid,
|
summoner_puuid: puuid,
|
||||||
result: { $not: { $eq: 'Remake' } },
|
result: { $not: { $eq: 'Remake' } },
|
||||||
gamemode: { $nin: [800, 810, 820, 830, 840, 850] },
|
gamemode: { $nin: [800, 810, 820, 830, 840, 850, 2000, 2010, 2020] },
|
||||||
season: season ? season : { $exists: true },
|
season: season ? season : { $exists: true },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,15 @@
|
||||||
import { getSeasonNumber, queuesWithRole, sortTeamByRole, supportItems } from 'App/helpers'
|
import { getSeasonNumber, queuesWithRole, sortTeamByRole, supportItems } from 'App/helpers'
|
||||||
import Jax from 'App/Services/Jax'
|
import Jax from 'App/Services/Jax'
|
||||||
import { MatchDto, ParticipantDto, ParticipantTimelineDto } from 'App/Services/Jax/src/Endpoints/MatchEndpoint'
|
import { Champion, Item, ParticipantBasic, ParticipantDetails, PercentStats, Perks, Stats, SummonerSpell } from 'App/Models/Match'
|
||||||
import { Champion, Item, ParticipantBasic, ParticipantDetails, PercentStats, Stats, SummonerSpell } from 'App/Models/Match'
|
|
||||||
import RoleIdentificationService, { ChampionsPlayRate } from 'App/Services/RoleIdentiticationService'
|
import RoleIdentificationService, { ChampionsPlayRate } from 'App/Services/RoleIdentiticationService'
|
||||||
import { ChampionDTO, ItemDTO, PerkDTO, PerkStyleDTO, SummonerSpellDTO } from 'App/Services/Jax/src/Endpoints/CDragonEndpoint'
|
import { ChampionDTO, ItemDTO, PerkDTO, PerkStyleDTO, SummonerSpellDTO } from 'App/Services/Jax/src/Endpoints/CDragonEndpoint'
|
||||||
import { TeamStats } from 'App/Models/DetailedMatch'
|
import { TeamStats } from 'App/Models/DetailedMatch'
|
||||||
|
import {
|
||||||
|
MatchDto,
|
||||||
|
ParticipantDto,
|
||||||
|
ParticipantStatsDto,
|
||||||
|
ParticipantTimelineDto,
|
||||||
|
} from 'App/Services/Jax/src/Endpoints/MatchEndpoint'
|
||||||
|
|
||||||
export interface PlayerRole {
|
export interface PlayerRole {
|
||||||
champion: number,
|
champion: number,
|
||||||
|
|
@ -194,9 +199,29 @@ export default abstract class MatchTransformer {
|
||||||
playerData.percentStats = percentStats!
|
playerData.percentStats = percentStats!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playerData.perks = this.getFullPerks(player.stats)
|
||||||
|
|
||||||
return playerData
|
return playerData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getFullPerks (stats: ParticipantStatsDto) {
|
||||||
|
const perks: Perks = {
|
||||||
|
primaryStyle: stats.perkPrimaryStyle,
|
||||||
|
secondaryStyle: stats.perkSubStyle,
|
||||||
|
selected: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
perks.selected.push(stats[`perk${i}`])
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
perks.selected.push(stats[`statPerk${i}`])
|
||||||
|
}
|
||||||
|
|
||||||
|
return perks
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the icons of the primary rune and secondary category
|
* Return the icons of the primary rune and secondary category
|
||||||
* @param perk0 primary perks id
|
* @param perk0 primary perks id
|
||||||
|
|
|
||||||
29
server/app/Transformers/RuneTransformer.ts
Normal file
29
server/app/Transformers/RuneTransformer.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { PerkDTO, PerkStyleDTO } from 'App/Services/Jax/src/Endpoints/CDragonEndpoint'
|
||||||
|
|
||||||
|
class RuneTransformer {
|
||||||
|
public transformPerks (perks: PerkDTO[]) {
|
||||||
|
return perks.reduce((acc, perk) => {
|
||||||
|
acc[perk.id] = {
|
||||||
|
name: perk.name,
|
||||||
|
desc: perk.longDesc,
|
||||||
|
icon: perk.iconPath,
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
public transformStyles (styles: PerkStyleDTO[]) {
|
||||||
|
return styles.reduce((acc, style) => {
|
||||||
|
acc[style.id] = {
|
||||||
|
name: style.name,
|
||||||
|
icon: style.iconPath,
|
||||||
|
slots: style.slots
|
||||||
|
.filter(s => s.type !== 'kStatMod')
|
||||||
|
.map(s => s.perks),
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new RuneTransformer()
|
||||||
|
|
@ -22,6 +22,8 @@ import Route from '@ioc:Adonis/Core/Route'
|
||||||
|
|
||||||
Route.get('/', async () => ({ hi: 'Hello World from LeagueStats API', uptime: process.uptime() }))
|
Route.get('/', async () => ({ hi: 'Hello World from LeagueStats API', uptime: process.uptime() }))
|
||||||
|
|
||||||
|
Route.get('/cdragon/runes', 'CDragonController.runes')
|
||||||
|
|
||||||
Route.post('/summoner/basic', 'SummonersController.basic')
|
Route.post('/summoner/basic', 'SummonersController.basic')
|
||||||
Route.post('/summoner/overview', 'SummonersController.overview')
|
Route.post('/summoner/overview', 'SummonersController.overview')
|
||||||
Route.post('/summoner/champions', 'SummonersController.champions')
|
Route.post('/summoner/champions', 'SummonersController.champions')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue