/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unused-vars */ // app/components/Editor/MonacoEditor.tsx 'use client' import { useRef, useCallback, useEffect } from 'react' import Editor from '@monaco-editor/react' import * as Y from 'yjs' import { WebsocketProvider } from 'y-websocket' import { MonacoBinding } from 'y-monaco' import { message } from 'antd' import { DocumentService } from '@/app/lib/services/document' interface MonacoEditorProps { docId: string defaultValue?: string onContentChange?: (content: string) => void } export default function MonacoEditor({ docId, defaultValue = '', onContentChange }: MonacoEditorProps) { const editorRef = useRef(null) const monacoRef = useRef(null) // 自动保存防抖 const autoSaveDebounced = useCallback( debounce(async (content: string) => { try { await DocumentService.saveDocument({ id: docId, content, }) message.success('自动保存成功') } catch (error) { message.error('自动保存失败'+error) } }, 2000), [docId] ) // 手动保存 const saveContent = async () => { if (!editorRef.current) return const content = editorRef.current.getValue() try { await DocumentService.saveDocument({ id: docId, content, }) message.success('保存成功') } catch (error) { message.error('保存失败'+error) } } // 监听内容变化 const handleEditorChange = (value: string | undefined) => { if (value === undefined) return onContentChange?.(value) autoSaveDebounced(value) } useEffect(() => { if (!editorRef.current) return const ydoc = new Y.Doc() const provider = new WebsocketProvider( 'ws://localhost:1234', docId, ydoc ) const type = ydoc.getText('monaco') const binding = new MonacoBinding( type, editorRef.current.getModel(), new Set([editorRef.current]), provider.awareness ) // 添加快捷键保存 editorRef.current.addCommand( monacoRef.current.KeyMod.CtrlCmd | monacoRef.current.KeyCode.KeyS, () => { saveContent() } ) return () => { ydoc.destroy() provider.destroy() } }, [docId]) function handleEditorDidMount(editor: any, monaco: any) { editorRef.current = editor monacoRef.current = monaco editor.updateOptions({ fontSize: 14, fontFamily: 'JetBrains Mono, Consolas, monospace', minimap: { enabled: false }, scrollBeyondLastLine: false, lineNumbers: 'on', renderWhitespace: 'boundary', wordWrap: 'on', }) } return (
) } // 防抖函数 function debounce(func: Function, wait: number) { let timeout: NodeJS.Timeout return function executedFunction(...args: any[]) { const later = () => { clearTimeout(timeout) func(...args) } clearTimeout(timeout) timeout = setTimeout(later, wait) } }