Files
shanghai-residences/src/pages/chenyun/reflection/yinyuan/YinyuanBattle.tsx
T

239 lines
7.2 KiB
TypeScript

/**
* 银元之战主组件
* 整合银元之战的所有子组件:文件、线索、题目、引导提示
*/
import { useEffect } from "react";
import { YinyuanFile } from "./YinyuanFile";
import { YinyuanClues } from "./YinyuanClues";
import { YinyuanQuizzes } from "./YinyuanQuizzes";
import { YinyuanGuides } from "./YinyuanGuides";
import { useYinyuanState } from "./useYinyuanState";
import type { FileType } from "../shared/types";
import type { ClueData } from "@/components/layout";
export interface YinyuanBattleProps {
/** 当前展开的文件 */
expandedFile: FileType | null;
/** 是否所有线索都已查看 */
isAllViewed: boolean;
/** 线索状态 */
clueStates: Record<string, boolean>;
/** 文件点击回调 */
onFileClick: () => void;
/** 线索点击回调 */
onClueClick: (clue: ClueData, clueKey: string) => void;
/** 播放视频回调 */
onPlayVideo: (fileType: FileType) => void;
/** 银元之战解决状态变化回调 */
onSolvedChange?: (solved: boolean) => void;
}
/**
* 银元之战主组件
* 管理银元之战的所有状态和逻辑
*/
export const YinyuanBattle = ({
expandedFile,
isAllViewed,
clueStates,
onFileClick,
onClueClick,
onPlayVideo,
onSolvedChange,
}: YinyuanBattleProps) => {
const state = useYinyuanState();
// 当银元之战解决状态变化时,通知父组件
useEffect(() => {
if (onSolvedChange) {
onSolvedChange(state.isYinyuanSolved);
}
}, [state.isYinyuanSolved, onSolvedChange]);
// 监听"前往解决"按钮出现的条件,显示第一个提示
useEffect(() => {
const shouldShowGuide1 =
isAllViewed &&
!state.isYinyuanSolved &&
!state.showQuiz1 &&
!state.showNarration2 &&
!state.showQuiz2 &&
!state.showSuccessAlert &&
!state.hasShownGuide1;
if (shouldShowGuide1) {
// 延迟一下,确保按钮已经渲染
const timer = setTimeout(() => {
state.setShowGuide1(true);
state.setHasShownGuide1(true);
}, 300);
return () => clearTimeout(timer);
}
}, [
isAllViewed,
state.isYinyuanSolved,
state.showQuiz1,
state.showNarration2,
state.showQuiz2,
state.showSuccessAlert,
state.hasShownGuide1,
state.setShowGuide1,
state.setHasShownGuide1,
]);
// 监听走势图图标出现的条件,显示第二个提示
useEffect(() => {
const shouldShowGuide2 =
state.isYinyuanSolved &&
state.showTrendChartIcon &&
!state.hasShownGuide2;
if (shouldShowGuide2) {
// 延迟一下,确保走势图已经渲染
const timer = setTimeout(() => {
state.setShowGuide2(true);
state.setHasShownGuide2(true);
}, 300);
return () => clearTimeout(timer);
}
}, [
state.isYinyuanSolved,
state.showTrendChartIcon,
state.hasShownGuide2,
state.setShowGuide2,
state.setHasShownGuide2,
]);
// 监听走势图大图打开的条件,显示第三个提示
useEffect(() => {
const shouldShowGuide3 =
state.showTrendChartDetail && !state.hasShownGuide3;
if (shouldShowGuide3) {
// 延迟一下,确保大图已经打开
const timer = setTimeout(() => {
state.setShowGuide3(true);
state.setHasShownGuide3(true);
}, 300);
return () => clearTimeout(timer);
}
}, [
state.showTrendChartDetail,
state.hasShownGuide3,
state.setShowGuide3,
state.setHasShownGuide3,
]);
// 处理多选题1提交
const handleQuiz1Submit = (values: string[], isCorrect: boolean) => {
if (isCorrect) {
// 关闭多选题1,显示旁白文字(图2)
state.setShowQuiz1(false);
state.setNarration2Text(
`六月五日,上海政府抛出十万银元,力图以银元制服银元,使价格回跌。全市举行了"反对银元投机,保障人民生活"的游行和宣传。上海市军委会主任陈毅在全市集会上警告投机奸商"赶快洗手不干,否则勿谓言之不预"。但这两手收效仍微。十万银元被投机商人一吸而空,六月七日银元每元的价格涨到一千八百元人民币。陈云同志判断:'单纯的经济手段已不足以震慑敌人,必须辅以坚定的行政与法律手段。`
);
state.setShowNarration2(true);
}
};
// 处理旁白2关闭
const handleNarration2Close = () => {
state.setShowNarration2(false);
// 关闭旁白后显示多选题2
state.setShowQuiz2(true);
};
// 处理多选题2提交
const handleQuiz2Submit = (values: string[], isCorrect: boolean) => {
if (isCorrect) {
// 关闭多选题2,显示成功提示框
state.setShowQuiz2(false);
state.setShowSuccessAlert(true);
}
};
// 处理成功提示框继续
const handleSuccessAlertContinue = () => {
// 关闭聚光灯、标记银元之战为已解决、显示走势图
state.setIsYinyuanSolved(true);
state.setShowSuccessAlert(false);
};
// 处理走势图点击
const handleTrendChartClick = () => {
// 关闭第三个提示框
state.setShowGuide3(false);
// 点击走势图:隐藏文件上的走势图图标,播放米棉之战视频
state.setShowTrendChartIcon(false);
state.setShowTrendChartDetail(false);
// 播放米棉之战视频
onPlayVideo("mimian");
};
// 处理走势图大图关闭
const handleTrendChartDetailClose = () => {
// 关闭第三个提示框
state.setShowGuide3(false);
state.setShowTrendChartDetail(false);
};
return (
<>
{/* 文件组件 */}
<YinyuanFile
expandedFile={expandedFile}
isSolved={state.isYinyuanSolved}
showTrendChartIcon={state.showTrendChartIcon}
isAllViewed={isAllViewed}
showQuiz1={state.showQuiz1}
showNarration2={state.showNarration2}
showQuiz2={state.showQuiz2}
showSuccessAlert={state.showSuccessAlert}
onFileClick={onFileClick}
onTrendChartClick={() => {
state.setShowGuide2(false);
state.setShowTrendChartDetail(true);
}}
onSolveClick={() => {
state.setShowGuide1(false);
state.setShowQuiz1(true);
}}
/>
{/* 线索组件 */}
<YinyuanClues
expandedFile={expandedFile}
clueStates={clueStates}
onClueClick={onClueClick}
/>
{/* 题目组件 */}
<YinyuanQuizzes
showQuiz1={state.showQuiz1}
showNarration2={state.showNarration2}
narration2Text={state.narration2Text}
showQuiz2={state.showQuiz2}
showSuccessAlert={state.showSuccessAlert}
onQuiz1Submit={handleQuiz1Submit}
onNarration2Close={handleNarration2Close}
onQuiz2Submit={handleQuiz2Submit}
onSuccessAlertContinue={handleSuccessAlertContinue}
/>
{/* 引导提示组件 */}
<YinyuanGuides
showGuide1={state.showGuide1}
showGuide2={state.showGuide2}
showGuide3={state.showGuide3}
showTrendChartDetail={state.showTrendChartDetail}
onGuide1Close={() => state.setShowGuide1(false)}
onGuide2Close={() => state.setShowGuide2(false)}
onGuide3Close={() => state.setShowGuide3(false)}
onTrendChartDetailClose={handleTrendChartDetailClose}
onTrendChartClick={handleTrendChartClick}
/>
</>
);
};