279 lines
11 KiB
TypeScript
279 lines
11 KiB
TypeScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
|
|
import {AutoFocusPlugin} from '@lexical/react/LexicalAutoFocusPlugin';
|
|
import {CharacterLimitPlugin} from '@lexical/react/LexicalCharacterLimitPlugin';
|
|
import {CheckListPlugin} from '@lexical/react/LexicalCheckListPlugin';
|
|
import {ClearEditorPlugin} from '@lexical/react/LexicalClearEditorPlugin';
|
|
import LexicalClickableLinkPlugin from '@lexical/react/LexicalClickableLinkPlugin';
|
|
import {CollaborationPlugin} from '@lexical/react/LexicalCollaborationPlugin';
|
|
import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary';
|
|
import {HashtagPlugin} from '@lexical/react/LexicalHashtagPlugin';
|
|
import {HistoryPlugin} from '@lexical/react/LexicalHistoryPlugin';
|
|
import {HorizontalRulePlugin} from '@lexical/react/LexicalHorizontalRulePlugin';
|
|
import {ListPlugin} from '@lexical/react/LexicalListPlugin';
|
|
import {PlainTextPlugin} from '@lexical/react/LexicalPlainTextPlugin';
|
|
import {RichTextPlugin} from '@lexical/react/LexicalRichTextPlugin';
|
|
import {TabIndentationPlugin} from '@lexical/react/LexicalTabIndentationPlugin';
|
|
import {TablePlugin} from '@lexical/react/LexicalTablePlugin';
|
|
import useLexicalEditable from '@lexical/react/useLexicalEditable';
|
|
import {useEffect, useState,useLayoutEffect} from 'react';
|
|
import {CAN_USE_DOM} from './shared/src/canUseDOM';
|
|
|
|
import {createWebsocketProvider} from './collaboration';
|
|
import {useSettings} from './context/SettingsContext';
|
|
import {useSharedHistoryContext} from './context/SharedHistoryContext';
|
|
import ActionsPlugin from './plugins/ActionsPlugin';
|
|
import AutocompletePlugin from './plugins/AutocompletePlugin';
|
|
import AutoEmbedPlugin from './plugins/AutoEmbedPlugin';
|
|
import AutoLinkPlugin from './plugins/AutoLinkPlugin';
|
|
import CodeActionMenuPlugin from './plugins/CodeActionMenuPlugin';
|
|
import CodeHighlightPlugin from './plugins/CodeHighlightPlugin';
|
|
import CollapsiblePlugin from './plugins/CollapsiblePlugin';
|
|
import CommentPlugin from './plugins/CommentPlugin';
|
|
import ComponentPickerPlugin from './plugins/ComponentPickerPlugin';
|
|
import ContextMenuPlugin from './plugins/ContextMenuPlugin';
|
|
import DragDropPaste from './plugins/DragDropPastePlugin';
|
|
import DraggableBlockPlugin from './plugins/DraggableBlockPlugin';
|
|
import EmojiPickerPlugin from './plugins/EmojiPickerPlugin';
|
|
import EmojisPlugin from './plugins/EmojisPlugin';
|
|
import EquationsPlugin from './plugins/EquationsPlugin';
|
|
import ExcalidrawPlugin from './plugins/ExcalidrawPlugin';
|
|
import FigmaPlugin from './plugins/FigmaPlugin';
|
|
import FloatingLinkEditorPlugin from './plugins/FloatingLinkEditorPlugin';
|
|
import FloatingTextFormatToolbarPlugin from './plugins/FloatingTextFormatToolbarPlugin';
|
|
import ImagesPlugin from './plugins/ImagesPlugin';
|
|
import InlineImagePlugin from './plugins/InlineImagePlugin';
|
|
import KeywordsPlugin from './plugins/KeywordsPlugin';
|
|
import {LayoutPlugin} from './plugins/LayoutPlugin/LayoutPlugin';
|
|
import LinkPlugin from './plugins/LinkPlugin';
|
|
import ListMaxIndentLevelPlugin from './plugins/ListMaxIndentLevelPlugin';
|
|
import MarkdownShortcutPlugin from './plugins/MarkdownShortcutPlugin';
|
|
import {MaxLengthPlugin} from './plugins/MaxLengthPlugin';
|
|
import MentionsPlugin from './plugins/MentionsPlugin';
|
|
import PageBreakPlugin from './plugins/PageBreakPlugin';
|
|
import PollPlugin from './plugins/PollPlugin';
|
|
import SpeechToTextPlugin from './plugins/SpeechToTextPlugin';
|
|
import TabFocusPlugin from './plugins/TabFocusPlugin';
|
|
import TableCellActionMenuPlugin from './plugins/TableActionMenuPlugin';
|
|
import TableCellResizer from './plugins/TableCellResizer';
|
|
import TableOfContentsPlugin from './plugins/TableOfContentsPlugin';
|
|
import ToolbarPlugin from './plugins/ToolbarPlugin';
|
|
import TreeViewPlugin from './plugins/TreeViewPlugin';
|
|
import TwitterPlugin from './plugins/TwitterPlugin';
|
|
import YouTubePlugin from './plugins/YouTubePlugin';
|
|
import ContentEditable from './ui/ContentEditable';
|
|
import Placeholder from './ui/Placeholder';
|
|
|
|
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
|
|
import GlobalEventsPlugin from "./plugins/GlobalEventsPlugin";
|
|
|
|
const skipCollaborationInit =
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-expect-error
|
|
window.parent != null && window.parent.frames.right === window;
|
|
|
|
|
|
function OnChangePlugin({ onChange }) {
|
|
const [editor] = useLexicalComposerContext();
|
|
useEffect(() => {
|
|
return editor.registerUpdateListener(({editorState}) => {
|
|
onChange(editorState);
|
|
});
|
|
}, [editor, onChange]);
|
|
}
|
|
|
|
export default function Editor(props: { noteId: bigint; noteTitle: string; editData: any; handleLawClick_item2: any; }): JSX.Element {
|
|
const [editor] = useLexicalComposerContext();
|
|
|
|
console.log(props.noteId)
|
|
|
|
const {historyState} = useSharedHistoryContext();
|
|
const {
|
|
settings: {
|
|
isCollab,
|
|
isAutocomplete,
|
|
isMaxLength,
|
|
isCharLimit,
|
|
isCharLimitUtf8,
|
|
isRichText,
|
|
showTreeView,
|
|
showTableOfContents,
|
|
shouldUseLexicalContextMenu,
|
|
tableCellMerge,
|
|
tableCellBackgroundColor,
|
|
},
|
|
} = useSettings();
|
|
const isEditable = useLexicalEditable();
|
|
const text = isCollab
|
|
? 'Enter some collaborative rich text...'
|
|
: isRichText
|
|
? 'Enter some rich text...'
|
|
: 'Enter some plain text...';
|
|
const placeholder = <Placeholder>{text}</Placeholder>;
|
|
const [floatingAnchorElem, setFloatingAnchorElem] =
|
|
useState<HTMLDivElement | null>(null);
|
|
const [isSmallWidthViewport, setIsSmallWidthViewport] =
|
|
useState<boolean>(false);
|
|
const [isLinkEditMode, setIsLinkEditMode] = useState<boolean>(false);
|
|
const [editorState, setEditorState] = useState();
|
|
const onRef = (_floatingAnchorElem: HTMLDivElement) => {
|
|
if (_floatingAnchorElem !== null) {
|
|
setFloatingAnchorElem(_floatingAnchorElem);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
const updateViewPortWidth = () => {
|
|
const isNextSmallWidthViewport =
|
|
CAN_USE_DOM && window.matchMedia('(max-width: 1025px)').matches;
|
|
|
|
if (isNextSmallWidthViewport !== isSmallWidthViewport) {
|
|
setIsSmallWidthViewport(isNextSmallWidthViewport);
|
|
}
|
|
};
|
|
updateViewPortWidth();
|
|
window.addEventListener('resize', updateViewPortWidth);
|
|
|
|
return () => {
|
|
window.removeEventListener('resize', updateViewPortWidth);
|
|
};
|
|
}, [isSmallWidthViewport]);
|
|
|
|
|
|
function onChange(editorState) {
|
|
// Call toJSON on the EditorState object, which produces a serialization safe string
|
|
const editorStateJSON = editorState.toJSON();
|
|
|
|
// However, we still have a JavaScript object, so we need to convert it to an actual string with JSON.stringify
|
|
setEditorState(JSON.stringify(editorStateJSON));
|
|
|
|
}
|
|
|
|
console.log(props.noteId)
|
|
// console.log(props.editData)
|
|
|
|
return (
|
|
<>
|
|
{isRichText && <ToolbarPlugin setIsLinkEditMode={setIsLinkEditMode} />}
|
|
<div
|
|
className={`editor-container ${showTreeView ? 'tree-view' : ''} ${
|
|
!isRichText ? 'plain-text' : ''
|
|
}`}>
|
|
{isMaxLength && <MaxLengthPlugin maxLength={30} />}
|
|
<DragDropPaste />
|
|
<AutoFocusPlugin />
|
|
<ClearEditorPlugin />
|
|
<ComponentPickerPlugin />
|
|
<EmojiPickerPlugin />
|
|
<AutoEmbedPlugin />
|
|
|
|
<MentionsPlugin />
|
|
<EmojisPlugin />
|
|
<HashtagPlugin />
|
|
<KeywordsPlugin />
|
|
<SpeechToTextPlugin />
|
|
<AutoLinkPlugin />
|
|
<CommentPlugin
|
|
providerFactory={isCollab ? createWebsocketProvider : undefined}
|
|
/>
|
|
{isRichText ? (
|
|
<>
|
|
{isCollab ? (
|
|
<CollaborationPlugin
|
|
id="main"
|
|
providerFactory={createWebsocketProvider}
|
|
shouldBootstrap={!skipCollaborationInit}
|
|
/>
|
|
) : (
|
|
<HistoryPlugin externalHistoryState={historyState} />
|
|
)}
|
|
<RichTextPlugin
|
|
contentEditable={
|
|
<div className="editor-scroller">
|
|
<div className="editor" ref={onRef}>
|
|
<ContentEditable />
|
|
</div>
|
|
</div>
|
|
}
|
|
placeholder={placeholder}
|
|
ErrorBoundary={LexicalErrorBoundary}
|
|
/>
|
|
<MarkdownShortcutPlugin />
|
|
<CodeHighlightPlugin />
|
|
<ListPlugin />
|
|
<CheckListPlugin />
|
|
<ListMaxIndentLevelPlugin maxDepth={7} />
|
|
<TablePlugin
|
|
hasCellMerge={tableCellMerge}
|
|
hasCellBackgroundColor={tableCellBackgroundColor}
|
|
/>
|
|
<TableCellResizer />
|
|
<ImagesPlugin />
|
|
<InlineImagePlugin />
|
|
<LinkPlugin />
|
|
<PollPlugin />
|
|
<TwitterPlugin />
|
|
<YouTubePlugin />
|
|
<FigmaPlugin />
|
|
{!isEditable && <LexicalClickableLinkPlugin />}
|
|
<HorizontalRulePlugin />
|
|
<EquationsPlugin />
|
|
<ExcalidrawPlugin />
|
|
<TabFocusPlugin />
|
|
<TabIndentationPlugin />
|
|
<CollapsiblePlugin />
|
|
<PageBreakPlugin />
|
|
<LayoutPlugin />
|
|
<OnChangePlugin onChange={onChange}/>
|
|
<GlobalEventsPlugin />
|
|
{floatingAnchorElem && !isSmallWidthViewport && (
|
|
<>
|
|
<DraggableBlockPlugin anchorElem={floatingAnchorElem} />
|
|
<CodeActionMenuPlugin anchorElem={floatingAnchorElem} />
|
|
<FloatingLinkEditorPlugin
|
|
anchorElem={floatingAnchorElem}
|
|
isLinkEditMode={isLinkEditMode}
|
|
setIsLinkEditMode={setIsLinkEditMode}
|
|
/>
|
|
<TableCellActionMenuPlugin
|
|
anchorElem={floatingAnchorElem}
|
|
cellMerge={true}
|
|
/>
|
|
<FloatingTextFormatToolbarPlugin
|
|
anchorElem={floatingAnchorElem}
|
|
/>
|
|
</>
|
|
)}
|
|
</>
|
|
) : (
|
|
<>
|
|
<PlainTextPlugin
|
|
contentEditable={<ContentEditable />}
|
|
placeholder={placeholder}
|
|
ErrorBoundary={LexicalErrorBoundary}
|
|
/>
|
|
<HistoryPlugin externalHistoryState={historyState} />
|
|
</>
|
|
)}
|
|
{(isCharLimit || isCharLimitUtf8) && (
|
|
<CharacterLimitPlugin
|
|
charset={isCharLimit ? 'UTF-16' : 'UTF-8'}
|
|
maxLength={5}
|
|
/>
|
|
)}
|
|
{isAutocomplete && <AutocompletePlugin />}
|
|
<div>{showTableOfContents && <TableOfContentsPlugin />}</div>
|
|
{shouldUseLexicalContextMenu && <ContextMenuPlugin />}
|
|
<ActionsPlugin isRichText={isRichText} noteId={props.noteId} noteTitle={props.noteTitle} editData ={props.editData} handleLawClick_item3={props.handleLawClick_item2}/>
|
|
</div>
|
|
{showTreeView && <TreeViewPlugin />}
|
|
</>
|
|
);
|
|
}
|