mirror of https://github.com/fantasticit/think.git
use loading id to find correct position
This commit is contained in:
parent
55241f14cb
commit
ba189b26e2
|
@ -1,7 +1,22 @@
|
||||||
import { Node } from '@tiptap/core';
|
import { Editor, Node } from '@tiptap/core';
|
||||||
import { ReactNodeViewRenderer } from '@tiptap/react';
|
import { ReactNodeViewRenderer } from '@tiptap/react';
|
||||||
|
import { Node as PMNode } from 'prosemirror-state';
|
||||||
import { LoadingWrapper } from 'tiptap/core/wrappers/loading';
|
import { LoadingWrapper } from 'tiptap/core/wrappers/loading';
|
||||||
|
|
||||||
|
export function findLoadingById(editor: Editor, id: string): null | { node: PMNode; pos: number } {
|
||||||
|
let target: PMNode | null = null;
|
||||||
|
let pos = -1;
|
||||||
|
|
||||||
|
editor.state.doc.descendants((node, nodePos) => {
|
||||||
|
if (node.type.name === 'loading' && node.attrs.id === id) {
|
||||||
|
target = node;
|
||||||
|
pos = nodePos;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return target ? { node: target, pos } : null;
|
||||||
|
}
|
||||||
|
|
||||||
export const Loading = Node.create({
|
export const Loading = Node.create({
|
||||||
name: 'loading',
|
name: 'loading',
|
||||||
inline: true,
|
inline: true,
|
||||||
|
@ -10,6 +25,9 @@ export const Loading = Node.create({
|
||||||
|
|
||||||
addAttributes() {
|
addAttributes() {
|
||||||
return {
|
return {
|
||||||
|
id: {
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
text: {
|
text: {
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Editor } from '@tiptap/core';
|
||||||
import { uploadFile } from 'services/file';
|
import { uploadFile } from 'services/file';
|
||||||
import { Attachment } from 'tiptap/core/extensions/attachment';
|
import { Attachment } from 'tiptap/core/extensions/attachment';
|
||||||
import { Image } from 'tiptap/core/extensions/image';
|
import { Image } from 'tiptap/core/extensions/image';
|
||||||
import { Loading } from 'tiptap/core/extensions/loading';
|
import { findLoadingById, Loading } from 'tiptap/core/extensions/loading';
|
||||||
|
|
||||||
import { extractFileExtension, extractFilename } from './file';
|
import { extractFileExtension, extractFilename } from './file';
|
||||||
|
|
||||||
|
@ -28,50 +28,85 @@ interface FnProps {
|
||||||
*/
|
*/
|
||||||
const uploadImage = async ({ file, fileInfo, editor }: FnProps & { fileInfo: FileInfo }) => {
|
const uploadImage = async ({ file, fileInfo, editor }: FnProps & { fileInfo: FileInfo }) => {
|
||||||
const { view } = editor;
|
const { view } = editor;
|
||||||
const { state } = view;
|
|
||||||
const { from } = state.selection;
|
const id = `loading-${loadingId++}`;
|
||||||
const loadingNode = view.props.state.schema.nodes[Loading.name].create({
|
const loadingNode = editor.state.schema?.nodes?.[Loading.name]?.create({
|
||||||
|
id,
|
||||||
text: fileInfo.fileName,
|
text: fileInfo.fileName,
|
||||||
});
|
});
|
||||||
view.dispatch(view.state.tr.replaceSelectionWith(loadingNode));
|
|
||||||
|
editor.view.dispatch(editor.view.state.tr.replaceSelectionWith(loadingNode));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = await uploadFile(file);
|
const url = await uploadFile(file);
|
||||||
const node = view.props.state.schema.nodes[Image.name].create({
|
|
||||||
src: url,
|
const maybeLoading = findLoadingById(editor, id);
|
||||||
});
|
|
||||||
const transaction = view.state.tr.replaceRangeWith(from, from + loadingNode.nodeSize, node);
|
if (maybeLoading) {
|
||||||
view.dispatch(transaction);
|
const node = view.props.state.schema.nodes[Image.name].create({
|
||||||
|
src: url,
|
||||||
|
});
|
||||||
|
const transaction = view.state.tr.replaceRangeWith(
|
||||||
|
maybeLoading?.pos,
|
||||||
|
maybeLoading?.pos + maybeLoading?.node.nodeSize,
|
||||||
|
node
|
||||||
|
);
|
||||||
|
view.dispatch(transaction);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
editor.commands.deleteRange({ from: from, to: from + loadingNode.nodeSize });
|
const maybeLoading = findLoadingById(editor, id);
|
||||||
|
if (maybeLoading) {
|
||||||
|
editor.commands.deleteRange({
|
||||||
|
from: maybeLoading?.pos,
|
||||||
|
to: maybeLoading?.pos + maybeLoading?.node.nodeSize,
|
||||||
|
});
|
||||||
|
}
|
||||||
console.log('上传文件失败!');
|
console.log('上传文件失败!');
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let loadingId = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传附件
|
* 上传附件
|
||||||
* @param param0
|
* @param param0
|
||||||
*/
|
*/
|
||||||
const uploadAttachment = async ({ file, fileInfo, editor }: FnProps & { fileInfo: FileInfo }) => {
|
const uploadAttachment = async ({ file, fileInfo, editor }: FnProps & { fileInfo: FileInfo }) => {
|
||||||
const { view } = editor;
|
const { view } = editor;
|
||||||
const { state } = view;
|
|
||||||
const { from } = state.selection;
|
const id = `loading-${loadingId++}`;
|
||||||
const loadingNode = view.props.state.schema.nodes[Loading.name].create({
|
const loadingNode = editor.state.schema?.nodes?.[Loading.name]?.create({
|
||||||
|
id,
|
||||||
text: fileInfo.fileName,
|
text: fileInfo.fileName,
|
||||||
});
|
});
|
||||||
view.dispatch(view.state.tr.replaceSelectionWith(loadingNode));
|
|
||||||
|
editor.view.dispatch(editor.view.state.tr.replaceSelectionWith(loadingNode));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = await uploadFile(file);
|
const url = await uploadFile(file);
|
||||||
const node = view.props.state.schema.nodes[Attachment.name].create({
|
const maybeLoading = findLoadingById(editor, id);
|
||||||
url,
|
|
||||||
...fileInfo,
|
if (maybeLoading) {
|
||||||
});
|
const node = view.props.state.schema.nodes[Attachment.name].create({
|
||||||
const transaction = view.state.tr.replaceRangeWith(from, from + loadingNode.nodeSize, node);
|
url,
|
||||||
view.dispatch(transaction);
|
...fileInfo,
|
||||||
|
});
|
||||||
|
const transaction = view.state.tr.replaceRangeWith(
|
||||||
|
maybeLoading?.pos,
|
||||||
|
maybeLoading?.pos + maybeLoading?.node.nodeSize,
|
||||||
|
node
|
||||||
|
);
|
||||||
|
view.dispatch(transaction);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
editor.commands.deleteRange({ from: from, to: from + loadingNode.nodeSize });
|
const maybeLoading = findLoadingById(editor, id);
|
||||||
|
if (maybeLoading) {
|
||||||
|
editor.commands.deleteRange({
|
||||||
|
from: maybeLoading?.pos,
|
||||||
|
to: maybeLoading?.pos + maybeLoading?.node.nodeSize,
|
||||||
|
});
|
||||||
|
}
|
||||||
console.log('上传文件失败!');
|
console.log('上传文件失败!');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue