mirror of
https://github.com/vkaelin/LeagueStats.git
synced 2026-03-25 12:57:28 +00:00
feat: add live game tab back
This commit is contained in:
parent
0b0aa48e69
commit
5a7c38281f
11 changed files with 249 additions and 42 deletions
|
|
@ -30,11 +30,11 @@
|
||||||
class="flex flex-col items-center runes"
|
class="flex flex-col items-center runes"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:style="{backgroundImage: `url('${player.runes.primaryRune}')`}"
|
:style="{backgroundImage: `url('${getPrimarRune(player.perks)}')`}"
|
||||||
class="w-6 h-6 bg-center bg-cover"
|
class="w-6 h-6 bg-center bg-cover"
|
||||||
></div>
|
></div>
|
||||||
<div
|
<div
|
||||||
:style="{backgroundImage: `url('${player.runes.secondaryRune}')`}"
|
:style="{backgroundImage: `url('${getSecondaryRune(player.perks)}')`}"
|
||||||
class="w-3 h-3 mt-1 bg-center bg-cover"
|
class="w-3 h-3 mt-1 bg-center bg-cover"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -72,7 +72,11 @@
|
||||||
:class="[player.summonerId === account.id ? 'text-yellow-500' : 'hover:text-blue-200']"
|
:class="[player.summonerId === account.id ? 'text-yellow-500' : 'hover:text-blue-200']"
|
||||||
class="font-semibold"
|
class="font-semibold"
|
||||||
>{{ player.summonerName }}</router-link>
|
>{{ player.summonerName }}</router-link>
|
||||||
<div class="text-xs">Level {{ player.level }}</div>
|
<div
|
||||||
|
:class="[ally ? 'text-teal-300 ' : 'text-red-400 ']"
|
||||||
|
class="text-xs"
|
||||||
|
>{{ player.champion.name }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -185,7 +189,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapActions, mapState } from 'vuex'
|
import { mapActions, mapState } from 'vuex'
|
||||||
import { getSummonerLink } from '@/helpers/summoner.js'
|
import { getSummonerLink, getPrimarRune, getSecondaryRune } from '@/helpers/summoner.js'
|
||||||
import { ContentLoader } from 'vue-content-loader'
|
import { ContentLoader } from 'vue-content-loader'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -264,17 +268,13 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectRunes(player) {
|
selectRunes(player) {
|
||||||
if(!player.perks) {
|
if(!player.perks)
|
||||||
return
|
return
|
||||||
}
|
this.displayOrHideRunes(player.perks)
|
||||||
|
|
||||||
this.displayOrHideRunes({
|
|
||||||
primaryStyle: player.perks.perkStyle,
|
|
||||||
secondaryStyle: player.perks.perkSubStyle,
|
|
||||||
selected: player.perks.perkIds
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
getSummonerLink,
|
getSummonerLink,
|
||||||
|
getPrimarRune,
|
||||||
|
getSecondaryRune,
|
||||||
...mapActions('cdragon', ['displayOrHideRunes']),
|
...mapActions('cdragon', ['displayOrHideRunes']),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,21 @@ import store from '@/store'
|
||||||
const leaguesNumbers = { 'I': 1, 'II': 2, 'III': 3, 'IV': 4 }
|
const leaguesNumbers = { 'I': 1, 'II': 2, 'III': 3, 'IV': 4 }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the url of the of the player runes
|
* Get the url of the of the player primary rune
|
||||||
* @param {Object} perks : from the API
|
* @param {Object} perks : from the API
|
||||||
*/
|
*/
|
||||||
export function getPrimaryAndSecondaryRune(perks) {
|
export function getPrimarRune(perks) {
|
||||||
const primaryRune = perks.selected.length ? store.state.cdragon.runes.perks[perks.selected[0]] : null
|
const primaryRune = perks.selected.length ? store.state.cdragon.runes.perks[perks.selected[0]] : null
|
||||||
const secondaryRune = store.state.cdragon.runes.perkstyles[perks.secondaryStyle]
|
return primaryRune ? createCDragonAssetUrl(primaryRune.icon) : null
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
/**
|
||||||
primaryRune: primaryRune ? createCDragonAssetUrl(primaryRune.icon) : null,
|
* Get the url of the of the player secondary rune
|
||||||
secondaryRune: secondaryRune ? createCDragonAssetUrl(secondaryRune.icon) : null
|
* @param {Object} perks : from the API
|
||||||
}
|
*/
|
||||||
|
export function getSecondaryRune(perks) {
|
||||||
|
const secondaryRune = store.state.cdragon.runes.perkstyles[perks.secondaryStyle]
|
||||||
|
return secondaryRune ? createCDragonAssetUrl(secondaryRune.icon) : null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -26,9 +30,8 @@ export function getPrimaryAndSecondaryRune(perks) {
|
||||||
export function createMatchData(matches) {
|
export function createMatchData(matches) {
|
||||||
for (const match of matches) {
|
for (const match of matches) {
|
||||||
// Runes
|
// Runes
|
||||||
const runes = getPrimaryAndSecondaryRune(match.perks)
|
match.primaryRune = getPrimarRune(match.perks)
|
||||||
match.primaryRune = runes.primaryRune
|
match.secondaryRune = getSecondaryRune(match.perks)
|
||||||
match.secondaryRune = runes.secondaryRune
|
|
||||||
|
|
||||||
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' }
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ export default {
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
|
|
||||||
|
this.getRunes()
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -67,6 +69,7 @@ export default {
|
||||||
this.liveMatchRequest()
|
this.liveMatchRequest()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
...mapActions('cdragon', ['getRunes']),
|
||||||
...mapActions('summoner', ['liveMatchRequest']),
|
...mapActions('summoner', ['liveMatchRequest']),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,13 @@ import { getCurrentSeason } from 'App/helpers'
|
||||||
import Summoner from 'App/Models/Summoner'
|
import Summoner from 'App/Models/Summoner'
|
||||||
import MatchRepository from 'App/Repositories/MatchRepository'
|
import MatchRepository from 'App/Repositories/MatchRepository'
|
||||||
import BasicMatchSerializer from 'App/Serializers/BasicMatchSerializer'
|
import BasicMatchSerializer from 'App/Serializers/BasicMatchSerializer'
|
||||||
|
import LiveMatchSerializer from 'App/Serializers/LiveMatchSerializer'
|
||||||
import Jax from 'App/Services/Jax'
|
import Jax from 'App/Services/Jax'
|
||||||
import MatchService from 'App/Services/MatchService'
|
import MatchService from 'App/Services/MatchService'
|
||||||
import StatsService from 'App/Services/StatsService'
|
import StatsService from 'App/Services/StatsService'
|
||||||
import SummonerService from 'App/Services/SummonerService'
|
import SummonerService from 'App/Services/SummonerService'
|
||||||
import SummonerBasicValidator from 'App/Validators/SummonerBasicValidator'
|
import SummonerBasicValidator from 'App/Validators/SummonerBasicValidator'
|
||||||
|
import SummonerLiveValidator from 'App/Validators/SummonerLiveValidator'
|
||||||
import SummonerOverviewValidator from 'App/Validators/SummonerOverviewValidator'
|
import SummonerOverviewValidator from 'App/Validators/SummonerOverviewValidator'
|
||||||
import SummonerRecordValidator from 'App/Validators/SummonerRecordValidator'
|
import SummonerRecordValidator from 'App/Validators/SummonerRecordValidator'
|
||||||
|
|
||||||
|
|
@ -104,4 +106,25 @@ export default class SummonersController {
|
||||||
console.timeEnd('recordsRequest')
|
console.timeEnd('recordsRequest')
|
||||||
return response.json(recordsSerialized)
|
return response.json(recordsSerialized)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST - Return live match detail
|
||||||
|
* @param ctx
|
||||||
|
*/
|
||||||
|
public async liveMatchDetails({ request, response }: HttpContextContract) {
|
||||||
|
console.time('liveMatchDetails')
|
||||||
|
const { id, region } = await request.validate(SummonerLiveValidator)
|
||||||
|
|
||||||
|
// CURRENT GAME
|
||||||
|
const currentGame = await Jax.Spectator.summonerID(id, region)
|
||||||
|
|
||||||
|
if (!currentGame) {
|
||||||
|
return response.json(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentGameSerialized = await LiveMatchSerializer.serializeOneMatch(currentGame, region)
|
||||||
|
console.timeEnd('liveMatchDetails')
|
||||||
|
|
||||||
|
return response.json(currentGameSerialized)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
81
server-v2/app/Serializers/LiveMatchSerializer.ts
Normal file
81
server-v2/app/Serializers/LiveMatchSerializer.ts
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
import { PlayerRole, queuesWithRole } from 'App/helpers'
|
||||||
|
import CDragonService from 'App/Services/CDragonService'
|
||||||
|
import { CurrentGameInfoDTO } from 'App/Services/Jax/src/Endpoints/SpectatorEndpoint'
|
||||||
|
import { RoleComposition } from 'App/Services/RoleIdentificationService'
|
||||||
|
import SummonerService from 'App/Services/SummonerService'
|
||||||
|
import MatchSerializer from './MatchSerializer'
|
||||||
|
import { SerializedLiveMatch, SerializedLiveMatchPlayer } from './SerializedTypes'
|
||||||
|
|
||||||
|
class LiveMatchSerializer extends MatchSerializer {
|
||||||
|
public async serializeOneMatch(
|
||||||
|
liveMatch: CurrentGameInfoDTO,
|
||||||
|
region: string
|
||||||
|
): Promise<SerializedLiveMatch> {
|
||||||
|
// Roles
|
||||||
|
const blueTeam: PlayerRole[] = [] // 100
|
||||||
|
const redTeam: PlayerRole[] = [] // 200
|
||||||
|
let blueRoles: RoleComposition = {}
|
||||||
|
let redRoles: RoleComposition = {}
|
||||||
|
const needsRole =
|
||||||
|
CDragonService.championRoles &&
|
||||||
|
(queuesWithRole.includes(liveMatch.gameQueueConfigId) ||
|
||||||
|
(liveMatch.gameType === 'CUSTOM_GAME' && liveMatch.participants.length === 10))
|
||||||
|
|
||||||
|
if (needsRole) {
|
||||||
|
liveMatch.participants.map((p) => {
|
||||||
|
const playerRole = {
|
||||||
|
champion: p.championId,
|
||||||
|
jungle: p.spell1Id === 11 || p.spell2Id === 11,
|
||||||
|
}
|
||||||
|
p.teamId === 100 ? blueTeam.push(playerRole) : redTeam.push(playerRole)
|
||||||
|
})
|
||||||
|
|
||||||
|
blueRoles = super.getTeamRoles(blueTeam)
|
||||||
|
redRoles = super.getTeamRoles(redTeam)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ranks
|
||||||
|
const requestsRanks = liveMatch.participants.map((p) =>
|
||||||
|
SummonerService.getRanked(p.summonerId, region)
|
||||||
|
)
|
||||||
|
const ranks = await Promise.all(requestsRanks)
|
||||||
|
|
||||||
|
// Players
|
||||||
|
const players: SerializedLiveMatchPlayer[] = liveMatch.participants.map((player, index) => {
|
||||||
|
let role: string | undefined
|
||||||
|
|
||||||
|
// Roles
|
||||||
|
if (needsRole) {
|
||||||
|
const roles = player.teamId === 100 ? blueRoles : redRoles
|
||||||
|
role = Object.entries(roles).find(([, champion]) => player.championId === champion)![0]
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...player,
|
||||||
|
role,
|
||||||
|
rank: ranks[index],
|
||||||
|
champion: this.getChampion(player.championId),
|
||||||
|
perks: {
|
||||||
|
primaryStyle: player.perks.perkStyle,
|
||||||
|
secondaryStyle: player.perks.perkSubStyle,
|
||||||
|
selected: player.perks.perkIds,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
gameId: liveMatch.gameId,
|
||||||
|
gameType: liveMatch.gameType,
|
||||||
|
gameStartTime: liveMatch.gameStartTime,
|
||||||
|
mapId: liveMatch.mapId,
|
||||||
|
gameLength: liveMatch.gameLength,
|
||||||
|
platformId: liveMatch.platformId,
|
||||||
|
gameMode: liveMatch.gameMode,
|
||||||
|
bannedChampions: liveMatch.bannedChampions,
|
||||||
|
gameQueueConfigId: liveMatch.gameQueueConfigId,
|
||||||
|
observers: liveMatch.observers,
|
||||||
|
participants: players,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new LiveMatchSerializer()
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
|
import { PlayerRole } from 'App/helpers'
|
||||||
import MatchPlayer from 'App/Models/MatchPlayer'
|
import MatchPlayer from 'App/Models/MatchPlayer'
|
||||||
import MatchPlayerRank from 'App/Models/MatchPlayerRank'
|
import MatchPlayerRank from 'App/Models/MatchPlayerRank'
|
||||||
import { PlayerRankParsed, TeamPosition } from 'App/Parsers/ParsedType'
|
import { PlayerRankParsed, TeamPosition } from 'App/Parsers/ParsedType'
|
||||||
import CDragonService from 'App/Services/CDragonService'
|
import CDragonService from 'App/Services/CDragonService'
|
||||||
|
import RoleIdentificationService, { RoleComposition } from 'App/Services/RoleIdentificationService'
|
||||||
import SummonerService from 'App/Services/SummonerService'
|
import SummonerService from 'App/Services/SummonerService'
|
||||||
import {
|
import {
|
||||||
SerializedBasePlayer,
|
SerializedBasePlayer,
|
||||||
|
|
@ -112,4 +114,22 @@ export default abstract class MatchSerializer {
|
||||||
shortName: SummonerService.getRankedShortName(rank),
|
shortName: SummonerService.getRankedShortName(rank),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the 5 roles of a team based on champions
|
||||||
|
* @param team 5 champions + smite from a team
|
||||||
|
*/
|
||||||
|
protected getTeamRoles(team: PlayerRole[]): RoleComposition {
|
||||||
|
const teamJunglers = team.filter((p) => p.jungle && !p.support)
|
||||||
|
const jungle = teamJunglers.length === 1 ? teamJunglers[0].champion : undefined
|
||||||
|
const teamSupports = team.filter((p) => p.support && !p.jungle)
|
||||||
|
const support = teamSupports.length === 1 ? teamSupports[0].champion : undefined
|
||||||
|
|
||||||
|
return RoleIdentificationService.getRoles(
|
||||||
|
CDragonService.championRoles,
|
||||||
|
team.map((p) => p.champion),
|
||||||
|
jungle,
|
||||||
|
support
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
import {
|
||||||
|
CurrentGameInfoDTO,
|
||||||
|
GameCustomizationObjectDTO,
|
||||||
|
} from 'App/Services/Jax/src/Endpoints/SpectatorEndpoint'
|
||||||
|
import { LeagueEntriesByQueue } from 'App/Services/SummonerService'
|
||||||
|
|
||||||
export interface SerializedBasePlayer {
|
export interface SerializedBasePlayer {
|
||||||
champion: SerializedMatchChampion
|
champion: SerializedMatchChampion
|
||||||
items: Array<SerializedMatchItem | null>
|
items: Array<SerializedMatchItem | null>
|
||||||
|
|
@ -178,3 +184,28 @@ export interface SerializedPlayerRank {
|
||||||
losses: number
|
losses: number
|
||||||
shortName: number | string
|
shortName: number | string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================
|
||||||
|
|
||||||
|
Live Match
|
||||||
|
|
||||||
|
============================ */
|
||||||
|
export interface SerializedLiveMatch extends Omit<CurrentGameInfoDTO, 'participants'> {
|
||||||
|
participants: SerializedLiveMatchPlayer[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SerializedLiveMatchPlayer {
|
||||||
|
bot: boolean
|
||||||
|
champion: SerializedMatchChampion
|
||||||
|
championId: number
|
||||||
|
gameCustomizationObjects: GameCustomizationObjectDTO[]
|
||||||
|
perks: SerializedMatchPerks
|
||||||
|
profileIconId: number
|
||||||
|
rank: LeagueEntriesByQueue
|
||||||
|
role?: string
|
||||||
|
spell1Id: number
|
||||||
|
spell2Id: number
|
||||||
|
summonerId: string
|
||||||
|
summonerName: string
|
||||||
|
teamId: number
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
// import { RiotRateLimiter } from '@fightmegg/riot-rate-limiter'
|
// import { RiotRateLimiter } from '@fightmegg/riot-rate-limiter'
|
||||||
import RiotRateLimiter from 'riot-ratelimiter'
|
import RiotRateLimiter from 'riot-ratelimiter'
|
||||||
import { LeagueEntriesByQueue } from 'App/Services/SummonerService'
|
|
||||||
import { JaxConfig } from '../../JaxConfig'
|
import { JaxConfig } from '../../JaxConfig'
|
||||||
import JaxRequest from '../JaxRequest'
|
import JaxRequest from '../JaxRequest'
|
||||||
|
|
||||||
export interface CurrentGameInfo {
|
export interface CurrentGameInfoDTO {
|
||||||
gameId: number
|
gameId: number
|
||||||
gameType: string
|
gameType: string
|
||||||
gameStartTime: number
|
gameStartTime: number
|
||||||
|
|
@ -12,25 +11,25 @@ export interface CurrentGameInfo {
|
||||||
gameLength: number
|
gameLength: number
|
||||||
platformId: string
|
platformId: string
|
||||||
gameMode: string
|
gameMode: string
|
||||||
bannedChampions: BannedChampion[]
|
bannedChampions: BannedChampionDTO[]
|
||||||
gameQueueConfigId: number
|
gameQueueConfigId: number
|
||||||
observers: Observer
|
observers: ObserverDTO
|
||||||
participants: CurrentGameParticipant[]
|
participants: CurrentGameParticipantDTO[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BannedChampion {
|
export interface BannedChampionDTO {
|
||||||
pickTurn: number
|
pickTurn: number
|
||||||
championId: number
|
championId: number
|
||||||
teamId: number
|
teamId: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Observer {
|
export interface ObserverDTO {
|
||||||
encryptionKey: string
|
encryptionKey: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CurrentGameParticipant {
|
export interface CurrentGameParticipantDTO {
|
||||||
championId: number
|
championId: number
|
||||||
perks: Perks
|
perks: PerksDTO
|
||||||
profileIconId: number
|
profileIconId: number
|
||||||
bot: boolean
|
bot: boolean
|
||||||
teamId: number
|
teamId: number
|
||||||
|
|
@ -38,21 +37,16 @@ export interface CurrentGameParticipant {
|
||||||
summonerId: string
|
summonerId: string
|
||||||
spell1Id: number
|
spell1Id: number
|
||||||
spell2Id: number
|
spell2Id: number
|
||||||
gameCustomizationObjects: GameCustomizationObject[]
|
gameCustomizationObjects: GameCustomizationObjectDTO[]
|
||||||
// Custom types from here
|
|
||||||
role?: string
|
|
||||||
runes?: { primaryRune: string; secondaryRune: string } | {}
|
|
||||||
level?: number
|
|
||||||
rank?: LeagueEntriesByQueue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Perks {
|
export interface PerksDTO {
|
||||||
perkIds: number[]
|
perkIds: number[]
|
||||||
perkStyle: number
|
perkStyle: number
|
||||||
perkSubStyle: number
|
perkSubStyle: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GameCustomizationObject {
|
export interface GameCustomizationObjectDTO {
|
||||||
category: string
|
category: string
|
||||||
content: string
|
content: string
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +60,7 @@ export default class SpectatorEndpoint {
|
||||||
this.limiter = limiter
|
this.limiter = limiter
|
||||||
}
|
}
|
||||||
|
|
||||||
public summonerID(summonerID: string, region: string): Promise<CurrentGameInfo | undefined> {
|
public summonerID(summonerID: string, region: string): Promise<CurrentGameInfoDTO | undefined> {
|
||||||
return new JaxRequest(
|
return new JaxRequest(
|
||||||
region,
|
region,
|
||||||
this.config,
|
this.config,
|
||||||
|
|
|
||||||
43
server-v2/app/Validators/SummonerLiveValidator.ts
Normal file
43
server-v2/app/Validators/SummonerLiveValidator.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { schema } from '@ioc:Adonis/Core/Validator'
|
||||||
|
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
||||||
|
|
||||||
|
export default class SummonerLiveValidator {
|
||||||
|
constructor(protected ctx: HttpContextContract) {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define schema to validate the "shape", "type", "formatting" and "integrity" of data.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* 1. The username must be of data type string. But then also, it should
|
||||||
|
* not contain special characters or numbers.
|
||||||
|
* ```
|
||||||
|
* schema.string({}, [ rules.alpha() ])
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 2. The email must be of data type string, formatted as a valid
|
||||||
|
* email. But also, not used by any other user.
|
||||||
|
* ```
|
||||||
|
* schema.string({}, [
|
||||||
|
* rules.email(),
|
||||||
|
* rules.unique({ table: 'users', column: 'email' }),
|
||||||
|
* ])
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public schema = schema.create({
|
||||||
|
id: schema.string(),
|
||||||
|
region: schema.string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom messages for validation failures. You can make use of dot notation `(.)`
|
||||||
|
* for targeting nested fields and array expressions `(*)` for targeting all
|
||||||
|
* children of an array. For example:
|
||||||
|
*
|
||||||
|
* {
|
||||||
|
* 'profile.username.required': 'Username is required',
|
||||||
|
* 'scores.*.number': 'Define scores as valid numbers'
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public messages = {}
|
||||||
|
}
|
||||||
|
|
@ -50,6 +50,15 @@ export function getRiotRegion(region: string): RiotRegion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to help define a player's role
|
||||||
|
*/
|
||||||
|
export interface PlayerRole {
|
||||||
|
champion: number
|
||||||
|
jungle?: boolean
|
||||||
|
support?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* League of Legends queues with defined role for each summoner
|
* League of Legends queues with defined role for each summoner
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ Route.post('/summoner/overview', 'SummonersController.overview')
|
||||||
|
|
||||||
// Route.post('/summoner/champions', 'SummonersController.champions')
|
// Route.post('/summoner/champions', 'SummonersController.champions')
|
||||||
Route.post('/summoner/records', 'SummonersController.records')
|
Route.post('/summoner/records', 'SummonersController.records')
|
||||||
// Route.post('/summoner/live', 'SummonersController.liveMatchDetails')
|
Route.post('/summoner/live', 'SummonersController.liveMatchDetails')
|
||||||
|
|
||||||
Route.post('/match', 'MatchesController.index')
|
Route.post('/match', 'MatchesController.index')
|
||||||
Route.post('/match/details', 'MatchesController.show')
|
Route.post('/match/details', 'MatchesController.show')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue