tauri-app: use fields from recorded raw league data
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m6s
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m6s
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import type { GameHistoryItem, TimestampedEvent, ItemInfo, RawEndGameStats, EndGamePlayer } from "../types/timeline";
|
||||
import type { GameHistoryItem, TimestampedEvent, ItemInfo } from "../types/timeline";
|
||||
import {
|
||||
getGameResult,
|
||||
formatDuration,
|
||||
@@ -16,6 +16,15 @@ import {
|
||||
formatGameStartTime,
|
||||
getSummonerSpellUrl,
|
||||
getItemImageUrl,
|
||||
getChampionName,
|
||||
getSummonerName,
|
||||
getQueueType,
|
||||
getQueueId,
|
||||
getGameMode,
|
||||
getMapName,
|
||||
getFinalStats,
|
||||
getSummonerSpells,
|
||||
getItems,
|
||||
} from "../types/timeline";
|
||||
|
||||
// Helper to get video timestamp in seconds from tuple format
|
||||
@@ -49,58 +58,9 @@ function closeDetail() {
|
||||
selectedGame.value = null;
|
||||
}
|
||||
|
||||
// Helper to find local player from raw end game stats
|
||||
function getLocalPlayer(stats: RawEndGameStats | null): EndGamePlayer | null {
|
||||
if (!stats) return null;
|
||||
|
||||
// Try localPlayer field first (camelCase from API)
|
||||
if (stats.localPlayer) {
|
||||
return stats.localPlayer;
|
||||
}
|
||||
|
||||
// Try teams
|
||||
if (stats.teams) {
|
||||
for (const team of stats.teams) {
|
||||
if (team.players) {
|
||||
for (const player of team.players) {
|
||||
if (player.isLocalPlayer) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try legacy players array
|
||||
if (stats.players && stats.players.length > 0) {
|
||||
return stats.players[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Helper to get items array for display (6 slots + trinket)
|
||||
// Items are now stored as raw item IDs in raw_end_game_stats
|
||||
function getItemsArray(game: GameHistoryItem): (ItemInfo | null)[] {
|
||||
const result: (ItemInfo | null)[] = [null, null, null, null, null, null, null];
|
||||
|
||||
const localPlayer = getLocalPlayer(game.raw_end_game_stats);
|
||||
if (localPlayer && localPlayer.items) {
|
||||
// Items are stored as an array of item IDs (up to 7 items: 6 main + 1 trinket)
|
||||
for (let i = 0; i < Math.min(localPlayer.items.length, 7); i++) {
|
||||
const itemId = localPlayer.items[i];
|
||||
if (itemId && itemId > 0) {
|
||||
// Slot 6 is trinket, slots 0-5 are main items
|
||||
result[i] = {
|
||||
itemId: itemId,
|
||||
name: null,
|
||||
slot: i
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return getItems(game);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@@ -161,13 +121,13 @@ onMounted(() => {
|
||||
<div class="champion-section">
|
||||
<div class="champion-image-wrapper">
|
||||
<img
|
||||
:src="getChampionImageUrl(game.champion)"
|
||||
:alt="game.champion || 'Unknown Champion'"
|
||||
:src="getChampionImageUrl(getChampionName(game))"
|
||||
:alt="getChampionName(game) || 'Unknown Champion'"
|
||||
class="champion-image"
|
||||
@error="($event.target as HTMLImageElement).src = getChampionImageUrl(null)"
|
||||
/>
|
||||
<div class="champion-level" v-if="game.final_stats">
|
||||
{{ Math.min(18, Math.floor(game.final_stats.game_duration / 60)) }}
|
||||
<div class="champion-level" v-if="getFinalStats(game)">
|
||||
{{ Math.min(18, Math.floor(getFinalStats(game)!.game_duration / 60)) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -175,18 +135,18 @@ onMounted(() => {
|
||||
<div class="summoner-spells">
|
||||
<div class="spell-slot">
|
||||
<img
|
||||
v-if="game.summoner_spells"
|
||||
:src="getSummonerSpellUrl(game.summoner_spells.spell1Id)"
|
||||
:alt="game.summoner_spells.spell1Name || 'Spell 1'"
|
||||
v-if="getSummonerSpells(game)"
|
||||
:src="getSummonerSpellUrl(getSummonerSpells(game)!.spell1Id)"
|
||||
:alt="getSummonerSpells(game)!.spell1Name || 'Spell 1'"
|
||||
class="spell-image"
|
||||
/>
|
||||
<div v-else class="spell-placeholder"></div>
|
||||
</div>
|
||||
<div class="spell-slot">
|
||||
<img
|
||||
v-if="game.summoner_spells"
|
||||
:src="getSummonerSpellUrl(game.summoner_spells.spell2Id)"
|
||||
:alt="game.summoner_spells.spell2Name || 'Spell 2'"
|
||||
v-if="getSummonerSpells(game)"
|
||||
:src="getSummonerSpellUrl(getSummonerSpells(game)!.spell2Id)"
|
||||
:alt="getSummonerSpells(game)!.spell2Name || 'Spell 2'"
|
||||
class="spell-image"
|
||||
/>
|
||||
<div v-else class="spell-placeholder"></div>
|
||||
@@ -200,7 +160,7 @@ onMounted(() => {
|
||||
<!-- Left: Queue Type & Time -->
|
||||
<div class="game-info-left">
|
||||
<div class="queue-type">
|
||||
{{ getQueueDisplayName(game.queue_type, game.queue_id) }}
|
||||
{{ getQueueDisplayName(getQueueType(game), getQueueId(game)) }}
|
||||
</div>
|
||||
<div class="game-duration">
|
||||
{{ formatDuration(game.duration_secs) }}
|
||||
@@ -211,12 +171,12 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<!-- Right: KDA Score -->
|
||||
<div class="kda-section" v-if="game.final_stats">
|
||||
<div class="kda-section" v-if="getFinalStats(game)">
|
||||
<span class="kda-values">
|
||||
{{ formatKDA(game.final_stats) }}
|
||||
{{ formatKDA(getFinalStats(game)) }}
|
||||
</span>
|
||||
<span class="kda-ratio" :class="{ perfect: game.final_stats.deaths === 0 }">
|
||||
{{ calculateKDA(game.final_stats) }} KDA
|
||||
<span class="kda-ratio" :class="{ perfect: getFinalStats(game)!.deaths === 0 }">
|
||||
{{ calculateKDA(getFinalStats(game)) }} KDA
|
||||
</span>
|
||||
</div>
|
||||
<div class="kda-section" v-else>
|
||||
@@ -227,15 +187,15 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<!-- Right: Key Stats Column + Items -->
|
||||
<div class="stats-section" v-if="game.final_stats">
|
||||
<div class="stats-section" v-if="getFinalStats(game)">
|
||||
<!-- Key Stats Column -->
|
||||
<div class="key-stats-column">
|
||||
<div class="key-stat">
|
||||
<span class="key-stat-value">{{ formatCSPerMin(game.final_stats) }}</span>
|
||||
<span class="key-stat-value">{{ formatCSPerMin(getFinalStats(game)) }}</span>
|
||||
<span class="key-stat-label">CS/m</span>
|
||||
</div>
|
||||
<div class="key-stat">
|
||||
<span class="key-stat-value">{{ formatGoldPerMin(game.final_stats) }}</span>
|
||||
<span class="key-stat-value">{{ formatGoldPerMin(getFinalStats(game)) }}</span>
|
||||
<span class="key-stat-label">Gold/m</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -277,14 +237,14 @@ onMounted(() => {
|
||||
<div class="modal-header">
|
||||
<div class="modal-champion">
|
||||
<img
|
||||
:src="getChampionImageUrl(selectedGame.champion)"
|
||||
:alt="selectedGame.champion || 'Unknown Champion'"
|
||||
:src="getChampionImageUrl(getChampionName(selectedGame))"
|
||||
:alt="getChampionName(selectedGame) || 'Unknown Champion'"
|
||||
class="modal-champion-image"
|
||||
/>
|
||||
<div class="modal-champion-info">
|
||||
<h2>{{ selectedGame.champion || 'Unknown Champion' }}</h2>
|
||||
<h2>{{ getChampionName(selectedGame) || 'Unknown Champion' }}</h2>
|
||||
<div class="modal-queue">
|
||||
{{ getQueueDisplayName(selectedGame.queue_type, selectedGame.queue_id) }}
|
||||
{{ getQueueDisplayName(getQueueType(selectedGame), getQueueId(selectedGame)) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -306,66 +266,62 @@ onMounted(() => {
|
||||
<span class="detail-label">Started:</span>
|
||||
<span class="detail-value">{{ formatGameStartTime(selectedGame.start_time) }}</span>
|
||||
</div>
|
||||
<div class="detail-row" v-if="selectedGame.game_mode">
|
||||
<div class="detail-row" v-if="getGameMode(selectedGame)">
|
||||
<span class="detail-label">Game Mode:</span>
|
||||
<span class="detail-value">{{ selectedGame.game_mode }}</span>
|
||||
<span class="detail-value">{{ getGameMode(selectedGame) }}</span>
|
||||
</div>
|
||||
<div class="detail-row" v-if="selectedGame.map_name">
|
||||
<div class="detail-row" v-if="getMapName(selectedGame)">
|
||||
<span class="detail-label">Map:</span>
|
||||
<span class="detail-value">{{ selectedGame.map_name }}</span>
|
||||
<span class="detail-value">{{ getMapName(selectedGame) }}</span>
|
||||
</div>
|
||||
<div class="detail-row" v-if="selectedGame.summoner_name">
|
||||
<div class="detail-row" v-if="getSummonerName(selectedGame)">
|
||||
<span class="detail-label">Summoner:</span>
|
||||
<span class="detail-value">{{ selectedGame.summoner_name }}</span>
|
||||
</div>
|
||||
<div class="detail-row" v-if="selectedGame.team">
|
||||
<span class="detail-label">Team:</span>
|
||||
<span class="detail-value">{{ selectedGame.team === 100 ? 'Blue' : 'Red' }}</span>
|
||||
<span class="detail-value">{{ getSummonerName(selectedGame) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="modal-section" v-if="selectedGame.final_stats">
|
||||
<div class="modal-section" v-if="getFinalStats(selectedGame)">
|
||||
<h3>Performance</h3>
|
||||
<div class="stats-highlight">
|
||||
<div class="stat-highlight-item">
|
||||
<span class="stat-highlight-value">{{ selectedGame.final_stats.kills }}</span>
|
||||
<span class="stat-highlight-value">{{ getFinalStats(selectedGame)!.kills }}</span>
|
||||
<span class="stat-highlight-label">Kills</span>
|
||||
</div>
|
||||
<div class="stat-highlight-item">
|
||||
<span class="stat-highlight-value">{{ selectedGame.final_stats.deaths }}</span>
|
||||
<span class="stat-highlight-value">{{ getFinalStats(selectedGame)!.deaths }}</span>
|
||||
<span class="stat-highlight-label">Deaths</span>
|
||||
</div>
|
||||
<div class="stat-highlight-item">
|
||||
<span class="stat-highlight-value">{{ selectedGame.final_stats.assists }}</span>
|
||||
<span class="stat-highlight-value">{{ getFinalStats(selectedGame)!.assists }}</span>
|
||||
<span class="stat-highlight-label">Assists</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-grid">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">KDA Ratio:</span>
|
||||
<span class="detail-value">{{ calculateKDA(selectedGame.final_stats) }}</span>
|
||||
<span class="detail-value">{{ calculateKDA(getFinalStats(selectedGame)) }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Creep Score:</span>
|
||||
<span class="detail-value">{{ selectedGame.final_stats.creep_score }} ({{ formatCSPerMin(selectedGame.final_stats) }}/min)</span>
|
||||
<span class="detail-value">{{ getFinalStats(selectedGame)!.creep_score }} ({{ formatCSPerMin(getFinalStats(selectedGame)) }}/min)</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Gold Earned:</span>
|
||||
<span class="detail-value">{{ formatNumber(selectedGame.final_stats.gold_earned) }} ({{ formatGoldPerMin(selectedGame.final_stats) }}/min)</span>
|
||||
<span class="detail-value">{{ formatNumber(getFinalStats(selectedGame)!.gold_earned) }} ({{ formatGoldPerMin(getFinalStats(selectedGame)) }}/min)</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Damage Dealt:</span>
|
||||
<span class="detail-value">{{ formatNumber(selectedGame.final_stats.damage_dealt) }}</span>
|
||||
<span class="detail-value">{{ formatNumber(getFinalStats(selectedGame)!.damage_dealt) }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Damage Taken:</span>
|
||||
<span class="detail-value">{{ formatNumber(selectedGame.final_stats.damage_taken) }}</span>
|
||||
<span class="detail-value">{{ formatNumber(getFinalStats(selectedGame)!.damage_taken) }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Vision Score:</span>
|
||||
<span class="detail-value">{{ selectedGame.final_stats.vision_score.toFixed(1) }}</span>
|
||||
<span class="detail-value">{{ getFinalStats(selectedGame)!.vision_score.toFixed(1) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user