Merge branch 'css-rework' of https://github.com/sendou-ink/sendou.ink into css-rework

This commit is contained in:
hfcRed 2026-01-07 20:06:07 +01:00
commit 06977fe295
12 changed files with 54 additions and 25 deletions

View File

@ -8,10 +8,17 @@
}
.avatarWrapper {
display: inline-flex;
flex-shrink: 0;
width: fit-content;
height: fit-content;
background-color: var(--color-bg-higher);
border-radius: 50%;
overflow: hidden;
line-height: 0;
}
.avatarWrapper img {
display: block;
border-radius: 50%;
}

View File

@ -18,13 +18,15 @@ const dimensions = {
export function Avatar({
user,
url,
identiconInput,
size = "sm",
className,
alt = "",
...rest
}: {
user?: Pick<Tables["User"], "discordId" | "discordAvatar">;
url?: string;
url?: string | null;
identiconInput?: string;
className?: string;
alt?: string;
size: keyof typeof dimensions;
@ -111,7 +113,14 @@ export function Avatar({
return canvas.toDataURL();
}
const isIdenticon = !url && (!user?.discordAvatar || isErrored);
const isIdenticon =
!url && (!user?.discordAvatar || isErrored || identiconInput);
const identiconSource = () => {
if (identiconInput) return identiconInput;
if (user) return user.discordId;
return "unknown";
};
const src = url
? url
@ -122,17 +131,13 @@ export function Avatar({
size: size === "lg" ? "lg" : "sm",
})
: isClient
? generateIdenticon(
user ? user.discordId : "unknown",
dimensions[size],
7,
)
? generateIdenticon(identiconSource(), dimensions[size], 7)
: BLANK_IMAGE_URL;
return (
<div className={styles.avatarWrapper}>
<div className={clsx(styles.avatarWrapper, className)}>
<img
className={clsx(className, {
className={clsx({
[styles.identicon]: isIdenticon,
[styles.loaded]: loaded,
})}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -229,8 +229,8 @@ function MatchRow({
const ownTeam = tournament.teamMemberOfByUser(user);
const logoSrc =
!simulated && team ? tournament.tournamentTeamLogoSrc(team) : null;
const logoSrc = team ? tournament.tournamentTeamLogoSrc(team) : null;
const showAvatar = !simulated && team;
const isBigSeedNumber = team?.seed && team.seed > 99;
@ -248,7 +248,14 @@ function MatchRow({
>
{team?.seed}
</div>
{logoSrc ? <Avatar size="xxxs" url={logoSrc} className="mr-1" /> : null}
{showAvatar ? (
<Avatar
size="xxxs"
url={logoSrc}
identiconInput={team.name}
className="mr-1"
/>
) : null}
<div
className={clsx(styles.matchTeamName, {
"text-theme-secondary":
@ -256,9 +263,9 @@ function MatchRow({
"text-lighter italic opaque": simulated,
[styles.matchTeamNameNarrow]:
// either but not both
(logoSrc || isBigSeedNumber) && !(logoSrc && isBigSeedNumber),
(showAvatar || isBigSeedNumber) && !(showAvatar && isBigSeedNumber),
// both
[styles.matchTeamNameNarrowest]: logoSrc && isBigSeedNumber,
[styles.matchTeamNameNarrowest]: showAvatar && isBigSeedNumber,
invisible: !team,
})}
>

View File

@ -47,7 +47,7 @@ export function MatchRosters({
<h2
className={clsx("text-sm", {
"text-lighter": !teamOne,
[styles.rostersSpacedHeader]: teamOneLogoSrc || teamTwoLogoSrc,
[styles.rostersSpacedHeader]: teamOne || teamTwo,
})}
>
{teamOne ? (
@ -58,9 +58,11 @@ export function MatchRosters({
})}
className="text-main-forced font-bold stack horizontal xs items-center"
>
{teamOneLogoSrc ? (
<Avatar url={teamOneLogoSrc} size="sm" />
) : null}
<Avatar
url={teamOneLogoSrc}
identiconInput={teamOne.name}
size="sm"
/>
{teamOne.name}
</Link>
) : (
@ -105,7 +107,7 @@ export function MatchRosters({
<h2
className={clsx("text-sm", {
"text-lighter": !teamTwo,
[styles.rostersSpacedHeader]: teamOneLogoSrc || teamTwoLogoSrc,
[styles.rostersSpacedHeader]: teamOne || teamTwo,
})}
>
{teamTwo ? (
@ -116,9 +118,11 @@ export function MatchRosters({
})}
className="text-main-forced font-bold stack horizontal xs items-center"
>
{teamTwoLogoSrc ? (
<Avatar url={teamTwoLogoSrc} size="sm" />
) : null}
<Avatar
url={teamTwoLogoSrc}
identiconInput={teamTwo.name}
size="sm"
/>
{teamTwo.name}
</Link>
) : (

View File

@ -35,7 +35,7 @@ export function TeamWithRoster({
<div className={styles.teamWithRoster}>
<div className={styles.teamWithRosterName}>
<div className="stack horizontal sm justify-end items-end">
{teamLogoSrc ? <Avatar size="xxs" url={teamLogoSrc} /> : null}
<Avatar size="xxs" url={teamLogoSrc} identiconInput={team.name} />
{seed ? (
<div className={styles.teamWithRosterSeed}>#{seed}</div>
) : null}

View File

@ -139,7 +139,11 @@ function ResultsTable({ standings }: { standings: Standing[] }) {
className={styles.standingsTeamName}
data-testid="result-team-name"
>
{teamLogoSrc ? <Avatar size="xs" url={teamLogoSrc} /> : null}{" "}
<Avatar
size="xs"
url={teamLogoSrc}
identiconInput={standing.team.name}
/>{" "}
{standing.team.name}
</Link>
</td>

View File

@ -381,7 +381,9 @@ function RowContents({
return (
<>
<div>{seed}</div>
<div>{logoUrl ? <Avatar url={logoUrl} size="xxs" /> : null}</div>
<div>
<Avatar url={logoUrl} identiconInput={team.name} size="xxs" />
</div>
<div className={styles.seedsTeamName}>
{team.checkIns.length > 0 ? "✅ " : "❌ "} {team.name}
</div>