feat(WechatFriends): 实现联系人列表分页加载功能
添加react-window依赖并实现分组联系人列表的分页加载功能,优化大数据量下的性能表现 - 每组初始加载20条数据,滚动到底部可点击加载更多 - 添加加载状态提示和"没有更多了"的结束提示 - 优化样式添加加载更多按钮的容器样式
This commit is contained in:
18
Cunkebao/dist/.vite/manifest.json
vendored
18
Cunkebao/dist/.vite/manifest.json
vendored
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"_charts-M0qaf_ew.js": {
|
"_charts-DKSCc2_C.js": {
|
||||||
"file": "assets/charts-M0qaf_ew.js",
|
"file": "assets/charts-DKSCc2_C.js",
|
||||||
"name": "charts",
|
"name": "charts",
|
||||||
"imports": [
|
"imports": [
|
||||||
"_ui-D5qYGnLz.js",
|
"_ui-DhAz00L0.js",
|
||||||
"_vendor-2vc8h_ct.js"
|
"_vendor-2vc8h_ct.js"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
"file": "assets/ui-D0C0OGrH.css",
|
"file": "assets/ui-D0C0OGrH.css",
|
||||||
"src": "_ui-D0C0OGrH.css"
|
"src": "_ui-D0C0OGrH.css"
|
||||||
},
|
},
|
||||||
"_ui-D5qYGnLz.js": {
|
"_ui-DhAz00L0.js": {
|
||||||
"file": "assets/ui-D5qYGnLz.js",
|
"file": "assets/ui-DhAz00L0.js",
|
||||||
"name": "ui",
|
"name": "ui",
|
||||||
"imports": [
|
"imports": [
|
||||||
"_vendor-2vc8h_ct.js"
|
"_vendor-2vc8h_ct.js"
|
||||||
@@ -33,18 +33,18 @@
|
|||||||
"name": "vendor"
|
"name": "vendor"
|
||||||
},
|
},
|
||||||
"index.html": {
|
"index.html": {
|
||||||
"file": "assets/index-BQxyt58_.js",
|
"file": "assets/index-BdCPAYQ7.js",
|
||||||
"name": "index",
|
"name": "index",
|
||||||
"src": "index.html",
|
"src": "index.html",
|
||||||
"isEntry": true,
|
"isEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_vendor-2vc8h_ct.js",
|
"_vendor-2vc8h_ct.js",
|
||||||
"_utils-6WF66_dS.js",
|
"_utils-6WF66_dS.js",
|
||||||
"_ui-D5qYGnLz.js",
|
"_ui-DhAz00L0.js",
|
||||||
"_charts-M0qaf_ew.js"
|
"_charts-DKSCc2_C.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"assets/index-B6B8u-1D.css"
|
"assets/index-ChiFk16x.css"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
8
Cunkebao/dist/index.html
vendored
8
Cunkebao/dist/index.html
vendored
@@ -11,13 +11,13 @@
|
|||||||
</style>
|
</style>
|
||||||
<!-- 引入 uni-app web-view SDK(必须) -->
|
<!-- 引入 uni-app web-view SDK(必须) -->
|
||||||
<script type="text/javascript" src="/websdk.js"></script>
|
<script type="text/javascript" src="/websdk.js"></script>
|
||||||
<script type="module" crossorigin src="/assets/index-BQxyt58_.js"></script>
|
<script type="module" crossorigin src="/assets/index-BdCPAYQ7.js"></script>
|
||||||
<link rel="modulepreload" crossorigin href="/assets/vendor-2vc8h_ct.js">
|
<link rel="modulepreload" crossorigin href="/assets/vendor-2vc8h_ct.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/utils-6WF66_dS.js">
|
<link rel="modulepreload" crossorigin href="/assets/utils-6WF66_dS.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/ui-D5qYGnLz.js">
|
<link rel="modulepreload" crossorigin href="/assets/ui-DhAz00L0.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/charts-M0qaf_ew.js">
|
<link rel="modulepreload" crossorigin href="/assets/charts-DKSCc2_C.js">
|
||||||
<link rel="stylesheet" crossorigin href="/assets/ui-D0C0OGrH.css">
|
<link rel="stylesheet" crossorigin href="/assets/ui-D0C0OGrH.css">
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-B6B8u-1D.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-ChiFk16x.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-router-dom": "^6.20.0",
|
"react-router-dom": "^6.20.0",
|
||||||
|
"react-window": "^1.8.11",
|
||||||
"vconsole": "^3.15.1",
|
"vconsole": "^3.15.1",
|
||||||
"zustand": "^5.0.6"
|
"zustand": "^5.0.6"
|
||||||
},
|
},
|
||||||
|
|||||||
22
Cunkebao/pnpm-lock.yaml
generated
22
Cunkebao/pnpm-lock.yaml
generated
@@ -41,6 +41,9 @@ importers:
|
|||||||
react-router-dom:
|
react-router-dom:
|
||||||
specifier: ^6.20.0
|
specifier: ^6.20.0
|
||||||
version: 6.30.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 6.30.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
react-window:
|
||||||
|
specifier: ^1.8.11
|
||||||
|
version: 1.8.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
vconsole:
|
vconsole:
|
||||||
specifier: ^3.15.1
|
specifier: ^3.15.1
|
||||||
version: 3.15.1
|
version: 3.15.1
|
||||||
@@ -1563,6 +1566,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
memoize-one@5.2.1:
|
||||||
|
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
|
||||||
|
|
||||||
merge2@1.4.1:
|
merge2@1.4.1:
|
||||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -2001,6 +2007,13 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: '>=16.8'
|
react: '>=16.8'
|
||||||
|
|
||||||
|
react-window@1.8.11:
|
||||||
|
resolution: {integrity: sha512-+SRbUVT2scadgFSWx+R1P754xHPEqvcfSfVX10QYg6POOz+WNgkN48pS+BtZNIMGiL1HYrSEiCkwsMS15QogEQ==}
|
||||||
|
engines: {node: '>8.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
|
||||||
react@18.3.1:
|
react@18.3.1:
|
||||||
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
|
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -4025,6 +4038,8 @@ snapshots:
|
|||||||
|
|
||||||
math-intrinsics@1.1.0: {}
|
math-intrinsics@1.1.0: {}
|
||||||
|
|
||||||
|
memoize-one@5.2.1: {}
|
||||||
|
|
||||||
merge2@1.4.1: {}
|
merge2@1.4.1: {}
|
||||||
|
|
||||||
micromatch@4.0.8:
|
micromatch@4.0.8:
|
||||||
@@ -4538,6 +4553,13 @@ snapshots:
|
|||||||
'@remix-run/router': 1.23.0
|
'@remix-run/router': 1.23.0
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
|
|
||||||
|
react-window@1.8.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.28.2
|
||||||
|
memoize-one: 5.2.1
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
react@18.3.1:
|
react@18.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
loose-envify: 1.4.0
|
loose-envify: 1.4.0
|
||||||
|
|||||||
@@ -44,8 +44,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.groupPanel {
|
.groupPanel {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loadMoreContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noMoreText {
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState, useCallback, useEffect } from "react";
|
||||||
import { List, Avatar, Collapse } from "antd";
|
import { List, Avatar, Collapse, Button } from "antd";
|
||||||
import { ContractData } from "@/pages/pc/ckbox/data";
|
import { ContractData } from "@/pages/pc/ckbox/data";
|
||||||
import styles from "./WechatFriends.module.scss";
|
import styles from "./WechatFriends.module.scss";
|
||||||
import { useCkChatStore } from "@/store/module/ckchat";
|
import { useCkChatStore } from "@/store/module/ckchat";
|
||||||
@@ -20,6 +20,14 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
|
|||||||
const newContractList = useCkChatStore(state => state.newContractList);
|
const newContractList = useCkChatStore(state => state.newContractList);
|
||||||
const [activeKey, setActiveKey] = useState<string[]>(["0"]); // 默认展开第一个分组
|
const [activeKey, setActiveKey] = useState<string[]>(["0"]); // 默认展开第一个分组
|
||||||
|
|
||||||
|
// 分页加载相关状态
|
||||||
|
const [visibleContacts, setVisibleContacts] = useState<{
|
||||||
|
[key: string]: ContractData[];
|
||||||
|
}>({});
|
||||||
|
const [loading, setLoading] = useState<{ [key: string]: boolean }>({});
|
||||||
|
const [hasMore, setHasMore] = useState<{ [key: string]: boolean }>({});
|
||||||
|
const [page, setPage] = useState<{ [key: string]: number }>({});
|
||||||
|
|
||||||
// 渲染联系人项
|
// 渲染联系人项
|
||||||
const renderContactItem = (contact: ContractData) => (
|
const renderContactItem = (contact: ContractData) => (
|
||||||
<List.Item
|
<List.Item
|
||||||
@@ -42,6 +50,86 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
|
|||||||
</List.Item>
|
</List.Item>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 初始化分页数据
|
||||||
|
useEffect(() => {
|
||||||
|
if (newContractList && newContractList.length > 0) {
|
||||||
|
const initialVisibleContacts: { [key: string]: ContractData[] } = {};
|
||||||
|
const initialLoading: { [key: string]: boolean } = {};
|
||||||
|
const initialHasMore: { [key: string]: boolean } = {};
|
||||||
|
const initialPage: { [key: string]: number } = {};
|
||||||
|
|
||||||
|
newContractList.forEach((group, index) => {
|
||||||
|
const groupKey = index.toString();
|
||||||
|
// 每个分组初始加载20条数据
|
||||||
|
const pageSize = 20;
|
||||||
|
initialVisibleContacts[groupKey] = group.contacts.slice(0, pageSize);
|
||||||
|
initialLoading[groupKey] = false;
|
||||||
|
initialHasMore[groupKey] = group.contacts.length > pageSize;
|
||||||
|
initialPage[groupKey] = 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
setVisibleContacts(initialVisibleContacts);
|
||||||
|
setLoading(initialLoading);
|
||||||
|
setHasMore(initialHasMore);
|
||||||
|
setPage(initialPage);
|
||||||
|
}
|
||||||
|
}, [newContractList]);
|
||||||
|
|
||||||
|
// 加载更多联系人
|
||||||
|
const loadMoreContacts = useCallback(
|
||||||
|
(groupKey: string) => {
|
||||||
|
if (loading[groupKey] || !hasMore[groupKey] || !newContractList) return;
|
||||||
|
|
||||||
|
setLoading(prev => ({ ...prev, [groupKey]: true }));
|
||||||
|
|
||||||
|
// 模拟异步加载
|
||||||
|
setTimeout(() => {
|
||||||
|
const groupIndex = parseInt(groupKey);
|
||||||
|
const group = newContractList[groupIndex];
|
||||||
|
if (!group) return;
|
||||||
|
|
||||||
|
const pageSize = 20;
|
||||||
|
const currentPage = page[groupKey] || 1;
|
||||||
|
const nextPage = currentPage + 1;
|
||||||
|
const startIndex = currentPage * pageSize;
|
||||||
|
const endIndex = nextPage * pageSize;
|
||||||
|
const newContacts = group.contacts.slice(startIndex, endIndex);
|
||||||
|
|
||||||
|
setVisibleContacts(prev => ({
|
||||||
|
...prev,
|
||||||
|
[groupKey]: [...(prev[groupKey] || []), ...newContacts],
|
||||||
|
}));
|
||||||
|
|
||||||
|
setPage(prev => ({ ...prev, [groupKey]: nextPage }));
|
||||||
|
setHasMore(prev => ({
|
||||||
|
...prev,
|
||||||
|
[groupKey]: endIndex < group.contacts.length,
|
||||||
|
}));
|
||||||
|
|
||||||
|
setLoading(prev => ({ ...prev, [groupKey]: false }));
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
|
[loading, hasMore, page, newContractList],
|
||||||
|
);
|
||||||
|
|
||||||
|
// 渲染加载更多按钮
|
||||||
|
const renderLoadMoreButton = (groupKey: string) => {
|
||||||
|
if (!hasMore[groupKey])
|
||||||
|
return <div className={styles.noMoreText}>没有更多了</div>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.loadMoreContainer}>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
loading={loading[groupKey]}
|
||||||
|
onClick={() => loadMoreContacts(groupKey)}
|
||||||
|
>
|
||||||
|
{loading[groupKey] ? "加载中..." : "加载更多"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.contractListSimple}>
|
<div className={styles.contractListSimple}>
|
||||||
{newContractList && newContractList.length > 0 ? (
|
{newContractList && newContractList.length > 0 ? (
|
||||||
@@ -50,26 +138,36 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
|
|||||||
activeKey={activeKey}
|
activeKey={activeKey}
|
||||||
onChange={keys => setActiveKey(keys as string[])}
|
onChange={keys => setActiveKey(keys as string[])}
|
||||||
>
|
>
|
||||||
{newContractList.map((group, index) => (
|
{newContractList.map((group, index) => {
|
||||||
<Panel
|
const groupKey = index.toString();
|
||||||
header={
|
const isActive = activeKey.includes(groupKey);
|
||||||
<div className={styles.groupHeader}>
|
|
||||||
<span>{group.groupName}</span>
|
return (
|
||||||
<span className={styles.contactCount}>
|
<Panel
|
||||||
{group.contacts.length}
|
header={
|
||||||
</span>
|
<div className={styles.groupHeader}>
|
||||||
</div>
|
<span>{group.groupName}</span>
|
||||||
}
|
<span className={styles.contactCount}>
|
||||||
key={index.toString()}
|
{group.contacts.length}
|
||||||
className={styles.groupPanel}
|
</span>
|
||||||
>
|
</div>
|
||||||
<List
|
}
|
||||||
className={styles.list}
|
key={groupKey}
|
||||||
dataSource={group.contacts}
|
className={styles.groupPanel}
|
||||||
renderItem={renderContactItem}
|
>
|
||||||
/>
|
{isActive && (
|
||||||
</Panel>
|
<>
|
||||||
))}
|
<List
|
||||||
|
className={styles.list}
|
||||||
|
dataSource={visibleContacts[groupKey] || []}
|
||||||
|
renderItem={renderContactItem}
|
||||||
|
/>
|
||||||
|
{renderLoadMoreButton(groupKey)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</Collapse>
|
</Collapse>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from "react";
|
||||||
import { Skeleton, Layout } from 'antd';
|
import { Skeleton, Layout } from "antd";
|
||||||
import styles from './index.module.scss';
|
import styles from "./index.module.scss";
|
||||||
import pageStyles from '../../index.module.scss';
|
import pageStyles from "../../index.module.scss";
|
||||||
|
|
||||||
const { Header, Content, Sider } = Layout;
|
const { Header, Content, Sider } = Layout;
|
||||||
|
|
||||||
@@ -29,7 +29,10 @@ const PageSkeleton: React.FC<PageSkeletonProps> = ({ loading, children }) => {
|
|||||||
{Array(5)
|
{Array(5)
|
||||||
.fill(null)
|
.fill(null)
|
||||||
.map((_, index) => (
|
.map((_, index) => (
|
||||||
<div key={`vertical-${index}`} className={styles.verticalUserItem}>
|
<div
|
||||||
|
key={`vertical-${index}`}
|
||||||
|
className={styles.verticalUserItem}
|
||||||
|
>
|
||||||
<Skeleton.Avatar active size="large" shape="circle" />
|
<Skeleton.Avatar active size="large" shape="circle" />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -42,18 +45,39 @@ const PageSkeleton: React.FC<PageSkeletonProps> = ({ loading, children }) => {
|
|||||||
<Skeleton.Input active size="small" block />
|
<Skeleton.Input active size="small" block />
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.tabsSkeleton}>
|
<div className={styles.tabsSkeleton}>
|
||||||
<Skeleton.Button active size="small" shape="square" style={{ width: '30%' }} />
|
<Skeleton.Button
|
||||||
<Skeleton.Button active size="small" shape="square" style={{ width: '30%' }} />
|
active
|
||||||
|
size="small"
|
||||||
|
shape="square"
|
||||||
|
style={{ width: "30%" }}
|
||||||
|
/>
|
||||||
|
<Skeleton.Button
|
||||||
|
active
|
||||||
|
size="small"
|
||||||
|
shape="square"
|
||||||
|
style={{ width: "30%" }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.contactListSkeleton}>
|
<div className={styles.contactListSkeleton}>
|
||||||
{Array(8)
|
{Array(8)
|
||||||
.fill(null)
|
.fill(null)
|
||||||
.map((_, index) => (
|
.map((_, index) => (
|
||||||
<div key={`contact-${index}`} className={styles.contactItemSkeleton}>
|
<div
|
||||||
|
key={`contact-${index}`}
|
||||||
|
className={styles.contactItemSkeleton}
|
||||||
|
>
|
||||||
<Skeleton.Avatar active size="large" shape="circle" />
|
<Skeleton.Avatar active size="large" shape="circle" />
|
||||||
<div className={styles.contactInfoSkeleton}>
|
<div className={styles.contactInfoSkeleton}>
|
||||||
<Skeleton.Input active size="small" style={{ width: '60%' }} />
|
<Skeleton.Input
|
||||||
<Skeleton.Input active size="small" style={{ width: '80%' }} />
|
active
|
||||||
|
size="small"
|
||||||
|
style={{ width: "60%" }}
|
||||||
|
/>
|
||||||
|
<Skeleton.Input
|
||||||
|
active
|
||||||
|
size="small"
|
||||||
|
style={{ width: "80%" }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -64,7 +88,7 @@ const PageSkeleton: React.FC<PageSkeletonProps> = ({ loading, children }) => {
|
|||||||
<Content className={styles.skeletonMainContent}>
|
<Content className={styles.skeletonMainContent}>
|
||||||
<div className={styles.chatHeaderSkeleton}>
|
<div className={styles.chatHeaderSkeleton}>
|
||||||
<Skeleton.Avatar active size="large" shape="circle" />
|
<Skeleton.Avatar active size="large" shape="circle" />
|
||||||
<Skeleton.Input active size="small" style={{ width: '30%' }} />
|
<Skeleton.Input active size="small" style={{ width: "30%" }} />
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.chatContentSkeleton}>
|
<div className={styles.chatContentSkeleton}>
|
||||||
{Array(5)
|
{Array(5)
|
||||||
@@ -75,7 +99,11 @@ const PageSkeleton: React.FC<PageSkeletonProps> = ({ loading, children }) => {
|
|||||||
className={`${styles.messageSkeleton} ${index % 2 === 0 ? styles.leftMessage : styles.rightMessage}`}
|
className={`${styles.messageSkeleton} ${index % 2 === 0 ? styles.leftMessage : styles.rightMessage}`}
|
||||||
>
|
>
|
||||||
<Skeleton.Avatar active size="small" shape="circle" />
|
<Skeleton.Avatar active size="small" shape="circle" />
|
||||||
<Skeleton.Input active size="small" style={{ width: index % 2 === 0 ? '60%' : '40%' }} />
|
<Skeleton.Input
|
||||||
|
active
|
||||||
|
size="small"
|
||||||
|
style={{ width: index % 2 === 0 ? "60%" : "40%" }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -88,4 +116,4 @@ const PageSkeleton: React.FC<PageSkeletonProps> = ({ loading, children }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PageSkeleton;
|
export default PageSkeleton;
|
||||||
|
|||||||
Reference in New Issue
Block a user