diff --git a/static/style.css b/static/style.css
index c1f467b..11d567a 100644
--- a/static/style.css
+++ b/static/style.css
@@ -144,14 +144,20 @@ a { color: var(--ink); }
text-transform: uppercase;
}
-.sheet tfoot td {
- border-top: 2px solid var(--ink);
+.sheet .totals td {
+ border-bottom: 2px solid var(--ink);
font-size: 2.1rem;
font-weight: 700;
- padding-top: 0.7rem;
}
-.sheet tfoot .label { font-weight: 400; }
+.sheet .totals .label { font-weight: 400; font-size: 0.85rem; }
+
+.sheet .more td {
+ text-align: left;
+ color: var(--ink-soft);
+ font-size: 0.85rem;
+ font-family: var(--font-ui);
+}
/* --- nuly za sebou ------------------------------------------------------- */
diff --git a/templates/_sheet.html b/templates/_sheet.html
index 9b2294c..369f61a 100644
--- a/templates/_sheet.html
+++ b/templates/_sheet.html
@@ -16,6 +16,20 @@
{% endfor %}
+
+ {# Součty patří nahoru: po padesáti kolech by je jinak nikdo neviděl. #}
+
+
+ | Celkem |
+ {% for name in game.names %}
+
+ {{ totals[name]|cislo }}
+ {%- if streaks[name] %} {{ '✕' * streaks[name] }}{% endif %}
+ |
+ {% endfor %}
+
+
+
{% for row in rows %}
@@ -41,17 +55,12 @@
{% endfor %}
{% endfor %}
-
-
-
- | Celkem |
- {% for name in game.names %}
-
- {{ totals[name]|cislo }}
- {%- if streaks[name] %} {{ '✕' * streaks[name] }}{% endif %}
- |
- {% endfor %}
+
+ {% if hidden %}
+
+ | … a dalších {{ hidden|kola }} |
-
+ {% endif %}
+
diff --git a/tests/test_web.py b/tests/test_web.py
index 6a24620..b10660e 100644
--- a/tests/test_web.py
+++ b/tests/test_web.py
@@ -191,3 +191,48 @@ def test_sin_slavy(client):
def test_sin_slavy_bez_her(client):
assert "Rekordy přibudou po první hře" in text(client.get("/stats"))
+
+
+def test_zapisnik_zacina_nejnovejsim_kolem(client):
+ game_id = start_game(client, "Adam", final_score=99999)
+ for value in (111, 222, 333):
+ score(client, game_id, value)
+
+ panel = text(client.get(f"/board/{game_id}/panel"))
+
+ assert panel.index("333") < panel.index("222") < panel.index("111")
+
+
+def test_soucty_jsou_nad_koly(client):
+ game_id = start_game(client, "Adam", final_score=99999)
+ score(client, game_id, 450)
+
+ panel = text(client.get(f"/board/{game_id}/panel"))
+
+ assert panel.index("Celkem") < panel.index(">450<")
+
+
+def test_tabule_useka_starou_historii(client):
+ game_id = start_game(client, "Adam", final_score=999999)
+ for value in range(1, 31):
+ score(client, game_id, value * 10)
+
+ panel = text(client.get(f"/board/{game_id}/panel"))
+
+ assert "a dalších 15 kol" in panel
+ assert "300" in panel # nejnovější kolo tam je
+ assert ">150<" not in panel # patnácté odspodu už ne
+
+
+def test_kratka_hra_nic_neuseka(client):
+ game_id = start_game(client, "Adam", final_score=99999)
+ score(client, game_id, 100)
+
+ assert "a dalších" not in text(client.get(f"/board/{game_id}/panel"))
+
+
+@pytest.mark.parametrize("count, expected", [
+ (1, "1 kolo"), (2, "2 kola"), (4, "4 kola"), (5, "5 kol"), (22, "22 kol"),
+])
+def test_sklonovani_kol(count, expected):
+ assert web.kola(count) == expected
diff --git a/web.py b/web.py
index 34a4bdc..e8749ef 100644
--- a/web.py
+++ b/web.py
@@ -20,6 +20,10 @@ app = Flask(__name__)
PORT = int(os.environ.get("DICE_PORT", 8000))
+# Kolik kol tabule ukáže. Zbytek historie je na hráčích, ne na tabuli —
+# ta má ukazovat stav, ne archiv.
+BOARD_ROUNDS = 15
+
# --- připojení k databázi ---------------------------------------------------
@@ -87,6 +91,15 @@ def datum(value: str) -> str:
return f"{int(den[2])}. {int(den[1])}. {den[0]}"
+@app.template_filter("kola")
+def kola(count: int) -> str:
+ if count == 1:
+ return "1 kolo"
+ if 2 <= count <= 4:
+ return f"{count} kola"
+ return f"{count} kol"
+
+
@app.template_filter("cislo")
def cislo(value: int) -> str:
"""Tisíce se v češtině oddělují mezerou."""
@@ -95,8 +108,11 @@ def cislo(value: int) -> str:
# --- zápisník ---------------------------------------------------------------
-def scoresheet(game: Game) -> list[dict]:
- """Řádky zápisníku po kolech.
+def scoresheet(game: Game) -> tuple[list[dict], int]:
+ """Řádky zápisníku po kolech, od nejnovějšího.
+
+ Naposledy odehrané kolo patří nahoru — po padesáti kolech by jinak bylo
+ to podstatné mimo obrazovku. Vrací i počet kol, která se nevešla.
Tahy zapsané před posledním vynulováním se přeškrtnou — přesně tak, jak
by se škrtaly na papíře.
@@ -118,19 +134,24 @@ def scoresheet(game: Game) -> list[dict]:
})
rows.append({"round": number, "cells": cells})
- return rows
+ rows.reverse()
+ hidden = max(0, len(rows) - BOARD_ROUNDS)
+
+ return rows[:BOARD_ROUNDS], hidden
def view(game: Game, game_id: int, row) -> dict:
"""Společný podklad pro zápisník i pro zadávací pohled."""
totals = game.totals()
winner = row["winner_name"] if row["status"] == storage.STATUS_FINISHED else ""
+ rows, hidden = scoresheet(game)
return {
"game": game,
"game_id": game_id,
"row": row,
"totals": totals,
- "rows": scoresheet(game),
+ "rows": rows,
+ "hidden": hidden,
"streaks": {name: game.zero_streak(name) for name in game.names},
"standings": game.standings(),
"winner": winner,