95 lines
2.9 KiB
TypeScript
95 lines
2.9 KiB
TypeScript
/**
|
|
* Collabora Online 文档查看器组件
|
|
*
|
|
* 功能:
|
|
* - 加载 Collabora Online iframe
|
|
* - 管理文档加载状态
|
|
* - 提供 UNO 命令接口
|
|
* - 支持只读和编辑模式
|
|
*
|
|
* @encoding UTF-8
|
|
*/
|
|
|
|
import { useRef } from 'react';
|
|
import type { CollaboraViewerProps } from './types';
|
|
import { useCollaboraConfig, useDocumentReady, useCollaboraUnoCommands } from './hooks';
|
|
|
|
/**
|
|
* Collabora 文档查看器组件
|
|
* @param props - 组件属性
|
|
*/
|
|
export function CollaboraViewer({
|
|
fileId,
|
|
mode = 'view',
|
|
userId = 'guest',
|
|
userName = '访客',
|
|
}: CollaboraViewerProps) {
|
|
const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
|
|
// 1. 加载 Collabora 配置
|
|
const { config, loading, error } = useCollaboraConfig(fileId, mode, userId, userName);
|
|
|
|
// 2. 监听文档加载状态
|
|
const { isDocumentLoaded } = useDocumentReady(iframeRef);
|
|
|
|
// 3. UNO 命令封装
|
|
const unoCommands = useCollaboraUnoCommands(iframeRef);
|
|
|
|
// 加载中状态
|
|
if (loading) {
|
|
return (
|
|
<div className="flex justify-center items-center h-full min-h-[600px]">
|
|
<div className="text-center">
|
|
<div className="inline-block animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
|
|
<p className="mt-4 text-gray-600">加载文档配置中...</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// 错误状态
|
|
if (error || !config) {
|
|
return (
|
|
<div className="flex justify-center items-center h-full min-h-[600px]">
|
|
<div className="text-center text-red-500">
|
|
<i className="ri-error-warning-line text-4xl mb-2"></i>
|
|
<p className="text-lg">{error || '加载配置失败'}</p>
|
|
<p className="text-sm text-gray-500 mt-2">请刷新页面重试或联系管理员</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="collabora-viewer relative w-full h-full min-h-[600px]">
|
|
{/* 文档加载提示 */}
|
|
{!isDocumentLoaded && (
|
|
<div className="absolute inset-0 flex items-center justify-center bg-white bg-opacity-90 z-10">
|
|
<div className="text-center">
|
|
<div className="inline-block animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
|
|
<p className="mt-4 text-gray-600">正在加载文档...</p>
|
|
<p className="text-sm text-gray-500 mt-2">{config.fileName}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Collabora iframe */}
|
|
<iframe
|
|
ref={iframeRef}
|
|
src={config.iframeUrl}
|
|
className="w-full h-full border-0"
|
|
style={{
|
|
minHeight: '600px',
|
|
height: '100%',
|
|
}}
|
|
allow="clipboard-read; clipboard-write"
|
|
title={`Collabora Online - ${config.fileName}`}
|
|
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-modals"
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// 导出 UNO 命令 hook 供父组件使用(如果需要)
|
|
export { useCollaboraUnoCommands };
|