feat: implement initial language resolution for SSR and local storage support

- Added a function to determine the initial language based on server-side rendering and local storage.
- Updated i18n initialization to use the resolved initial language instead of the default.
This commit is contained in:
2026-05-25 14:54:31 +08:00
parent 9bd7cc9b9e
commit 3649bb9300
8 changed files with 70 additions and 7 deletions

View File

@@ -20,7 +20,7 @@ export function PlayerAppShell({ children }: PlayerAppShellProps): ReactNode {
return (
<div className="min-h-dvh bg-white text-foreground">
<NetworkStatusBanner />
<main className="mx-auto flex w-full max-w-lg flex-col pb-[calc(3.5rem+env(safe-area-inset-bottom,0px)+0.75rem)]">
<main className="flex w-full flex-col pb-[calc(3.5rem+env(safe-area-inset-bottom,0px)+0.75rem)]">
{children}
</main>
<PlayerBottomNav />

View File

@@ -6,6 +6,7 @@ import { usePathname } from "next/navigation";
import { BarChart3, ClipboardList, Home, Wallet } from "lucide-react";
import { useTranslation } from "react-i18next";
import { playerViewportFixedBarClass } from "@/lib/player-viewport";
import { cn } from "@/lib/utils";
const tabs = [
@@ -48,10 +49,13 @@ export function PlayerBottomNav() {
return (
<nav
className="fixed bottom-0 left-0 right-0 z-50 border-t border-[#e4ebf5] bg-white/96 pb-[env(safe-area-inset-bottom,0px)] shadow-[0_-10px_30px_rgba(15,23,42,0.08)] backdrop-blur-md"
className={cn(
playerViewportFixedBarClass,
"bottom-0 border-t border-[#e4ebf5] bg-white/96 pb-[env(safe-area-inset-bottom,0px)] shadow-[0_-10px_30px_rgba(15,23,42,0.08)] backdrop-blur-md",
)}
aria-label={t("nav.aria")}
>
<div className="mx-auto grid h-14 w-full max-w-lg grid-rows-1 grid-cols-4">
<div className="grid h-14 w-full grid-cols-4 grid-rows-1">
{tabs.map(({ href, labelKey, labelDefault, icon: Icon, match }) => {
const active = match(pathname);
const label = t(labelKey, { defaultValue: labelDefault });

View File

@@ -0,0 +1,31 @@
import type { ReactNode } from "react";
import { playerViewportColumnClass } from "@/lib/player-viewport";
import { cn } from "@/lib/utils";
type PlayerMobileViewportProps = {
children: ReactNode;
className?: string;
};
/**
* 玩家端根容器:真机全宽;桌面浏览器居中为固定宽度的 H5 画布,避免 PC 打开时 UI 横向拉满。
*/
export function PlayerMobileViewport({
children,
className,
}: PlayerMobileViewportProps): ReactNode {
return (
<div className="min-h-dvh bg-[#e8ecf3]">
<div
className={cn(
playerViewportColumnClass,
"relative min-h-dvh bg-white shadow-none sm:shadow-[0_0_48px_rgba(15,23,42,0.1)]",
className,
)}
>
{children}
</div>
</div>
);
}