UNPKG

@droppii-org/chat-sdk

Version:

Droppii React Chat SDK

80 lines (79 loc) 3.98 kB
"use client"; import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext"; import { KEY_ENTER_COMMAND, COMMAND_PRIORITY_NORMAL, $getSelection, $isRangeSelection, $createParagraphNode, $getRoot, } from "lexical"; import { useEffect, useRef } from "react"; import { $generateHtmlFromNodes } from "@lexical/html"; import { $isListNode, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, } from "@lexical/list"; import { $isQuoteNode } from "@lexical/rich-text"; import { useMessageFooterContext } from "."; export default function EnterHandler() { const [editor] = useLexicalComposerContext(); const { onSendMessage } = useMessageFooterContext(); const shiftEnterCount = useRef(0); const { listUploadFiles } = useMessageFooterContext(); useEffect(() => { return editor.registerCommand(KEY_ENTER_COMMAND, (event) => { // Case 1: Enter (submit, chặn xuống dòng) if (!event.shiftKey) { event.preventDefault(); shiftEnterCount.current = 0; let plainText = ""; let richText = ""; // lấy plain text & html editor.getEditorState().read(() => { plainText = $getRoot().getTextContent(); richText = $generateHtmlFromNodes(editor); }); if (plainText.trim().length > 0 || listUploadFiles.length > 0) { onSendMessage({ plainText, richText, type: listUploadFiles.length > 0 ? "file" : "text", }); } editor.update(() => { const root = $getRoot(); root.clear(); const paragraph = $createParagraphNode(); root.append(paragraph); paragraph.select(); const selection = $getSelection(); if ($isRangeSelection(selection)) { const anchorNode = selection.anchor.getNode(); const topLevelNode = anchorNode.getTopLevelElementOrThrow(); const isListNode = $isListNode(topLevelNode); const isQuoteNode = $isQuoteNode(topLevelNode); const listType = isListNode ? topLevelNode.getListType() : undefined; if (selection.hasFormat("bold")) { selection.formatText("bold"); } if (selection.hasFormat("italic")) { selection.formatText("italic"); } if (selection.hasFormat("strikethrough")) { selection.formatText("strikethrough"); } if (isQuoteNode) { // Nếu đang là QuoteNode → chuyển về Paragraph (bình thường) const paragraph = $createParagraphNode(); // copy con của quote sang paragraph const children = topLevelNode.getChildren(); children.forEach((child) => paragraph.append(child)); topLevelNode.replace(paragraph); } if (isListNode && listType) { editor.dispatchCommand(listType === "number" ? INSERT_ORDERED_LIST_COMMAND : INSERT_UNORDERED_LIST_COMMAND, undefined); } } }); return true; } return false; }, COMMAND_PRIORITY_NORMAL); }, [editor, onSendMessage, listUploadFiles]); return null; }