Configure board deployment and backend proxy
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { CloudHeader } from '../components/CloudHeader';
|
||||
import { FullscreenButton } from '../components/FullscreenButton';
|
||||
import { QRPanel } from '../components/QRPanel';
|
||||
import { WordCloudCanvas } from '../components/WordCloudCanvas';
|
||||
import { CloudLoadingState } from '../components/CloudLoadingState';
|
||||
import { CloudUnavailableState } from '../components/CloudUnavailableState';
|
||||
import { useFocusQueue } from '../hooks/useFocusQueue';
|
||||
import { useCloud } from '../hooks/useCloud';
|
||||
import { useWordCloudChannel } from '../hooks/useWordCloudChannel';
|
||||
import { useWordCloudFocus } from '../hooks/useWordCloudFocus';
|
||||
import { TitleFrost } from '../components/TitleFrost';
|
||||
import type { FocusEvent } from '../types/channel';
|
||||
import styles from './PublicDisplayPage.module.css';
|
||||
|
||||
interface PublicDisplayPageProps {
|
||||
cloudId: string;
|
||||
}
|
||||
|
||||
export function PublicDisplayPage({ cloudId }: PublicDisplayPageProps) {
|
||||
const cloudState = useCloud(cloudId);
|
||||
const cloud = cloudState.cloud;
|
||||
const queue = useFocusQueue();
|
||||
const focus = useWordCloudFocus({
|
||||
words: cloud?.words ?? [],
|
||||
autoReturn: true,
|
||||
onComplete: queue.advance,
|
||||
});
|
||||
|
||||
const receiveMessage = useCallback(
|
||||
(message: FocusEvent) => {
|
||||
queue.enqueue(message);
|
||||
},
|
||||
[queue],
|
||||
);
|
||||
useWordCloudChannel(cloudId, receiveMessage);
|
||||
|
||||
useEffect(() => {
|
||||
if (!queue.current || focus.phase !== 'idle' || !cloud) {
|
||||
return;
|
||||
}
|
||||
|
||||
const found = focus.focusName(queue.current.name, queue.current.targetIndex ?? 0);
|
||||
|
||||
if (!found) {
|
||||
queue.advance();
|
||||
}
|
||||
}, [cloud, focus, queue]);
|
||||
|
||||
if (cloudState.status === 'loading') {
|
||||
return <CloudLoadingState />;
|
||||
}
|
||||
|
||||
if (!cloud) {
|
||||
return <CloudUnavailableState />;
|
||||
}
|
||||
|
||||
return (
|
||||
<main className={styles.page} aria-label="大屏展示词云">
|
||||
<WordCloudCanvas
|
||||
words={cloud.words}
|
||||
phase={focus.phase}
|
||||
transform={focus.transform}
|
||||
activeIds={focus.activeIds}
|
||||
cloudRef={focus.cloudRef}
|
||||
onPointerDown={focus.handlePointerDown}
|
||||
onPointerMove={focus.handlePointerMove}
|
||||
onPointerUp={focus.handlePointerUp}
|
||||
onWheel={focus.handleWheel}
|
||||
onKeyDown={focus.handleKeyDown}
|
||||
sourceCanvas={cloud.sourceCanvas}
|
||||
sourceSvg={cloud.sourceSvg}
|
||||
viewport={focus.viewport}
|
||||
/>
|
||||
<TitleFrost />
|
||||
<CloudHeader
|
||||
eyebrow={cloud.eyebrow}
|
||||
title={cloud.title}
|
||||
subtitle={cloud.subtitle}
|
||||
dimmed={focus.phase !== 'idle'}
|
||||
layered
|
||||
/>
|
||||
<p className={styles.caption}>{cloud.caption}</p>
|
||||
<QRPanel cloudId={cloudId} />
|
||||
<FullscreenButton />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user