From cff64700312463eb573a49b683ce62fd5ba6e548 Mon Sep 17 00:00:00 2001 From: kang Date: Wed, 24 Jun 2026 11:46:49 +0800 Subject: [PATCH] feat: implement global pull-to-refresh functionality and refine UI typography and layout scaling for improved mobile UX. --- src/app/globals.css | 12 +- src/app/layout.tsx | 6 +- src/components/layout/player-app-shell.tsx | 25 +++- src/components/layout/player-bottom-nav.tsx | 8 +- .../layout/player-mobile-viewport.tsx | 4 +- src/components/pull-to-refresh-indicator.tsx | 50 ++++++++ src/components/ui/calendar.tsx | 2 +- src/features/hall/hall-bet-preview-dialog.tsx | 4 +- src/features/hall/hall-bet-result-dialog.tsx | 6 +- src/features/hall/hall-betting-grid.tsx | 20 +-- src/features/hall/hall-draw-panel.tsx | 8 +- src/features/hall/hall-play-catalog-panel.tsx | 2 +- src/features/hall/hall-screen.tsx | 8 +- src/features/hall/jackpot-burst-overlay.tsx | 4 +- .../orders/ticket-order-group-screen.tsx | 4 +- .../orders/ticket-orders-list-screen.tsx | 10 +- src/features/player/entry-gate.tsx | 2 +- src/features/player/notifications-screen.tsx | 2 +- src/features/player/player-login-screen.tsx | 4 +- src/features/player/player-session-bar.tsx | 4 +- .../results/draw-result-detail-screen.tsx | 4 +- .../results/draw-results-list-screen.tsx | 2 +- src/features/rules/play-rules-screen.tsx | 2 +- src/hooks/use-pull-to-refresh.ts | 120 ++++++++++++++++++ 24 files changed, 253 insertions(+), 60 deletions(-) create mode 100644 src/components/pull-to-refresh-indicator.tsx create mode 100644 src/hooks/use-pull-to-refresh.ts diff --git a/src/app/globals.css b/src/app/globals.css index 6747975..54e02ec 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -121,11 +121,14 @@ * { @apply border-border outline-ring/50; } - body { - @apply bg-background text-foreground; - } html { @apply font-sans; + -webkit-text-size-adjust: 100%; + } + body { + @apply bg-background text-foreground; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; } html:lang(ne) { font-family: @@ -134,6 +137,9 @@ system-ui, sans-serif; } + button, a, [role="button"] { + touch-action: manipulation; + } } /* 玩家端 Toast:顶部居中、紧凑尺寸(位置见 components/ui/sonner.tsx) */ diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 0eede12..0cc0d2c 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -28,6 +28,8 @@ export const metadata: Metadata = { export const viewport = { width: "device-width", initialScale: 1, + maximumScale: 1, + userScalable: false, }; export default function RootLayout({ @@ -39,9 +41,9 @@ export default function RootLayout({ - + {children} diff --git a/src/components/layout/player-app-shell.tsx b/src/components/layout/player-app-shell.tsx index 0d7b427..38c9b60 100644 --- a/src/components/layout/player-app-shell.tsx +++ b/src/components/layout/player-app-shell.tsx @@ -4,6 +4,8 @@ import type { ReactNode } from "react"; import { NetworkStatusBanner } from "@/components/network-status-banner"; import { PlayerBottomNav } from "@/components/layout/player-bottom-nav"; +import { PullToRefreshIndicator } from "@/components/pull-to-refresh-indicator"; +import { usePullToRefresh } from "@/hooks/use-pull-to-refresh"; type PlayerAppShellProps = { children: ReactNode; @@ -11,19 +13,34 @@ type PlayerAppShellProps = { /** * 玩家端外壳:顶栏(品牌 + 会话)+ 主体 + **底部 Tab 导航**(H5)。 - * 底部栏留白:{@link PlayerBottomNav} 对应 `padding-bottom`. + * 底部栏留白:{@link PlayerBottomNav} 作为 sticky 元素放在底部,main 只需要基础 padding。 * * 注意:全局离线横幅和服务器错误覆盖层已在 ErrorProvider 中处理 * 这里的 NetworkStatusBanner 仅用于 WebSocket 状态显示 */ export function PlayerAppShell({ children }: PlayerAppShellProps): ReactNode { + const { pullDistance, isRefreshing } = usePullToRefresh({ + onRefresh: () => { + window.dispatchEvent(new CustomEvent("lottery-hall-refresh")); + window.dispatchEvent(new CustomEvent("lottery-wallet-refresh")); + }, + threshold: 70, + }); + return ( -
+
+ -
+
{children}
- +
+ +
); } diff --git a/src/components/layout/player-bottom-nav.tsx b/src/components/layout/player-bottom-nav.tsx index 259eabc..d0fa448 100644 --- a/src/components/layout/player-bottom-nav.tsx +++ b/src/components/layout/player-bottom-nav.tsx @@ -6,7 +6,6 @@ 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 { isCreditFundingPlayer } from "@/lib/player-funding-mode"; import { cn } from "@/lib/utils"; import { usePlayerSessionStore } from "@/stores/player-session-store"; @@ -55,8 +54,7 @@ export function PlayerBottomNav() { return (