feat(web): show a skeleton while a space loads
Draw the page frame instead of a blank screen, fade it in only after 300ms, and surface load errors with retry and back-to-home actions.
This commit is contained in:
1 parent
e79fbf1112
commit
22f272e361
4 files changed
+193
-4
No files matched your search
@@ -0,0 +1,31 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Button } from '@/ui/Button';
|
||||
import styles from './ChannelSkeleton.module.css';
|
||||
|
||||
const ROWS = [72, 48, 88, 36, 64];
|
||||
|
||||
/** 频道加载中:先画出页面框架(Apple HIG「别留白屏」),内容到了再替换。超过约 300ms 才可见,避免快的时候闪一下 */
|
||||
export function ChannelSkeleton({ error, onRetry, onHome }: { error?: string; onRetry: () => void; onHome: () => void }) {
|
||||
// 与手机聊天页一致:账号入口不浮在骨架屏上
|
||||
useEffect(() => {
|
||||
document.documentElement.dataset.chatShell = '';
|
||||
return () => { delete document.documentElement.dataset.chatShell; };
|
||||
}, []);
|
||||
return <div className={styles.page} role="status" aria-label={error ? '频道加载失败' : '正在加载频道'} aria-busy={!error}>
|
||||
<header className={styles.bar}><span className={`${styles.block} ${styles.title}`} /></header>
|
||||
<aside className={styles.rail}><span className={`${styles.block} ${styles.tile}`} /></aside>
|
||||
<aside className={styles.nav}>{[56, 40, 48].map((w) => <span key={w} className={styles.block} style={{ width: `${w}%` }} />)}</aside>
|
||||
<main className={styles.chat}>
|
||||
{ROWS.map((w, i) => <div key={i} className={styles.message}>
|
||||
<span className={`${styles.block} ${styles.avatar}`} />
|
||||
<div className={styles.lines}><span className={`${styles.block} ${styles.name}`} /><span className={styles.block} style={{ width: `${w}%` }} /></div>
|
||||
</div>)}
|
||||
<div className={`${styles.block} ${styles.composer}`} />
|
||||
</main>
|
||||
<aside className={styles.files}>{[80, 60, 70, 50].map((w) => <span key={w} className={styles.block} style={{ width: `${w}%` }} />)}</aside>
|
||||
{error ? <div className={styles.error} role="alert">
|
||||
<p>频道没能加载:{error}</p>
|
||||
<div><Button variant="primary" onClick={onRetry}>重试</Button><Button variant="ghost" onClick={onHome}>回到首页</Button></div>
|
||||
</div> : null}
|
||||
</div>;
|
||||
}
|
||||
Reference in new issue
Block a user