ui: 骨架屏替代全部页面级加载 spinner

- 新增 Skeleton 组件库:Skeleton、SkeletonCircle 基础元素 + 5 个业务骨架
  (SwipeDeck、ProfileCard、RecordItem、BlindboxRoom、BlindboxList、RoomCard)
- 替换 room、profile、blindbox 列表、blindbox 房间、invite 5 个页面的加载态
- 替换 profile 历史记录 / 收藏列表的内联加载 spinner
- 更新 project-conventions.mdc:新增 Loading States 规范,
  要求页面级和列表级加载必须使用骨架屏
This commit is contained in:
2026-02-26 16:11:01 +08:00
parent 798b883250
commit b2b18327cc
7 changed files with 200 additions and 29 deletions
+2 -10
View File
@@ -15,6 +15,7 @@ import {
} from "lucide-react";
import { getCachedProfile, isRegistered } from "@/lib/userId";
import AuthModal from "@/components/AuthModal";
import { BlindboxListSkeleton } from "@/components/Skeleton";
import type { UserProfile } from "@/types";
interface RoomSummary {
@@ -216,16 +217,7 @@ export default function BlindboxLobbyPage() {
</p>
</motion.div>
) : loading ? (
/* ============ Loading ============ */
<motion.div
key="loading"
className="mt-20 flex flex-col items-center gap-3"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
>
<Loader2 size={24} className="animate-spin text-purple-400" />
<p className="text-xs text-muted">...</p>
</motion.div>
<BlindboxListSkeleton />
) : rooms.length === 0 ? (
/* ============ Layer 2: Logged in, no rooms — Create first ============ */
<motion.div