fix: Resolve avatar display issues on chat and player pages
Chat page: - Fix player lookup using player_name instead of player_id to avoid JavaScript number precision loss with 64-bit Steam IDs - Update player filter dropdown to use names instead of IDs Player page (Teammates): - Construct full avatar URLs from hash when backend returns hash format - Handle both full URLs and hashes with startsWith check 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
let searchQuery = $state('');
|
||||
let showTeamChat = $state(true);
|
||||
let showAllChat = $state(true);
|
||||
let selectedPlayer = $state<number | null>(null);
|
||||
let selectedPlayer = $state<string | null>(null);
|
||||
|
||||
// Check if text likely needs translation (contains non-ASCII or Cyrillic characters)
|
||||
const mightNeedTranslation = (text: string): boolean => {
|
||||
@@ -34,16 +34,15 @@
|
||||
window.open(translateUrl, '_blank', 'width=800,height=600,noopener,noreferrer');
|
||||
};
|
||||
|
||||
// Get unique players who sent messages
|
||||
// Get unique players who sent messages (using player_name to avoid precision loss with player_id)
|
||||
const messagePlayers = $derived(
|
||||
chatData
|
||||
? Array.from(new Set(chatData.messages.map((m) => m.player_id)))
|
||||
.filter((playerId): playerId is number => playerId !== undefined)
|
||||
.map((playerId) => {
|
||||
const player = match.players?.find((p) => p.id === String(playerId));
|
||||
? Array.from(new Set(chatData.messages.map((m) => m.player_name || `Player ${m.player_id}`)))
|
||||
.filter((name): name is string => !!name)
|
||||
.map((name) => {
|
||||
const player = match.players?.find((p) => p.name === name);
|
||||
return {
|
||||
id: playerId,
|
||||
name: player?.name || `Player ${playerId}`,
|
||||
name,
|
||||
team_id: player?.team_id || 0
|
||||
};
|
||||
})
|
||||
@@ -56,7 +55,8 @@
|
||||
? chatData.messages.filter((msg) => {
|
||||
if (!showTeamChat && !msg.all_chat) return false;
|
||||
if (!showAllChat && msg.all_chat) return false;
|
||||
if (selectedPlayer !== null && msg.player_id !== selectedPlayer) return false;
|
||||
const msgPlayerName = msg.player_name || `Player ${msg.player_id}`;
|
||||
if (selectedPlayer !== null && msgPlayerName !== selectedPlayer) return false;
|
||||
if (searchQuery && !msg.message.toLowerCase().includes(searchQuery.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
@@ -204,7 +204,7 @@
|
||||
>
|
||||
<option value={null}>All Players</option>
|
||||
{#each messagePlayers as player}
|
||||
<option value={player.id}>{player.name}</option>
|
||||
<option value={player.name}>{player.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
@@ -256,9 +256,8 @@
|
||||
<!-- Messages -->
|
||||
<div class="divide-y divide-white/5">
|
||||
{#each messagesByRound[round] as message}
|
||||
{@const player = match.players?.find((p) => p.id === String(message.player_id))}
|
||||
{@const playerName =
|
||||
message.player_name || player?.name || `Player ${message.player_id}`}
|
||||
{@const playerName = message.player_name || `Player ${message.player_id}`}
|
||||
{@const player = match.players?.find((p) => p.name === playerName)}
|
||||
{@const playerAvatar = player?.avatar}
|
||||
{@const teamId = player?.team_id || 0}
|
||||
<div class="p-4 transition-colors hover:bg-white/5">
|
||||
|
||||
@@ -1125,6 +1125,11 @@
|
||||
<div class="space-y-3">
|
||||
{#each metaStats.best_mates.slice(0, 5) as teammate}
|
||||
{@const winRatePercent = (teammate.win_rate ?? 0) * 100}
|
||||
{@const avatarUrl = teammate.player.avatar
|
||||
? teammate.player.avatar.startsWith('http')
|
||||
? teammate.player.avatar
|
||||
: `https://avatars.steamstatic.com/${teammate.player.avatar}_full.jpg`
|
||||
: null}
|
||||
<a
|
||||
href="/player/{teammate.player.steamid64}"
|
||||
class="group flex items-center gap-3 rounded-lg bg-white/5 p-3 transition-all hover:bg-white/10"
|
||||
@@ -1132,9 +1137,9 @@
|
||||
<div
|
||||
class="relative flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-white/10 bg-void"
|
||||
>
|
||||
{#if teammate.player.avatar}
|
||||
{#if avatarUrl}
|
||||
<img
|
||||
src={teammate.player.avatar}
|
||||
src={avatarUrl}
|
||||
alt={teammate.player.name || 'Player'}
|
||||
class="h-full w-full rounded-full object-cover"
|
||||
onerror={(e) => {
|
||||
@@ -1190,6 +1195,11 @@
|
||||
<div class="space-y-3">
|
||||
{#each metaStats.most_mates.slice(0, 5) as teammate}
|
||||
{@const winRatePercent = (teammate.win_rate ?? 0) * 100}
|
||||
{@const avatarUrl = teammate.player.avatar
|
||||
? teammate.player.avatar.startsWith('http')
|
||||
? teammate.player.avatar
|
||||
: `https://avatars.steamstatic.com/${teammate.player.avatar}_full.jpg`
|
||||
: null}
|
||||
<a
|
||||
href="/player/{teammate.player.steamid64}"
|
||||
class="group flex items-center gap-3 rounded-lg bg-white/5 p-3 transition-all hover:bg-white/10"
|
||||
@@ -1197,9 +1207,9 @@
|
||||
<div
|
||||
class="relative flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-white/10 bg-void"
|
||||
>
|
||||
{#if teammate.player.avatar}
|
||||
{#if avatarUrl}
|
||||
<img
|
||||
src={teammate.player.avatar}
|
||||
src={avatarUrl}
|
||||
alt={teammate.player.name || 'Player'}
|
||||
class="h-full w-full rounded-full object-cover"
|
||||
onerror={(e) => {
|
||||
|
||||
Reference in New Issue
Block a user