76 lines
2.7 KiB
TypeScript
76 lines
2.7 KiB
TypeScript
import { useState } from 'react';
|
|
import { Home } from '@/features/home/Home';
|
|
import { JoinScreen, MissingAccess } from '@/features/scan/JoinScreen';
|
|
import { useChannels } from '@/store/channels';
|
|
import { useShares } from '@/store/shares';
|
|
import { useWorkspace } from '@/store/workspace';
|
|
import { ChannelScreen } from './ChannelScreen';
|
|
import { ShareScreen } from './ShareScreen';
|
|
import { channelPath, navigate, useRoute } from './navigation';
|
|
import { Splash } from './Splash';
|
|
|
|
const SEEN_KEY = 'wd.splash';
|
|
|
|
function splashSeen(): boolean {
|
|
try {
|
|
return sessionStorage.getItem(SEEN_KEY) === '1';
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export function App() {
|
|
const route = useRoute();
|
|
const list = useChannels((s) => s.list);
|
|
const channelsHydrated = useChannels((s) => s.hydrated);
|
|
const pendingLink = useChannels((s) => s.pendingLink);
|
|
const setPendingLink = useChannels((s) => s.setPendingLink);
|
|
const sharesHydrated = useShares((s) => s.hydrated);
|
|
const pendingShareLink = useShares((s) => s.pendingLink);
|
|
const wsReady = useWorkspace((s) => s.ready);
|
|
const [splash, setSplash] = useState(() => !splashSeen());
|
|
|
|
const saved = route.name === 'channel' && list.some((c) => c.id === route.id);
|
|
// 只有打开已保存的频道才需要等数据;首页与加入页没有加载过程
|
|
const waitingOnSavedChannel = route.name === 'channel' && !pendingLink && !channelsHydrated;
|
|
const waitingOnSavedShare = route.name === 'share' && pendingShareLink?.id !== route.id && !sharesHydrated;
|
|
const ready = route.name === 'home' || (route.name === 'channel'
|
|
? pendingLink?.id === route.id || (channelsHydrated && (!saved || wsReady))
|
|
: pendingShareLink?.id === route.id || sharesHydrated);
|
|
|
|
function onSplashDone() {
|
|
try {
|
|
sessionStorage.setItem(SEEN_KEY, '1');
|
|
} catch {
|
|
/* 无存储时每次都播,不影响功能 */
|
|
}
|
|
setSplash(false);
|
|
}
|
|
|
|
let screen;
|
|
if (route.name === 'home') screen = <Home />;
|
|
else if (route.name === 'share' && waitingOnSavedShare) screen = null;
|
|
else if (route.name === 'share') screen = <ShareScreen id={route.id} />;
|
|
else if (route.name === 'channel' && waitingOnSavedChannel) screen = null;
|
|
else if (saved) screen = <ChannelScreen id={route.id} />;
|
|
else if (pendingLink?.id === route.id) {
|
|
screen = (
|
|
<JoinScreen
|
|
link={pendingLink}
|
|
onJoined={(c) => navigate(channelPath(c.id))}
|
|
onCancel={() => {
|
|
setPendingLink(null);
|
|
navigate('/');
|
|
}}
|
|
/>
|
|
);
|
|
} else screen = <MissingAccess onHome={() => navigate('/')} />;
|
|
|
|
return (
|
|
<>
|
|
{screen}
|
|
{splash ? <Splash ready={ready} onDone={onSplashDone} /> : null}
|
|
</>
|
|
);
|
|
}
|