Private
Public Access
1
0

new: usr: registered users have avatars next to the timer #4

This commit is contained in:
2026-04-13 21:09:27 +02:00
parent 3db8a30115
commit 055e59d896
5 changed files with 65 additions and 5 deletions

View File

@@ -49,6 +49,36 @@
box-shadow: 0 0 16px rgba(35, 111, 135, 0.75), 0 0 5px rgba(149, 207, 245, 0.5);
}
#mine-wrapper .game-timer .timer-avatar {
width: 26px;
height: 26px;
border-radius: 50%;
overflow: hidden;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
font-weight: bold;
font-family: 'Rajdhani', sans-serif;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.15);
}
#mine-wrapper .game-timer .timer-avatar__img {
width: 100%;
height: 100%;
object-fit: cover;
}
#mine-wrapper .game-timer.red-timer .timer-avatar__initials {
color: rgba(246, 125, 82, 0.85);
}
#mine-wrapper .game-timer.blue-timer .timer-avatar__initials {
color: rgba(149, 207, 245, 0.85);
}
#mine-wrapper .game-timer .timer-icon {
font-size: 15px;
opacity: 0.7;

View File

@@ -10,8 +10,20 @@
import React, { useEffect, useRef, useState } from 'react';
import { useGame } from '@mine-contexts';
const renderAvatar = player => {
if (!player.registered) return null;
return (
<div className="timer-avatar">
{player.avatar
? <img src={player.avatar} alt={player.name} className="timer-avatar__img" />
: <span className="timer-avatar__initials">{player.name.slice(0, 2).toUpperCase()}</span>
}
</div>
);
};
const GameTimer = () => {
const { overlay, connectionLost, endRef, activePlayer, webPlayer } = useGame();
const { overlay, connectionLost, endRef, activePlayer, red, blue } = useGame();
const [redTime, setRedTime] = useState(0);
const [blueTime, setBlueTime] = useState(0);
const [isRunning, setIsRunning] = useState(false);
@@ -151,10 +163,12 @@ const GameTimer = () => {
return (
<div className="game-timer-container">
<div className={`game-timer red-timer ${!activePlayer ? 'active' : ''}`}>
{renderAvatar(red)}
<i className={`fa ${!activePlayer ? 'fa-hourglass-half' : 'fa-hourglass-start'} timer-icon`} />
<span className="timer-display">{formatTime(redTime)}</span>
</div>
<div className={`game-timer blue-timer ${activePlayer ? 'active' : ''}`}>
{renderAvatar(blue)}
<i className={`fa ${activePlayer ? 'fa-hourglass-half' : 'fa-hourglass-start'} timer-icon`} />
<span className="timer-display">{formatTime(blueTime)}</span>
</div>

View File

@@ -90,10 +90,14 @@ const useServerCommunication = (gameAssoc, gameInherited, isEnvDev) => {
syncRed(p => ({
...p,
name: payload.users.red || payload.users.redAnon || p.name,
registered: !!payload.users.red,
avatar: payload.users.redAvatar ?? null,
}));
syncBlue(p => ({
...p,
name: payload.users.blue || payload.users.blueAnon || p.name,
registered: !!payload.users.blue,
avatar: payload.users.blueAvatar ?? null,
desc: 'blue' === webPlayerRef.current ? DESC.you : DESC.buddy,
active: true,
}));

View File

@@ -36,6 +36,7 @@ export const IMAGES = {
export const PLAYER_DEF = {
name: '...', desc: '', active: false, mines: 0, haveBomb: true, enabledBomb: true,
registered: false, avatar: null,
};
export const DESC = {

View File

@@ -18,6 +18,7 @@ use App\Entity\User;
use App\Interfaces\TopicManagerInterface;
use App\Repository\PlayedGameRepository;
use App\Repository\UserRepository;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use DateTimeInterface;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
@@ -47,6 +48,7 @@ readonly class TopicManager implements TopicManagerInterface
private LoggerInterface $logger,
private PlayedGameRepository $playedGameRepository,
private UserRepository $userRepository,
private CacheManager $cacheManager,
) {
}
@@ -516,11 +518,20 @@ readonly class TopicManager implements TopicManagerInterface
private function getUserCollection(PlayedGame $playedGame): array
{
$redUser = $playedGame->getRed();
$blueUser = $playedGame->getBlue();
return [
'red' => null !== $playedGame->getRed() ? $playedGame->getRed()->getUsername() : '',
'blue' => null !== $playedGame->getBlue() ? $playedGame->getBlue()->getUsername() : '',
'redAnon' => null !== $playedGame->getRedAnon() ? $playedGame->getRedAnon()->getUserName() : '',
'blueAnon' => null !== $playedGame->getBlueAnon() ? $playedGame->getBlueAnon()->getUserName() : '',
'red' => null !== $redUser ? $redUser->getUsername() : '',
'blue' => null !== $blueUser ? $blueUser->getUsername() : '',
'redAnon' => null !== $playedGame->getRedAnon() ? $playedGame->getRedAnon()->getUserName() : '',
'blueAnon' => null !== $playedGame->getBlueAnon() ? $playedGame->getBlueAnon()->getUserName() : '',
'redAvatar' => null !== $redUser && null !== $redUser->getAvatarPath()
? $this->cacheManager->generateUrl($redUser->getAvatarPath(), 'avatar_thumb')
: null,
'blueAvatar' => null !== $blueUser && null !== $blueUser->getAvatarPath()
? $this->cacheManager->generateUrl($blueUser->getAvatarPath(), 'avatar_thumb')
: null,
];
}