Update to use dev branch
This commit is contained in:
@ -6,13 +6,13 @@ import keydown from 'react-keydown';
|
|||||||
import classnames from 'classnames/bind';
|
import classnames from 'classnames/bind';
|
||||||
import type { Document, State, Editor as EditorType } from './types';
|
import type { Document, State, Editor as EditorType } from './types';
|
||||||
import getDataTransferFiles from 'utils/getDataTransferFiles';
|
import getDataTransferFiles from 'utils/getDataTransferFiles';
|
||||||
import uploadFile from 'utils/uploadFile';
|
|
||||||
import Flex from 'components/Flex';
|
import Flex from 'components/Flex';
|
||||||
import ClickablePadding from './components/ClickablePadding';
|
import ClickablePadding from './components/ClickablePadding';
|
||||||
import Toolbar from './components/Toolbar';
|
import Toolbar from './components/Toolbar';
|
||||||
import Markdown from './serializer';
|
import Markdown from './serializer';
|
||||||
import createSchema from './schema';
|
import createSchema from './schema';
|
||||||
import createPlugins from './plugins';
|
import createPlugins from './plugins';
|
||||||
|
import insertImage from './insertImage';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import styles from './Editor.scss';
|
import styles from './Editor.scss';
|
||||||
|
|
||||||
@ -95,23 +95,22 @@ type KeyData = {
|
|||||||
|
|
||||||
const files = getDataTransferFiles(ev);
|
const files = getDataTransferFiles(ev);
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
await this.insertFile(file);
|
await this.insertImageFile(file);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
insertFile = async (file: Object) => {
|
insertImageFile = async (file: window.File) => {
|
||||||
this.props.onImageUploadStart();
|
|
||||||
const asset = await uploadFile(file);
|
|
||||||
const state = this.editor.getState();
|
const state = this.editor.getState();
|
||||||
const transform = state.transform();
|
let transform = state.transform();
|
||||||
transform.collapseToEndOf(state.document);
|
|
||||||
transform.insertBlock({
|
transform = await insertImage(
|
||||||
type: 'image',
|
transform,
|
||||||
isVoid: true,
|
file,
|
||||||
data: { src: asset.url, alt: file.name },
|
this.editor,
|
||||||
});
|
this.props.onImageUploadStart,
|
||||||
this.props.onImageUploadStop();
|
this.props.onImageUploadStop
|
||||||
this.setState({ state: transform.apply() });
|
);
|
||||||
|
this.editor.onChange(transform.apply());
|
||||||
};
|
};
|
||||||
|
|
||||||
cancelEvent = (ev: SyntheticEvent) => {
|
cancelEvent = (ev: SyntheticEvent) => {
|
||||||
|
56
frontend/components/Editor/insertImage.js
Normal file
56
frontend/components/Editor/insertImage.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// @flow
|
||||||
|
import uuid from 'uuid';
|
||||||
|
import uploadFile from 'utils/uploadFile';
|
||||||
|
import type { Editor, Transform } from './types';
|
||||||
|
|
||||||
|
export default async function insertImageFile(
|
||||||
|
transform: Transform,
|
||||||
|
file: window.File,
|
||||||
|
editor: Editor,
|
||||||
|
onImageUploadStart: () => void,
|
||||||
|
onImageUploadStop: () => void
|
||||||
|
) {
|
||||||
|
onImageUploadStart();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// load the file as a data URL
|
||||||
|
const id = uuid.v4();
|
||||||
|
const alt = file.name;
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.addEventListener('load', () => {
|
||||||
|
const src = reader.result;
|
||||||
|
|
||||||
|
// insert into document as uploading placeholder
|
||||||
|
const state = transform
|
||||||
|
.insertBlock({
|
||||||
|
type: 'image',
|
||||||
|
isVoid: true,
|
||||||
|
data: { src, alt, id, loading: true },
|
||||||
|
})
|
||||||
|
.apply();
|
||||||
|
editor.onChange(state);
|
||||||
|
});
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
|
||||||
|
// now we have a placeholder, start the upload
|
||||||
|
const asset = await uploadFile(file);
|
||||||
|
const src = asset.url;
|
||||||
|
|
||||||
|
// we dont use the original transform provided to the callback here
|
||||||
|
// as the state may have changed significantly in the time it took to
|
||||||
|
// upload the file.
|
||||||
|
const state = editor.getState();
|
||||||
|
const finalTransform = state.transform();
|
||||||
|
const placeholder = state.document.findDescendant(
|
||||||
|
node => node.data && node.data.get('id') === id
|
||||||
|
);
|
||||||
|
|
||||||
|
return finalTransform.setNodeByKey(placeholder.key, {
|
||||||
|
data: { src, alt, loading: false },
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw err;
|
||||||
|
} finally {
|
||||||
|
onImageUploadStop();
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
import DropOrPasteImages from 'slate-drop-or-paste-images';
|
||||||
import PasteLinkify from 'slate-paste-linkify';
|
import PasteLinkify from 'slate-paste-linkify';
|
||||||
import EditList from 'slate-edit-list';
|
import EditList from 'slate-edit-list';
|
||||||
import CollapseOnEscape from 'slate-collapse-on-escape';
|
import CollapseOnEscape from 'slate-collapse-on-escape';
|
||||||
@ -7,7 +8,7 @@ import EditCode from 'slate-edit-code';
|
|||||||
import Prism from 'slate-prism';
|
import Prism from 'slate-prism';
|
||||||
import KeyboardShortcuts from './plugins/KeyboardShortcuts';
|
import KeyboardShortcuts from './plugins/KeyboardShortcuts';
|
||||||
import MarkdownShortcuts from './plugins/MarkdownShortcuts';
|
import MarkdownShortcuts from './plugins/MarkdownShortcuts';
|
||||||
import ImageUploads from './plugins/ImageUploads';
|
import insertImage from './insertImage';
|
||||||
|
|
||||||
const onlyInCode = node => node.type === 'code';
|
const onlyInCode = node => node.type === 'code';
|
||||||
|
|
||||||
@ -16,13 +17,24 @@ type Options = {
|
|||||||
onImageUploadStop: Function,
|
onImageUploadStop: Function,
|
||||||
};
|
};
|
||||||
|
|
||||||
const createPlugins = (options: Options) => {
|
const createPlugins = ({ onImageUploadStart, onImageUploadStop }: Options) => {
|
||||||
return [
|
return [
|
||||||
PasteLinkify({
|
PasteLinkify({
|
||||||
type: 'link',
|
type: 'link',
|
||||||
collapseTo: 'end',
|
collapseTo: 'end',
|
||||||
}),
|
}),
|
||||||
ImageUploads(options),
|
DropOrPasteImages({
|
||||||
|
extensions: ['png', 'jpg', 'gif'],
|
||||||
|
applyTransform: (transform, editor, file) => {
|
||||||
|
return insertImage(
|
||||||
|
transform,
|
||||||
|
file,
|
||||||
|
editor,
|
||||||
|
onImageUploadStart,
|
||||||
|
onImageUploadStop
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}),
|
||||||
EditList({
|
EditList({
|
||||||
types: ['ordered-list', 'bulleted-list', 'todo-list'],
|
types: ['ordered-list', 'bulleted-list', 'todo-list'],
|
||||||
typeItem: 'list-item',
|
typeItem: 'list-item',
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
// @flow
|
|
||||||
import uuid from 'uuid';
|
|
||||||
import DropOrPasteImages from 'slate-drop-or-paste-images';
|
|
||||||
import uploadFile from 'utils/uploadFile';
|
|
||||||
|
|
||||||
type Options = {
|
|
||||||
onImageUploadStart: Function,
|
|
||||||
onImageUploadStop: Function,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function ImageUploads({
|
|
||||||
onImageUploadStart,
|
|
||||||
onImageUploadStop,
|
|
||||||
}: Options) {
|
|
||||||
return DropOrPasteImages({
|
|
||||||
extensions: ['png', 'jpg', 'gif'],
|
|
||||||
applyTransform: async (transform, editor, file) => {
|
|
||||||
onImageUploadStart();
|
|
||||||
|
|
||||||
// load the file as a data URL
|
|
||||||
const id = uuid.v4();
|
|
||||||
const alt = file.name;
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.addEventListener('load', () => {
|
|
||||||
const src = reader.result;
|
|
||||||
|
|
||||||
// insert into document as uploading placeholder
|
|
||||||
const state = transform
|
|
||||||
.insertBlock({
|
|
||||||
type: 'image',
|
|
||||||
isVoid: true,
|
|
||||||
data: { src, alt, id, loading: true },
|
|
||||||
})
|
|
||||||
.apply();
|
|
||||||
editor.onChange(state);
|
|
||||||
});
|
|
||||||
reader.readAsDataURL(file);
|
|
||||||
|
|
||||||
// now we have a placeholder, start the upload
|
|
||||||
try {
|
|
||||||
const asset = await uploadFile(file);
|
|
||||||
const src = asset.url;
|
|
||||||
|
|
||||||
// we dont use the original transform provided to the callback here
|
|
||||||
// as the state may have changed significantly in the time it took to
|
|
||||||
// upload the file.
|
|
||||||
const state = editor.getState();
|
|
||||||
const transform = state.transform();
|
|
||||||
const placeholder = state.document.findDescendant(
|
|
||||||
node => node.data && node.data.get('id') === id
|
|
||||||
);
|
|
||||||
return transform.setNodeByKey(placeholder.key, {
|
|
||||||
data: { src, alt, loading: false },
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
// TODO: Show a failure alert
|
|
||||||
console.error(err);
|
|
||||||
} finally {
|
|
||||||
onImageUploadStop();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
@ -158,7 +158,7 @@
|
|||||||
"sequelize-encrypted": "0.1.0",
|
"sequelize-encrypted": "0.1.0",
|
||||||
"slate": "^0.19.30",
|
"slate": "^0.19.30",
|
||||||
"slate-collapse-on-escape": "^0.2.1",
|
"slate-collapse-on-escape": "^0.2.1",
|
||||||
"slate-drop-or-paste-images": "tommoor/slate-drop-or-paste-images",
|
"slate-drop-or-paste-images": "tommoor/slate-drop-or-paste-images#dev",
|
||||||
"slate-edit-code": "^0.10.2",
|
"slate-edit-code": "^0.10.2",
|
||||||
"slate-edit-list": "^0.7.0",
|
"slate-edit-list": "^0.7.0",
|
||||||
"slate-markdown-serializer": "tommoor/slate-markdown-serializer",
|
"slate-markdown-serializer": "tommoor/slate-markdown-serializer",
|
||||||
|
@ -4846,6 +4846,10 @@ json-loader@0.5.4:
|
|||||||
version "0.5.4"
|
version "0.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.4.tgz#8baa1365a632f58a3c46d20175fc6002c96e37de"
|
resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.4.tgz#8baa1365a632f58a3c46d20175fc6002c96e37de"
|
||||||
|
|
||||||
|
json-loader@^0.5.7:
|
||||||
|
version "0.5.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"
|
||||||
|
|
||||||
json-schema@0.2.3:
|
json-schema@0.2.3:
|
||||||
version "0.2.3"
|
version "0.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||||
@ -8009,9 +8013,9 @@ slate-collapse-on-escape@^0.2.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
to-pascal-case "^1.0.0"
|
to-pascal-case "^1.0.0"
|
||||||
|
|
||||||
slate-drop-or-paste-images@tommoor/slate-drop-or-paste-images:
|
slate-drop-or-paste-images@tommoor/slate-drop-or-paste-images#dev:
|
||||||
version "0.5.0"
|
version "0.5.0"
|
||||||
resolved "https://codeload.github.com/tommoor/slate-drop-or-paste-images/tar.gz/a3ebc74658941ec2c56d4b90493b8718b8a9fd4f"
|
resolved "https://codeload.github.com/tommoor/slate-drop-or-paste-images/tar.gz/935894631acb528b1eec6a8a1a78857da9d0d1da"
|
||||||
dependencies:
|
dependencies:
|
||||||
data-uri-to-blob "0.0.4"
|
data-uri-to-blob "0.0.4"
|
||||||
es6-promise "^4.0.5"
|
es6-promise "^4.0.5"
|
||||||
@ -8019,6 +8023,7 @@ slate-drop-or-paste-images@tommoor/slate-drop-or-paste-images:
|
|||||||
is-data-uri "^0.1.0"
|
is-data-uri "^0.1.0"
|
||||||
is-image "^1.0.1"
|
is-image "^1.0.1"
|
||||||
is-url "^1.2.2"
|
is-url "^1.2.2"
|
||||||
|
json-loader "^0.5.7"
|
||||||
mime-types "^2.1.11"
|
mime-types "^2.1.11"
|
||||||
|
|
||||||
slate-edit-code@^0.10.2:
|
slate-edit-code@^0.10.2:
|
||||||
|
Reference in New Issue
Block a user