feat: add TagsSkeleton/TagDetailSkeleton and replace generic fallback on tags pages
This commit is contained in:
parent
5becd73ebc
commit
c2e1fbe3ac
@ -1,8 +1,54 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::components::skeletons::post_card_skeleton::PostCardSkeleton;
|
||||
|
||||
/// 标签列表页骨架屏
|
||||
/// 结构:统计行("共 N 个标签,M 篇文章") + 标签云(flex wrap 的 pill 列表)
|
||||
#[component]
|
||||
pub fn TagsSkeleton() -> Element {
|
||||
rsx! {
|
||||
div { class: "animate-pulse", "Loading..." }
|
||||
div { class: "animate-pulse",
|
||||
// 统计行占位
|
||||
div { class: "mt-2 mb-6",
|
||||
div { class: "h-5 w-48 bg-gray-200 dark:bg-[#2a2a2a] rounded" }
|
||||
}
|
||||
|
||||
// 标签云占位 (flex wrap gap-4)
|
||||
div { class: "flex flex-wrap gap-4 mt-6",
|
||||
// 生成 24 个不同宽度的标签 pill
|
||||
for i in 0..24 {
|
||||
div {
|
||||
class: "h-8 bg-gray-200 dark:bg-[#2a2a2a] rounded-lg",
|
||||
// 不同宽度模拟标签名长短
|
||||
style: match i % 6 {
|
||||
0 => "width: 60px;",
|
||||
1 => "width: 80px;",
|
||||
2 => "width: 50px;",
|
||||
3 => "width: 100px;",
|
||||
4 => "width: 70px;",
|
||||
_ => "width: 90px;",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 标签详情页骨架屏 - 与首页文章列表结构相同
|
||||
#[component]
|
||||
pub fn TagDetailSkeleton() -> Element {
|
||||
rsx! {
|
||||
div { class: "animate-pulse",
|
||||
// 统计行占位
|
||||
div { class: "mt-2 mb-6",
|
||||
div { class: "h-5 w-32 bg-gray-200 dark:bg-[#2a2a2a] rounded" }
|
||||
}
|
||||
|
||||
// 文章卡片列表
|
||||
for _ in 0..5 {
|
||||
PostCardSkeleton {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ use crate::api::posts::{get_posts_by_tag, list_tags, PostListResponse, TagListRe
|
||||
use crate::components::nav::use_nav_items;
|
||||
use crate::components::page_layout::PageLayout;
|
||||
use crate::components::post_card::PostCard;
|
||||
use crate::components::suspense_wrapper::SuspenseWrapper;
|
||||
use crate::components::skeletons::tags_skeleton::{TagsSkeleton, TagDetailSkeleton};
|
||||
use crate::router::Route;
|
||||
|
||||
#[component]
|
||||
@ -19,7 +19,8 @@ pub fn Tags() -> Element {
|
||||
"标签"
|
||||
}
|
||||
}
|
||||
SuspenseWrapper {
|
||||
SuspenseBoundary {
|
||||
fallback: |_| rsx! { TagsSkeleton {} },
|
||||
TagsContent {}
|
||||
}
|
||||
}
|
||||
@ -73,9 +74,7 @@ fn TagsContent() -> Element {
|
||||
}
|
||||
_ => {
|
||||
rsx! {
|
||||
div { class: "text-center text-gray-500 dark:text-[#9b9c9d] py-20",
|
||||
"加载中..."
|
||||
}
|
||||
// 骨架屏由 SuspenseBoundary fallback 处理
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,7 +92,8 @@ pub fn TagDetail(tag: String) -> Element {
|
||||
"{tag}"
|
||||
}
|
||||
}
|
||||
SuspenseWrapper {
|
||||
SuspenseBoundary {
|
||||
fallback: |_| rsx! { TagDetailSkeleton {} },
|
||||
TagDetailContent { tag: tag.clone() }
|
||||
}
|
||||
}
|
||||
@ -131,9 +131,7 @@ fn TagDetailContent(tag: String) -> Element {
|
||||
}
|
||||
_ => {
|
||||
rsx! {
|
||||
div { class: "text-center text-gray-500 dark:text-[#9b9c9d] py-20",
|
||||
"加载中..."
|
||||
}
|
||||
// 骨架屏由 SuspenseBoundary fallback 处理
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user