/** * Collabora Online 文档查看器组件 * * 功能: * - 加载 Collabora Online iframe * - 管理文档加载状态 * - 提供 UNO 命令接口 * - 支持只读和编辑模式 * * @encoding UTF-8 */ import { useRef, forwardRef, useImperativeHandle, useState } from 'react'; import type { CollaboraViewerProps, CollaboraViewerHandle } from './types'; import { useCollaboraConfig, useDocumentReady, useCollaboraUnoCommands } from './hooks'; import { sendUnoCommand } from './Uno'; /** * Collabora 文档查看器组件 * @param props - 组件属性 * @param ref - 父组件传入的 ref,用于暴露命令接口 */ export const CollaboraViewer = forwardRef( function CollaboraViewer( { fileId, mode = 'view', userId = 'guest', userName = '访客', }, ref ) { const iframeRef = useRef(null); // 调试面板状态 const [unoCmd, setUnoCmd] = useState('.uno:GoToStartOfDoc'); const [unoArgs, setUnoArgs] = useState('{}'); const [unoResult, setUnoResult] = useState(null); // 1. 加载 Collabora 配置 const { config, loading, error } = useCollaboraConfig(fileId, mode, userId, userName); // 2. 监听文档加载状态 const { isDocumentLoaded } = useDocumentReady(iframeRef); // 3. UNO 命令封装 const unoCommands = useCollaboraUnoCommands(iframeRef); // 4. 暴露接口给父组件 useImperativeHandle(ref, () => ({ unoCommands, isReady: isDocumentLoaded, mode, getIframeWindow: () => iframeRef.current?.contentWindow || null, }), [unoCommands, isDocumentLoaded, mode]); // 加载中状态 if (loading) { return (

加载文档配置中...

); } // 错误状态 if (error || !config) { return (

{error || '加载配置失败'}

请刷新页面重试或联系管理员

); } // 发送 UNO 命令的处理函数 const sendUno = () => { if (!iframeRef.current?.contentWindow) { setUnoResult('iframe 不可用'); return; } let args: Record = {}; const raw = (unoArgs || '').trim(); if (raw !== '') { try { args = JSON.parse(raw) as Record; } catch (err) { try { // fallback: replace single quotes with double quotes and parse args = JSON.parse(raw.replace(/'(.*?)'/g, '"$1"')) as Record; } catch (err2) { console.error('解析 UNO Args 失败:', err2); setUnoResult('Args 解析失败,请使用有效 JSON'); return; } } } try { // 使用正确的 sendUnoCommand 方法 sendUnoCommand(iframeRef.current.contentWindow, unoCmd, args); setUnoResult(`已发送: ${unoCmd}`); console.log('[UNO Debug] 发送命令:', unoCmd, args); } catch (e) { console.error('发送 UNO 失败:', e); setUnoResult('发送失败,请查看控制台'); } }; return (
{/* UNO 命令测试面板 */}
setUnoCmd(e.target.value)} placeholder="UNO 命令" aria-label="UNO 命令" /> setUnoArgs(e.target.value)} placeholder="UNO Args (JSON)" aria-label="UNO Args (JSON)" /> {unoResult && {unoResult}}
{/* 文档加载提示 */} {!isDocumentLoaded && (

正在加载文档...

{config.fileName}

)} {/* Collabora iframe - tabIndex is needed for keyboard navigation */} {/* eslint-disable jsx-a11y/no-noninteractive-tabindex */}