Add skins overview for champions

This commit is contained in:
BlossomiShymae
2024-09-14 17:35:32 -05:00
parent c51a215720
commit 58dd774cd4
4 changed files with 124 additions and 4 deletions

View File

@@ -1,4 +1,4 @@
import { Champion, ChampionSummary, Item, LocaleVersionArgs, Perk, SummonerEmote, SummonerIcon, WardSkin, Companion, Loot, CherryAugment, Universe, TftItem, TftMapSkin, TftDamageSkin } from './models';
import { Champion, ChampionSummary, Item, LocaleVersionArgs, Perk, SummonerEmote, SummonerIcon, WardSkin, Companion, Loot, CherryAugment, Universe, TftItem, TftMapSkin, TftDamageSkin, Skin } from './models';
import axios from "axios";
export abstract class ApiObject {
@@ -24,6 +24,7 @@ export class Client {
public tftItems: TftItemApi;
public tftMapSkins: TftMapSkinApi;
public tftDamageSkins: TftDamageSkinApi;
public skins: SkinApi;
constructor() {
this.items = new ItemApi();
@@ -40,6 +41,7 @@ export class Client {
this.tftItems = new TftItemApi();
this.tftMapSkins = new TftMapSkinApi();
this.tftDamageSkins = new TftDamageSkinApi();
this.skins = new SkinApi();
}
}
@@ -140,3 +142,10 @@ export class TftDamageSkinApi extends ApiObject {
return res.data.map((x: any) => new TftDamageSkin(x));
}
}
export class SkinApi extends ApiObject {
async listAsync(args: LocaleVersionArgs): Promise<Array<Skin>> {
let res = await axios.get(`${this.getClientPath(args)}/v1/skins.json`);
return Object.entries(res.data).map(([key, value]) => new Skin(value));
}
}

View File

@@ -74,6 +74,12 @@ export class Skin extends CommunityDragonObject {
rarity: string;
isLegacy: boolean;
loadScreenPath: string;
splashPath: string;
uncenteredSplashPath: string;
tilePath: string;
description?: string;
skinLines?: Array<SkinLine>;
constructor(json: any) {
super();
@@ -84,11 +90,38 @@ export class Skin extends CommunityDragonObject {
this.rarity = json.rarity;
this.isLegacy = json.isLegacy;
this.loadScreenPath = json.loadScreenPath;
this.splashPath = json.splashPath;
this.uncenteredSplashPath = json.uncenteredSplashPath;
this.tilePath = json.tilePath;
this.description = json.description;
this.skinLines = json.skinLines?.map((x: any) => new SkinLine(x)) ?? null;
}
getLoadScreen(version: string): string {
return this.resolveGamePath({path: this.loadScreenPath, version: version});
}
getSplash(args: LocaleVersionArgs): string {
return this.resolveClientPath({path: this.splashPath, args: args});
}
getUncenteredSplash(args: LocaleVersionArgs): string {
return this.resolveClientPath({path: this.uncenteredSplashPath, args: args});
}
getTile(args: LocaleVersionArgs): string {
return this.resolveClientPath({path: this.tilePath, args: args});
}
}
export class SkinLine extends CommunityDragonObject {
id: number;
constructor(json: any) {
super();
this.id = json.id;
}
}
export class Passive extends CommunityDragonObject {

View File

@@ -27,7 +27,9 @@
<div class="col-md-6 col-sm-12">
<div class="d-flex justify-content-between mb-2">
<div style="min-height: 560px; min-width: 308px;" id="champion-loading-screen">
<img class="border border-light border-opacity-25 rounded" :src="currentSkin" loading="lazy" />
<NuxtLink class="text-decoration-none" :to="`/skins/overview/${currentSkin.id}`">
<img class="border border-light border-opacity-25 rounded" :src="currentSkin.getLoadScreen('latest')" loading="lazy" />
</NuxtLink>
</div>
<div class="d-flex flex-row flex-wrap align-items-center gap-2 border-start border-5 border-light border-opacity-10 ms-0 ps-2">
<button class="btn btn-dark flex-grow-1 border-light border-opacity-25 bg-transparent bg-blur-3"
@@ -50,6 +52,7 @@ import Badge from '~/components/Badge.vue';
import { useRoute } from 'vue-router';
import useClient from '../../../composables/useClient';
import useLocale from '~/composables/useLocale';
import { Skin } from '../../../core/models';
const route = useRoute();
const id = route.params.id as unknown;
@@ -63,8 +66,8 @@ watch(currentLocale, async () => {
champion.value = await getChampion();
});
const currentSkin = ref(champion.value.skins[0].getLoadScreen('latest'));
const currentSkin = ref(champion.value.skins[0]);
const swapLoadScreen = (id: number) => {
currentSkin.value = champion.value.skins.find((x) => x.id == id)?.getLoadScreen('latest') as string;
currentSkin.value = champion.value.skins.find((x) => x.id == id) as Skin;
}
</script>

View File

@@ -0,0 +1,75 @@
<template>
<div class="row">
<div data-aos="fade-right" data-aos-duration="1000">
<div>
<h1 class="display-4">{{ skin!.name }}</h1>
<p v-if="skin?.description">{{ skin.description }}</p>
</div>
<ul class="nav nav-tabs mb-4">
<li class="nav-item">
<button class="nav-link text-light"
:class="{'active': selector == 'splash'}" @click="selector = 'splash'">Splash</button>
</li>
<li class="nav-item">
<button class="nav-link text-light"
:class="{'active': selector == 'uncenteredSplash'}" @click="selector = 'uncenteredSplash'">Uncentered Splash</button>
</li>
<li class="nav-item text-light">
<button class="nav-link text-light"
:class="{'active': selector == 'tile'}" @click="selector = 'tile'">Tile</button>
</li>
</ul>
</div>
<div class="d-flex justify-content-center align-items-center mb-4"
data-aos="fade-left" data-aos-duration="1000">
<img class="img-fluid" :src="selection"/>
</div>
<div v-if="skinUniverses.length > 0">
<h5 class="border-bottom border-light border-opacity-25 border-2 mb-2 pb-2">Universes</h5>
<div v-for="skinUniverse in skinUniverses">
<div v-if="skinUniverse" :id="`${skinUniverse!.id}`">
<h6 class="fw-bold">{{ skinUniverse?.name }}</h6>
<p class="ms-2">{{ skinUniverse?.description }}</p>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import useClient from '~/composables/useClient';
import useLocale from '~/composables/useLocale';
const route = useRoute();
const id = route.params.id as unknown;
const { client } = useClient();
const { currentLocale } = useLocale();
const getSkins = async () => await client.skins.listAsync({ locale: currentLocale.value, version: "latest"});
const getUniverses = async () => await client.universes.listAsync({ locale: currentLocale.value, version: "latest"});
const skins = ref(await getSkins());
const universes = ref(await getUniverses());
watch(currentLocale, async() => {
skins.value = await getSkins();
universes.value = await getUniverses();
});
const skin = computed(() => skins.value.find((x) => x.id == id));
const selector = ref("splash");
const selection = computed(() => {
switch (selector.value) {
case "splash":
return skin.value!.getSplash({locale: currentLocale.value, version: "latest"});
case "uncenteredSplash":
return skin.value!.getUncenteredSplash({locale: currentLocale.value, version: "latest"});
case "tile":
return skin.value!.getTile({locale: currentLocale.value, version: "latest"});
default:
return "/img/error.png";
}
});
const skinUniverses = computed(() => skin.value?.skinLines
?.map((x) => universes.value.find((y) => y.skinSets.includes(x.id)))
.filter(x => x != null) ?? []);
</script>