- 合并钱包、订单、开奖、通知等独立 screen 到页面层,减少重复壳组件 - 优化订单列表/详情、钱包划转与待对账展示、开奖核对与结果详情交互 - 改进入口 gate、移动端视口与下拉刷新在窄屏下的表现 - dev 绑定 0.0.0.0 并默认放行 192.168/10 网段,修复局域网 HMR WebSocket
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
import { useNetworkStatus } from "@/hooks/use-network-status";
|
||||
import { OfflineBanner } from "@/components/offline-banner";
|
||||
import { ServerError } from "@/components/server-error";
|
||||
|
||||
/**
|
||||
@@ -17,13 +16,7 @@ export function ErrorProvider({ children }: { children: ReactNode }): ReactNode
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* 全局离线状态横幅 - 显示在页面顶部 */}
|
||||
<OfflineBanner />
|
||||
|
||||
{/* 服务器错误全屏覆盖 */}
|
||||
<ServerError />
|
||||
|
||||
{/* 子内容 */}
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -28,14 +28,17 @@ export function PlayerAppShell({ children }: PlayerAppShellProps): ReactNode {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col bg-white text-foreground overflow-hidden">
|
||||
<div className="flex h-full min-h-0 flex-1 flex-col overflow-hidden bg-white text-foreground">
|
||||
<PullToRefreshIndicator
|
||||
pullDistance={pullDistance}
|
||||
isRefreshing={isRefreshing}
|
||||
threshold={70}
|
||||
/>
|
||||
<NetworkStatusBanner />
|
||||
<main id="player-scroll-container" className="flex w-full flex-1 flex-col pb-1 overflow-y-auto overscroll-y-contain">
|
||||
<main
|
||||
id="player-scroll-container"
|
||||
className="flex w-full min-h-0 flex-1 flex-col overflow-y-auto overscroll-y-contain pb-3"
|
||||
>
|
||||
{children}
|
||||
</main>
|
||||
<div className="shrink-0 w-full relative z-50">
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
import { playerViewportColumnClass } from "@/lib/player-viewport";
|
||||
import { OfflineBanner } from "@/components/offline-banner";
|
||||
import {
|
||||
playerSafeAreaTopClass,
|
||||
playerViewportColumnClass,
|
||||
} from "@/lib/player-viewport";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
type PlayerMobileViewportProps = {
|
||||
@@ -20,10 +24,12 @@ export function PlayerMobileViewport({
|
||||
<div
|
||||
className={cn(
|
||||
playerViewportColumnClass,
|
||||
"relative h-full bg-white shadow-none sm:shadow-[0_0_48px_rgba(15,23,42,0.1)] flex flex-col",
|
||||
playerSafeAreaTopClass,
|
||||
"relative flex h-full min-h-0 flex-col bg-white shadow-none sm:shadow-[0_0_48px_rgba(15,23,42,0.1)]",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<OfflineBanner />
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,10 @@ export function PullToRefreshIndicator({
|
||||
return (
|
||||
<div
|
||||
className="pointer-events-none fixed left-1/2 z-[60] flex w-full max-w-[480px] -translate-x-1/2 items-center justify-center overflow-hidden transition-[height] duration-100 ease-out"
|
||||
style={{ height: isRefreshing ? 40 : pullDistance }}
|
||||
style={{
|
||||
top: "env(safe-area-inset-top, 0px)",
|
||||
height: isRefreshing ? 40 : pullDistance,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
|
||||
@@ -9,7 +9,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
||||
type={type}
|
||||
data-slot="input"
|
||||
className={cn(
|
||||
"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
||||
"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -7,7 +7,7 @@ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
||||
<textarea
|
||||
data-slot="textarea"
|
||||
className={cn(
|
||||
"flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
||||
"flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
Reference in New Issue
Block a user