Added: Placeholder when uploading images

This commit is contained in:
Tom Moor
2017-08-26 22:37:20 -07:00
parent 3c51cc3197
commit 667d1caf11
5 changed files with 80 additions and 40 deletions

View File

@ -1,13 +1,16 @@
// @flow // @flow
import React from 'react'; import React from 'react';
import type { Props } from '../types'; import type { Props } from '../types';
import styled from 'styled-components';
const LoadingImage = styled.img`
opacity: .5;
`;
export default function Image({ attributes, node }: Props) { export default function Image({ attributes, node }: Props) {
return ( const loading = node.data.get('loading');
<img const Component = loading ? LoadingImage : 'img';
{...attributes} const src = node.data.get('inlineSrc') || node.data.get('src');
src={node.data.get('src')}
alt={node.data.get('alt')} return <Component {...attributes} src={src} alt={node.data.get('alt')} />;
/>
);
} }

View File

@ -1,14 +1,13 @@
// @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';
import TrailingBlock from 'slate-trailing-block'; import TrailingBlock from 'slate-trailing-block';
import EditCode from 'slate-edit-code'; import EditCode from 'slate-edit-code';
import Prism from 'slate-prism'; import Prism from 'slate-prism';
import uploadFile from 'utils/uploadFile';
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';
const onlyInCode = node => node.type === 'code'; const onlyInCode = node => node.type === 'code';
@ -17,34 +16,13 @@ type Options = {
onImageUploadStop: Function, onImageUploadStop: Function,
}; };
const createPlugins = ({ onImageUploadStart, onImageUploadStop }: Options) => { const createPlugins = (options: Options) => {
return [ return [
PasteLinkify({ PasteLinkify({
type: 'link', type: 'link',
collapseTo: 'end', collapseTo: 'end',
}), }),
DropOrPasteImages({ ImageUploads(options),
extensions: ['png', 'jpg', 'gif'],
applyTransform: async (transform, file) => {
onImageUploadStart();
try {
const asset = await uploadFile(file);
const alt = file.name;
const src = asset.url;
return transform.insertBlock({
type: 'image',
isVoid: true,
data: { src, alt },
});
} catch (err) {
// TODO: Show a failure alert
console.error(err);
} finally {
onImageUploadStop();
}
},
}),
EditList({ EditList({
types: ['ordered-list', 'bulleted-list', 'todo-list'], types: ['ordered-list', 'bulleted-list', 'todo-list'],
typeItem: 'list-item', typeItem: 'list-item',

View File

@ -0,0 +1,63 @@
// @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();
}
},
});
}

View File

@ -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": "^0.5.0", "slate-drop-or-paste-images": "tommoor/slate-drop-or-paste-images",
"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",

View File

@ -2501,11 +2501,7 @@ emoji-name-map@1.1.2:
iterate-object "^1.3.1" iterate-object "^1.3.1"
map-o "^2.0.1" map-o "^2.0.1"
emoji-regex@^6.1.0: emoji-regex@^6.1.0, emoji-regex@^6.5.1:
version "6.4.2"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.4.2.tgz#a30b6fee353d406d96cfb9fa765bdc82897eff6e"
emoji-regex@^6.5.1:
version "6.5.1" version "6.5.1"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2"
@ -8013,9 +8009,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@^0.5.0: slate-drop-or-paste-images@tommoor/slate-drop-or-paste-images:
version "0.5.0" version "0.5.0"
resolved "https://registry.yarnpkg.com/slate-drop-or-paste-images/-/slate-drop-or-paste-images-0.5.0.tgz#c90367f9612f75abae0d1d6b8b2008108da02598" resolved "https://codeload.github.com/tommoor/slate-drop-or-paste-images/tar.gz/a3ebc74658941ec2c56d4b90493b8718b8a9fd4f"
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"