Skip to content

Wyniki dnia i ranking: ikony ról, rangi oraz wyróżnienie emperora - #372

Open
MalkizH3 wants to merge 7 commits into
mainfrom
wyniki-dnia
Open

MalkizH3 wants to merge 7 commits into
mainfrom
wyniki-dnia

Conversation

@MalkizH3

@MalkizH3 MalkizH3 commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

W wynikach dnia ikony końcowych ról zastępują oznaczenia W/L, a statystyki ról pokazują awatary graczy według roli początkowej. Kolor wskazuje wynik, a checkbox „Tryb dla daltonistów” w prawym górnym rogu dodaje kontrastowe oznaczenia W/L przy każdej ikonie i awatarze. Ustawienie jest zapamiętywane w przeglądarce. Tabele przewijają się poziomo na telefonie; usunięto podwójne dymki. Kolumna W/R używa gradientu 0–100%.

Ranking ma osobną kolumnę Ranga z ikoną i nazwą, a na małych ekranach samą ikonę (z nazwą dla czytników ekranu). Żółty nick i korona wyróżniają ostatniego odbiorcę gwiazdki. Wspólna funkcja wyznacza zwycięzców sesji dla korony, historii i gwiazdek: w bieżącym sezonie najnowsza data pozostaje otwarta do następnej daty, w zakończonych sezonach finał jest zamknięty; remis nie przyznaje gwiazdki i zachowuje poprzedniego emperora.

Zapytanie o emperora działa niezależnie od getRanking, równolegle z rankingiem tylko w widokach i odświeżaniu, które go potrzebują. API rankingu i paginacja nie wykonują go niepotrzebnie. JOIN players zastąpiono podzapytaniem wykluczającym usuniętych graczy. Usunięto niewykorzystywane oryginały PNG rang; strona korzysta z WebP.

Weryfikacja: typecheck, ESLint zmienionych plików, git diff --check oraz 174 testy (19 zestawów), w tym testy zapytania na SQLite i zgodności korony, historii oraz gwiazdek. Lokalny podgląd rzeczywistych wyników z 21 października: komputer 1440 px i telefon 412 px; sprawdzone przełączanie trybu, pamiętanie wyboru i działanie przy blokadzie zapisu ustawień. Koszt odczytów nie był ponownie mierzony na produkcyjnej D1. Screeny przekazane autorowi w rozmowie. Bez scalania i wdrożenia.

Dodaj przygaszone ikony ról i awatary graczy w kolorach wyniku, dymki z nickami oraz płynny gradient kolorów W/R w obu tabelach.
Copilot AI balanced review requested due to automatic review settings October 19, 2026 20:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@MalkizH3
MalkizH3 requested a review from quarties October 19, 2026 20:23

@MalkizH3 MalkizH3 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nie znalazłem błędów wymagających poprawy w sprawdzonych zmianach.

Sprawdziłem zgodność indeksów wyników z detailedGames w getSessionSummaryByDate, dobór końcowej roli w tabeli graczy, dobór graczy według początkowej roli w tabeli ról oraz indywidualne oznaczenie zwycięstwa przy kilku graczach tą samą rolą. Gradient ogranicza wartości do zakresu 0–100% i obsługuje wartości niefinitywne.

PR Check dla tego commita zakończył się sukcesem. Review opiera się na analizie kodu; nie uruchamiałem lokalnie aplikacji ani pełnego zestawu testów. Publikuję jako Comment, ponieważ połączone konto jest autorem PR-a i nie może zatwierdzić własnych zmian.

@MalkizH3 MalkizH3 changed the title Wyniki dnia: ikony ról, awatary i gradient W/R Wyniki dnia i ranking: ikony ról, rangi oraz wyróżnienie emperora Oct 19, 2026

@quarties quarties left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emperor jest liczony z D1 (suma punktów sesji), tak jak w getEmperorHistory i getPlayerStars. To dobry wybór. getEmperorPoll nie pasuje, bo ankieta to przewidywanie, a nie wynik.

Sprawdziłem: CI zielone (typecheck, testy). npx eslint na zmienionych plikach: czysto. Zapytanie o emperora puściłem na lokalnej kopii D1 dla sezonów 2–4. Wynik zgadza się z logiką JS z getPlayerStars. Remisy i brak zamkniętej daty dają null, jak trzeba. Wag punktowych PR nie ujawnia.

// Same rule as getPlayerStars: only closed dates award a star. The newest
// game date is still open, so retain the latest unique winner before it.
// Aggregate in one query to avoid loading the full history and its child rows.
const emperors = await prisma.$queryRaw<{ playerId: number }[]>`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 do poprawy: Wydziel to zapytanie do osobnej funkcji i zamień JOIN players na NOT IN.

Teraz zapytanie działa przy każdym getRanking. Także w /api/ranking (src/app/api/ranking/get.ts:25), które wynik wyrzuca, i przy każdej stronie paginacji. Do tego idzie po kolei przed rankingiem, nie równolegle.

Na lokalnej kopii D1 (sezon 3) zapytanie czyta ok. 13 tys. wierszy. Około 6,1 tys. to sam JOIN players, jeden odczyt na wiersz gps. Ta wersja daje ten sam wynik i czyta 0 wierszy z players:

AND gps.playerId NOT IN (SELECT id FROM players WHERE deletedAt IS NOT NULL)

Propozycja: getLatestEmperorId(seasonId), wołane w obu stronach i w getRankingAction przez Promise.all z getRanking.

JOIN game_player_statistics gps ON gps.gameId = g.id
JOIN players p ON p.id = gps.playerId AND p.deletedAt IS NULL
WHERE g.season = ${targetSeason} AND g.deletedAt IS NULL
AND SUBSTR(g.startTime, 1, 10) < (SELECT date FROM latest_date)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 warto: Dla zakończonych sezonów traktuj ostatnią datę jako zamkniętą.

Dla targetSeason < CURRENT_SEASON nowa sesja już nie przyjdzie. Archiwalny ranking sezonu 3 daje koronę zwycięzcy z 2026-09-09, a nie z finałowej sesji 2026-09-16. Slajd historii w podsumowaniu (getEmperorHistory) liczy ostatnią datę, więc oba widoki pokazują innego emperora.

Ta sama reguła żyje teraz w trzech miejscach: getEmperorHistory, getPlayerStars i tutaj. getPlayerStars ma ten sam problem z ostatnim dniem sezonu. Warto ustalić jedną regułę i trzymać ją w jednym miejscu. To decyzja produktowa, więc dajcie znać, jeśli to celowe.

Comment thread src/app/_components/ResultImage.tsx Outdated
height={28}
className={`shrink-0 object-contain ${avatar ? 'rounded-full' : ''}`}
style={{
filter: won

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 warto: Zostaw drugi znak wyniku obok koloru, np. małą literę W/L w rogu.

Po zmianie wygraną od przegranej odróżnia tylko zielony i czerwony. Osoba z daltonizmem czerwono-zielonym nie odróżni tych kafelków. Na telefonie dymek z hover też się nie pokaże. Tekst alt pomaga czytnikom ekranu, ale nie oczom. Dotyczy PlayerTable i RoleTable.

Comment thread src/app/_components/ResultImage.tsx Outdated
<Image
src={src}
alt={description}
title={description}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 drobne: Usuń title. Obie tabele mają już własny dymek, więc po najechaniu widać dwa dymki naraz: natywny i ten czarny. alt wystarczy dla czytników ekranu.

return tier?.name ?? 'BAROX';
}

const RANK_ICONS: Readonly<Record<string, string>> = {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 warto: Usuń pliki PNG z public/images/ranks/, zostaw same WebP.

Kod używa tylko .webp. Dwanaście PNG 1254×1254 waży razem ok. 9,4 MB. WebP to ok. 50 kB. PNG trafią na produkcję jako publiczne pliki i zostaną w historii gita na zawsze. Oryginały lepiej trzymać poza repo.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dlaczego warto poza repo?

className="h-7 w-7 shrink-0 object-contain"
/>
)}
<span>{getRankName(Math.round(player.currentRating))}</span>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 drobne: Na wąskim ekranie pokaż samą ikonę rangi. Nowa kolumna ma whitespace-nowrap, a nazwy typu PIERDOLONA LEGENDA mocno poszerzają tabelę na telefonie. Propozycja: className="hidden sm:inline" na nazwie. Wtedy ikona potrzebuje alt/title z nazwą rangi, bo teraz ma alt="".

@MalkizH3
MalkizH3 requested a review from quarties October 25, 2026 17:06

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants