feat(client): polished toolbar, live online count via SSE
CI / runtime-diagnostics (push) Skipped
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m27s

- Redesign in-game client toolbar with refined glass styling and buttons
- Live online count + emulator status streamed over SSE multicast
- Who's-online tooltip throttled to reduce repeated requests
- Fix show button so it always returns the hidden toolbar
- Use theme CSS variables instead of hardcoded colors
- Add toolbar translations across all 25 locales
This commit is contained in:
openhands committed 2026-09-02 21:14:42 +02:00
1 parent e1ecb190bc
commit 67b67798b9
32 files changed
+799 -102

No files matched your search

+12 -2
View File
@@ -9,6 +9,8 @@ import { HomeLoginForm } from "@/components/auth/home-login-form";
import { Clock } from "@/components/clock";
import { LanguageSwitcher } from "@/components/language-switcher";
import Link from "@/components/link";
import { LiveOnlineCount } from "@/components/live-online-count";
import { LiveOnlineCounter } from "@/components/live-online-counter";
import { Reveal } from "@/components/motion-reveal";
import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail";
import { SurfaceCard } from "@/components/surface-card";
@@ -235,7 +237,7 @@ export default async function Home() {
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75" />
<span className="relative inline-flex rounded-full h-2 w-2 bg-primary" />
</span>
{th("online", { count: online, hotel: hotelName })}
<LiveOnlineCount initial={online} hotelName={hotelName} />
</div>
<h1
className="text-2xl font-black leading-[1.05] tracking-tight mb-2 sm:text-3xl md:text-5xl lg:text-6xl"
@@ -337,21 +339,25 @@ export default async function Home() {
value: users,
label: tp("statsCitizens"),
icon: "/assets/images/icons/friends.png",
live: false,
},
{
value: rooms,
label: tp("statsRooms"),
icon: "/assets/images/icons/catalog.png",
live: false,
},
{
value: online,
label: tp("statsOnline"),
icon: "/assets/images/icons/navigation/me.png",
live: true,
},
{
value: articles.length,
label: tp("statsArticles"),
icon: "/assets/images/icons/article.gif",
live: false,
},
].map((s) => (
<SurfaceCard
@@ -359,7 +365,11 @@ export default async function Home() {
className="relative p-3 sm:p-5 text-center transition-all duration-300 hover:-translate-y-1 hover:shadow-lg"
>
<div className="mb-0.5 text-2xl sm:text-3xl font-black tracking-tight md:text-4xl">
<AnimatedCounter value={s.value} />
{s.live ? (
<LiveOnlineCounter initial={s.value} />
) : (
<AnimatedCounter value={s.value} />
)}
</div>
<div
className="text-[10px] sm:text-xs font-bold uppercase tracking-widest flex items-center justify-center gap-1 sm:gap-1.5"