diff --git a/common/layout.py b/common/layout.py
index 81f5c74..8a0f255 100644
--- a/common/layout.py
+++ b/common/layout.py
@@ -187,6 +187,25 @@ def _main_script(mastered: bool) -> str:
return _MAIN_SCRIPT_A + ("true" if mastered else "false") + _MAIN_SCRIPT_B
+def NavbarPlaytime(
+ today_played: str, last_7_played: str, *, oob: bool = False
+) -> "Node":
+ """The navbar 'Today · Last 7 days' totals. Carries a stable id so
+ htmx endpoints can refresh it out-of-band after a session change."""
+ from common.components import Safe
+
+ oob_attr = ' hx-swap-oob="true"' if oob else ""
+ return Safe(
+ f'
'
+ 'Today'
+ '·Last 7 days'
+ ''
+ f'{today_played}·'
+ f"{last_7_played}"
+ )
+
+
def Navbar(
*, today_played: str, last_7_played: str, current_year: int, csrf_token: str
) -> "Node":
@@ -225,10 +244,7 @@ def Navbar(
-
- Today·Last 7 days
- {today_played}·{last_7_played}
-
+ {NavbarPlaytime(today_played, last_7_played)}
Home
diff --git a/tests/test_navbar_playtime.py b/tests/test_navbar_playtime.py
new file mode 100644
index 0000000..6c26efd
--- /dev/null
+++ b/tests/test_navbar_playtime.py
@@ -0,0 +1,15 @@
+from common.layout import NavbarPlaytime
+
+
+def test_navbar_playtime_has_stable_id_and_values():
+ html = str(NavbarPlaytime("1 h 00 m", "7 h 00 m"))
+ assert 'id="navbar-playtime"' in html
+ assert "1 h 00 m" in html
+ assert "7 h 00 m" in html
+ assert "hx-swap-oob" not in html
+
+
+def test_navbar_playtime_oob_flag():
+ html = str(NavbarPlaytime("1 h 00 m", "7 h 00 m", oob=True))
+ assert 'id="navbar-playtime"' in html
+ assert 'hx-swap-oob="true"' in html