feat: 尝试删除索引的时候删除整个段落
This commit is contained in:
parent
d56f427484
commit
732dd738c9
44
components/ParagraphDeleteInterface.tsx
Normal file
44
components/ParagraphDeleteInterface.tsx
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { faL } from "@fortawesome/free-solid-svg-icons";
|
||||
import React from "react";
|
||||
import Swal from "sweetalert2";
|
||||
|
||||
// 定义Props类型
|
||||
interface SweetAlertComponentProps {
|
||||
index: number;
|
||||
removeReferenceUpdateIndex: (index: number, rmPg: boolean) => void;
|
||||
}
|
||||
|
||||
const ParagraphDeleteButton: React.FC<SweetAlertComponentProps> = ({
|
||||
index,
|
||||
removeReferenceUpdateIndex,
|
||||
}) => {
|
||||
const showAlert = async () => {
|
||||
const result = await Swal.fire({
|
||||
title: "需要同时删除与文献相关的整个段落吗?",
|
||||
text: "根据周围的换行符来判断是否是同一个段落",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#3085d6",
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonText: "Yes, delete it!",
|
||||
});
|
||||
if (result.isConfirmed) {
|
||||
removeReferenceUpdateIndex(index, true);
|
||||
// Swal.fire("Deleted!", "Your file has been deleted.", "success");
|
||||
} else {
|
||||
removeReferenceUpdateIndex(index, false);
|
||||
// Swal.fire("Cancelled", "Your imaginary file is safe :)", "error");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
className="text-red-500 hover:text-red-700 ml-4"
|
||||
onClick={showAlert} // 直接使用showAlert而不传递参数
|
||||
>
|
||||
X
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default ParagraphDeleteButton;
|
|
@ -56,7 +56,7 @@ const QEditor = () => {
|
|||
const upsreamUrl = useAppSelector((state: any) => state.auth.upsreamUrl);
|
||||
const [quill, setQuill] = useState(null);
|
||||
//询问ai,用户输入
|
||||
const [userInput, setUserInput] = useState("");
|
||||
const [userInput, setUserInput] = useState("robot");
|
||||
//quill编辑器鼠标位置
|
||||
const [cursorPosition, setCursorPosition] = useState(null);
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@ import {
|
|||
formatAllReferencesForCopy,
|
||||
delteIndexUpdateBracketNumbersInDeltaKeepSelection,
|
||||
} from "@/utils/others/quillutils";
|
||||
//删除文献按钮
|
||||
import ParagraphDeleteButton from "@/components/ParagraphDeleteInterface";
|
||||
|
||||
//redux
|
||||
import { useAppDispatch, useAppSelector } from "@/app/store";
|
||||
import {
|
||||
|
@ -51,10 +54,9 @@ function ReferenceList({ editor }: ReferenceListProps) {
|
|||
dispatch(swapReferencesRedux({ indexA: index, indexB: index + 1 }));
|
||||
}
|
||||
|
||||
function removeReferenceUpdateIndex(index: number) {
|
||||
// removeReference(index);
|
||||
function removeReferenceUpdateIndex(index: number, rmPg = false) {
|
||||
handleRemoveReference(index);
|
||||
delteIndexUpdateBracketNumbersInDeltaKeepSelection(editor, index);
|
||||
delteIndexUpdateBracketNumbersInDeltaKeepSelection(editor, index, rmPg);
|
||||
}
|
||||
|
||||
const handleAddReference = (newReference: Reference) => {
|
||||
|
@ -205,12 +207,16 @@ function ReferenceList({ editor }: ReferenceListProps) {
|
|||
>
|
||||
复制
|
||||
</button>
|
||||
<button
|
||||
{/* <button
|
||||
className="text-red-500 hover:text-red-700 ml-4"
|
||||
onClick={() => removeReferenceUpdateIndex(index)}
|
||||
>
|
||||
X
|
||||
</button>
|
||||
</button> */}
|
||||
<ParagraphDeleteButton
|
||||
index={index}
|
||||
removeReferenceUpdateIndex={removeReferenceUpdateIndex}
|
||||
></ParagraphDeleteButton>
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
|
|
15
package-lock.json
generated
15
package-lock.json
generated
|
@ -39,6 +39,7 @@
|
|||
"slate-history": "^0.100.0",
|
||||
"slate-hyperscript": "^0.100.0",
|
||||
"slate-react": "^0.101.5",
|
||||
"sweetalert2": "^11.10.4",
|
||||
"tailwindcss": "3.3.3",
|
||||
"typescript": "5.1.3",
|
||||
"xml2js": "^0.6.2"
|
||||
|
@ -3045,6 +3046,15 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/sweetalert2": {
|
||||
"version": "11.10.4",
|
||||
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.4.tgz",
|
||||
"integrity": "sha512-MOVRuEW/yQsyzgkaiHqAJcYKxW3vhtE5o3Skp6vZdyJejCOWo4FOicbjRfvqHAXTyTMuwDHA+0lYbO6BiHl1Gw==",
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/limonte"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz",
|
||||
|
@ -5530,6 +5540,11 @@
|
|||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
|
||||
},
|
||||
"sweetalert2": {
|
||||
"version": "11.10.4",
|
||||
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.4.tgz",
|
||||
"integrity": "sha512-MOVRuEW/yQsyzgkaiHqAJcYKxW3vhtE5o3Skp6vZdyJejCOWo4FOicbjRfvqHAXTyTMuwDHA+0lYbO6BiHl1Gw=="
|
||||
},
|
||||
"tailwindcss": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz",
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
"slate-history": "^0.100.0",
|
||||
"slate-hyperscript": "^0.100.0",
|
||||
"slate-react": "^0.101.5",
|
||||
"sweetalert2": "^11.10.4",
|
||||
"tailwindcss": "3.3.3",
|
||||
"typescript": "5.1.3",
|
||||
"xml2js": "^0.6.2"
|
||||
|
|
|
@ -46,23 +46,138 @@ function updateBracketNumbersInDelta(delta) {
|
|||
return { ops: updatedOps };
|
||||
}
|
||||
|
||||
function deleteUpdateBracketNumbers(delta, indexToRemove: number, quill) {
|
||||
const updatedOps = delta.ops.map((op) => {
|
||||
function deleteReferenceNumberOrParagraph(
|
||||
delta,
|
||||
indexToRemove: number,
|
||||
quill,
|
||||
deleteParagraph: boolean
|
||||
) {
|
||||
const indexStr = `[${indexToRemove + 1}]`;
|
||||
const updatedOps = delta.ops.flatMap((op, i) => {
|
||||
if (typeof op.insert === "string") {
|
||||
// 如果文本包含要删除的索引,删除它
|
||||
const indexStr = `[${indexToRemove + 1}]`;
|
||||
const indexPos = op.insert.indexOf(indexStr);
|
||||
if (indexPos !== -1) {
|
||||
const before = op.insert.slice(0, indexPos);
|
||||
const after = op.insert.slice(indexPos + indexStr.length);
|
||||
op.insert = before + after;
|
||||
if (deleteParagraph) {
|
||||
// // 检查是否包含要删除的索引并找到段落的起止位置
|
||||
// let startPos = op.insert.lastIndexOf("\n", indexPos) + 1;
|
||||
// let endPos = op.insert.indexOf("\n", indexPos);
|
||||
// console.log("startPos", startPos);
|
||||
// console.log("endPos", endPos);
|
||||
// // 如果没有找到首部的换行符,说明是文档的第一个段落或索引紧跟在段落开头
|
||||
// if (startPos === 0 && indexPos > 0) {
|
||||
// // 直接从文档开始删除到段落末尾
|
||||
// startPos = 0; // 从文档开头开始
|
||||
// }
|
||||
// // 如果没有找到末尾的换行符,说明索引在文档或段落的末尾
|
||||
// endPos = endPos === -1 ? op.insert.length : endPos;
|
||||
// // 删除整个段落
|
||||
// console.log("startPos2", startPos);
|
||||
// console.log("endPos2", endPos);
|
||||
// const before = op.insert.slice(0, startPos);
|
||||
// const after = op.insert.slice(endPos);
|
||||
// op.insert = before + after;
|
||||
// // 如果处理后的insert为空字符串,我们返回一个空数组来避免创建空操作
|
||||
// console.log("删除整个段落");
|
||||
// return op.insert ? [op] : [];
|
||||
// 找到索引所在的op,开始向前和向后搜索段落的边界
|
||||
let startPos = findPrevParagraphEnd(delta.ops, i);
|
||||
let endPos = findNextParagraphStart(delta.ops, i);
|
||||
|
||||
// 删除段落:需要根据startPos和endPos来决定删除或修改哪些op
|
||||
// 这可能包括从一个op中删除文本,或者完全删除一个或多个op
|
||||
deleteParagraphOps(delta.ops, startPos, endPos);
|
||||
} else {
|
||||
// 删除单个索引的逻辑
|
||||
const before = op.insert.slice(0, indexPos);
|
||||
const after = op.insert.slice(indexPos + indexStr.length);
|
||||
op.insert = before + after;
|
||||
console.log("删除索引");
|
||||
}
|
||||
}
|
||||
}
|
||||
return op;
|
||||
// 对于不需要修改的op,直接返回
|
||||
return [op];
|
||||
});
|
||||
|
||||
return { ops: updatedOps };
|
||||
}
|
||||
|
||||
function findPrevParagraphEnd(ops, currentIndex) {
|
||||
// 从当前索引向前搜索换行符
|
||||
for (let i = currentIndex - 1; i >= 0; i--) {
|
||||
const op = ops[i];
|
||||
if (typeof op.insert === "string") {
|
||||
const newlineIndex = op.insert.lastIndexOf("\n");
|
||||
// 如果在当前op中找到了换行符,返回这个位置和op的索引
|
||||
if (newlineIndex !== -1) {
|
||||
return { opIndex: i, charIndex: newlineIndex + 1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
// 如果没有找到换行符,返回文档开头的位置
|
||||
return { opIndex: -1, charIndex: 0 };
|
||||
}
|
||||
function findNextParagraphStart(ops, currentIndex) {
|
||||
// 从当前索引向后搜索换行符
|
||||
for (let i = currentIndex; i < ops.length; i++) {
|
||||
const op = ops[i];
|
||||
if (typeof op.insert === "string") {
|
||||
const newlineIndex = op.insert.indexOf("\n");
|
||||
// 如果在当前op中找到了换行符,返回这个位置和op的索引
|
||||
if (newlineIndex !== -1) {
|
||||
return { opIndex: i, charIndex: newlineIndex + 1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
// 如果没有找到换行符,返回文档末尾的位置
|
||||
return {
|
||||
opIndex: ops.length - 1,
|
||||
charIndex: ops[ops.length - 1].insert.length,
|
||||
};
|
||||
}
|
||||
function deleteParagraphOps(ops, startPos, endPos) {
|
||||
// 如果段落在同一个op内
|
||||
if (startPos.opIndex === endPos.opIndex && startPos.opIndex !== -1) {
|
||||
const op = ops[startPos.opIndex];
|
||||
const before = op.insert.substring(0, startPos.charIndex);
|
||||
const after = op.insert.substring(endPos.charIndex);
|
||||
op.insert = before + after;
|
||||
if (op.insert === "") {
|
||||
// 如果op为空,则移除此op
|
||||
ops.splice(startPos.opIndex, 1);
|
||||
}
|
||||
} else {
|
||||
// 处理跨越多个op的段落删除
|
||||
// 1. 修改或删除起始op
|
||||
if (startPos.opIndex !== -1) {
|
||||
const startOp = ops[startPos.opIndex];
|
||||
startOp.insert = startOp.insert.substring(0, startPos.charIndex);
|
||||
if (startOp.insert === "") {
|
||||
// 如果起始op为空,删除之
|
||||
ops.splice(startPos.opIndex, 1);
|
||||
// 调整结束位置索引,因为数组长度减少了
|
||||
endPos.opIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 删除起始位置和结束位置之间的所有op
|
||||
const deleteCount = endPos.opIndex - startPos.opIndex - 1;
|
||||
if (deleteCount > 0) {
|
||||
ops.splice(startPos.opIndex + 1, deleteCount);
|
||||
}
|
||||
|
||||
// 3. 修改或删除结束op
|
||||
if (endPos.opIndex !== -1 && endPos.opIndex < ops.length) {
|
||||
const endOp = ops[endPos.opIndex];
|
||||
endOp.insert = endOp.insert.substring(endPos.charIndex);
|
||||
if (endOp.insert === "" && deleteCount >= 0) {
|
||||
// 如果结束op为空,删除之
|
||||
ops.splice(endPos.opIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// function deleteUpdateBracketNumbers(delta, indexToRemove:number, quill) {
|
||||
// let currentNumber = 1;
|
||||
|
||||
|
@ -100,11 +215,17 @@ function updateBracketNumbersInDeltaKeepSelection(quill) {
|
|||
|
||||
export function delteIndexUpdateBracketNumbersInDeltaKeepSelection(
|
||||
quill,
|
||||
index: number
|
||||
index: number,
|
||||
rmPg: boolean
|
||||
) {
|
||||
const selection = quill.getSelection();
|
||||
const delta = quill.getContents();
|
||||
let updatedDelta = deleteUpdateBracketNumbers(delta, index, quill);
|
||||
let updatedDelta = deleteReferenceNumberOrParagraph(
|
||||
delta,
|
||||
index,
|
||||
quill,
|
||||
rmPg
|
||||
);
|
||||
updatedDelta = updateBracketNumbersInDelta(updatedDelta);
|
||||
quill.setContents(updatedDelta);
|
||||
if (selection) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user