'use client';
import { useEffect, useRef, useState, useCallback, useMemo } from 'react';
import Reveal from 'reveal.js';
import 'reveal.js/dist/reveal.css';
import { marked } from 'marked';
// 简单的动态主题加载器
const loadTheme = async (themeName) => {
if (!themeName) return;
try {
// 1. 优先尝试加载自定义主题
await import(`./themes/${themeName}.css`);
console.log(`加载自定义主题: ${themeName}`);
} catch (error) {
try {
// 2. 尝试加载 Reveal.js 内置主题
await import(`reveal.js/dist/theme/${themeName}.css`);
console.log(`加载内置主题: ${themeName}`);
} catch (error2) {
// 3. 如果都失败,使用默认主题
console.warn(`主题 ${themeName} 未找到,使用默认主题`);
await import('reveal.js/dist/theme/black.css');
}
}
};
// Reveal.js配置
const REVEAL_CONFIG = {
hash: true,
transition: 'slide',
transitionSpeed: 'default',
backgroundTransition: 'fade',
controls: true,
progress: true,
center: true,
touch: true,
loop: false,
rtl: false,
navigationMode: 'default',
shuffle: false,
fragments: true,
fragmentInURL: false,
embedded: false,
help: true,
showNotes: true,
autoPlayMedia: null,
preloadIframes: null,
autoSlide: 0,
autoSlideStoppable: true,
autoSlideMethod: Reveal.navigateNext,
defaultTiming: null,
mouseWheel: false,
hideInactiveCursor: true,
hideCursorTime: 5000,
previewLinks: false,
postMessage: true,
postMessageEvents: false,
focusBodyOnPageVisibilityChange: true,
viewDistance: 3,
mobileViewDistance: 2,
display: 'block',
hideAnchorsOnUrl: false,
plugins: []
};
// 配置marked解析器(只配置一次)
marked.setOptions({
breaks: true,
gfm: true,
headerIds: false,
mangle: false,
});
export default function Presentation({ data }) {
const deckRef = useRef(null);
const revealRef = useRef(null);
const [mounted, setMounted] = useState(false);
const [error, setError] = useState(null);
// 客户端挂载检测
useEffect(() => {
setMounted(true);
}, []);
// 解析Markdown内容为幻灯片
const parseMarkdownToSlides = useCallback((data) => {
if (!data) {
return ` 暂无内容 暂无内容 内容解析失败,请检查数据格式演示文稿
${data.title || '演示文稿'}
解析错误
PPT加载失败
{error}
正在加载内容...