diff --git a/.babelrc b/.babelrc index a85de2f..505bd42 100644 --- a/.babelrc +++ b/.babelrc @@ -3,6 +3,7 @@ ["es2015", { "modules": false }], "stage-2", "react" ], "plugins": [ - "react-hot-loader/babel" + "react-hot-loader/babel", + "transform-runtime" ] } \ No newline at end of file diff --git a/package.json b/package.json index dea67a8..d0d4b6c 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "babel-core": "^6.25.0", "babel-loader": "^7.1.0", "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-preset-stage-0": "^6.24.1", diff --git a/src/scripts/components/Common/PlayHtmlEditor.jsx b/src/scripts/components/Common/PlayHtmlEditor.jsx index e9398bb..ff186e4 100644 --- a/src/scripts/components/Common/PlayHtmlEditor.jsx +++ b/src/scripts/components/Common/PlayHtmlEditor.jsx @@ -1,15 +1,15 @@ import React, { Component } from 'react' -import { Editor, EditorState,RichUtils,ContentState,Entity,convertToRaw,convertFromHTML } from 'draft-js' -// import {convertFromHTML} from 'draft-convert' +import { Editor, EditorState,RichUtils,ContentState,Entity,convertToRaw } from 'draft-js' import Request from 'superagent' import Dropzone from 'react-dropzone' import decorator from '../PlayDraft/DecoratorServer' import DraftToolbar from '../PlayDraft/DraftToolbar' -import { makeId, DraftImage,mediaBlockRenderer} from '../PlayDraft/draftServer' -import { createLinkEntity,createImageEntity,createVideoEntityWithHtml,createVideoEntityWithSrc,removeEntity } from '../PlayDraft/entityServer' +import { makeId,mediaBlockRenderer, draftFromHtml,draftToHtml} from '../PlayDraft/draftServer' +import { createImageEntity } from '../PlayDraft/entityServer' import CDN from '../../widgets/cdn' +import { uploadFiles } from '../../widgets/upload' export default class extends Component { constructor(props){ @@ -21,11 +21,36 @@ export default class extends Component { this.focus = () => this.refs.editor.focus() this.onChange = editorState => this.setState({editorState}) this.handleKeyCommand = (command) => this._handleKeyCommand(command) - this.blockRendererFn = this._blockRendererFn.bind(this) this.dropImage = this._dropImage.bind(this) this.uploadImage = this._uploadImage.bind(this) this.addImage = this._addImage.bind(this) + this.test = () => { + console.log(this.state.editorState.getCurrentContent().getEntityMap()) + // console.log(draftToHtml(this.state.editorState.getCurrentContent())) + // uploadFiles().then(a => console.log(a)) + } + this.test2 = (e) => { + console.log(e.dataTransfer.files) + const preview = window.URL.createObjectURL(e.target.files[0]) + const img = new Image() + img.onload = () => { + console.log(img.width) + console.log(img.height) + } + img.src = preview + // var file = e.target.files[0]; + // var reader = new FileReader(); + // reader.readAsDataURL(file); + // reader.onload = (e) =>{ + // // var pic = document.getElementById("preview"); + // img.src = e.target.result + // img.onload = () => { + // console.log(img.width) + // console.log(img.height) + // } + // } + } } _handleKeyCommand(command) { const {editorState} = this.state; @@ -36,44 +61,22 @@ export default class extends Component { } return false } - _blockRendererFn(block) { - const { editorState } = this.state - const contentState = editorState.getCurrentContent() - if (block.getType() === 'atomic') { - return { - component: (props) => { - const entityKey = props.block.getEntityAt(0) - const entity = contentState.getEntity(entityKey) - const { html, src } = entity.getData() - const type = entity.getType() - - let media = null - if (type === 'image') { - media = ( - this.onChange(removeEntity(editorState,props.block.getKey()))} - /> - ) - } - return media - }, - editable: false, - }; - } - return null; - } _dropImage(files) { - Request.get(`/api/uptoken`) - .end((err, res) => { - let uploadToken = res.body.uptoken - files.forEach((file) => { - let d = new Date() - let id = makeId() - let uploadKey = 'article/photo/' + Math.round(d.getTime() / 1000) + '_' + id + '.' + file.name.split('.').pop() - this.uploadImage(file, uploadKey, uploadToken) + uploadFiles(files,'article/photo').then(keys => { + keys.map(key => { + this.addImage(key) }) }) + // Request.get(`/api/uptoken`) + // .end((err, res) => { + // let uploadToken = res.body.uptoken + // files.forEach((file) => { + // let d = new Date() + // let id = makeId() + // let uploadKey = 'article/photo/' + Math.round(d.getTime() / 1000) + '_' + id + '.' + file.name.split('.').pop() + // this.uploadImage(file, uploadKey, uploadToken) + // }) + // }) } _uploadImage(file, uploadKey, uploadToken) { if (!file || file.size === 0) { @@ -100,51 +103,24 @@ export default class extends Component { } componentDidMount() { const html = ` + +

- - Bold text, Italic text + Bold text, Italic text

-
- baidukaasa
+
+ +
+
+ baidukaasa +
+
` - const blocksFromHTML = convertFromHTML(html)//.contentBlocks - // const entityMaps = convertFromHTML(html).entityMap - // blocksFromHTML.map((block,i) => { - // console.log(block.toJS()) - // }) - // let i = 1 - // while(entityMaps.get(i.toString())){ - // console.log(entityMaps.get(i.toString()).toJS()) - // i++ - // } - // const blocksFromHTML = convertFromHTML(html); - // const state = ContentState.createFromBlockArray( - // blocksFromHTML.contentBlocks, - // blocksFromHTML.entityMap - // ); - // this.setState({ - // editorState:EditorState.createWithContent(state,decorator) - // }) - // const blocksFromHTML = convertFromHTML(html); - - const defaultConvertedContentState = ContentState.createFromBlockArray( - blocksFromHTML.contentBlocks, - blocksFromHTML.entityMap, - ); - const raw = convertToRaw(defaultConvertedContentState) - console.log(raw) - - // const customConvertedContentState = CustomContentStateConverter(defaultConvertedContentState); - - // const initialEditorState = EditorState.createWithContent( - // customConvertedContentState, - // decorator, - // ); - // this.setState({ - // editorState:initialEditorState - // }) + this.setState({ + editorState:EditorState.createWithContent(draftFromHtml(html),decorator) + }) } render() { const {editorState} = this.state; @@ -162,6 +138,10 @@ export default class extends Component { + +
+ +
+ ) } } -// const CustomConvertFromHTML = (html) => { -// // Correctly seperates paragraphs into their own blocks -// const blockRenderMap = DefaultDraftBlockRenderMap.set('p', { element: 'p' }); -// const blocksFromHTML = convertFromHTML(html, getSafeBodyFromHTML, blockRenderMap); -// blocksFromHTML.contentBlocks = blocksFromHTML.contentBlocks.map(block => (block.get('type') === 'p' ? block.set('type', 'unstyled') : block)); - -// return blocksFromHTML; -// }; - -// const CustomContentStateConverter = (contentState) => { -// // Correctly assign properties to images and links -// const newBlockMap = contentState.getBlockMap().map((block) => { -// const entityKey = block.getEntityAt(0); -// if (entityKey !== null) { -// const entityBlock = contentState.getEntity(entityKey); -// const entityType = entityBlock.getType(); -// switch (entityType) { -// case 'IMAGE': { -// const newBlock = block.merge({ -// type: 'atomic', -// text: 'img', -// }); -// // const newContentState = contentState.mergeEntityData(entityKey, { mutability: 'IMMUTABLE' }); -// return newBlock; -// } -// default: -// return block; -// } -// } -// return block; -// }); -// const newContentState = contentState.set('blockMap', newBlockMap); - -// return newContentState; -// }; \ No newline at end of file diff --git a/src/scripts/components/EditPage/EditPage.jsx b/src/scripts/components/EditPage/EditPage.jsx index 201cda5..1d3f3b6 100644 --- a/src/scripts/components/EditPage/EditPage.jsx +++ b/src/scripts/components/EditPage/EditPage.jsx @@ -1,6 +1,5 @@ import React, { Component } from 'react' import ReactDOM from 'react-dom' -import { stateToHTML } from 'draft-js-export-html' import Request from 'superagent' import Dropzone from 'react-dropzone' import TagsInput from 'react-tagsinput' @@ -19,12 +18,13 @@ import { } from 'draft-js' import decorator from '../PlayDraft/DecoratorServer' -import { getBlockStyle,makeId, DraftImage,mediaBlockRenderer } from '../PlayDraft/draftServer' +import { getBlockStyle,makeId, DraftImage,mediaBlockRenderer,draftToHtml } from '../PlayDraft/draftServer' import { createLinkEntity,createImageEntity,createVideoEntityWithHtml,createVideoEntityWithSrc,removeEntity } from '../PlayDraft/entityServer' import DraftToolbar from '../PlayDraft/DraftToolbar' import CDN from '../../widgets/cdn' import parse from '../../widgets/parse' +import { uploadFiles,uploadImageWithWH } from '../../widgets/upload' export default class EditPage extends Component { constructor(props) { super(props) @@ -48,7 +48,7 @@ export default class EditPage extends Component { uploadKey:'', } //封面 - this.onDropCover = this._onDropCover.bind(this) + this.onDropCover = (files) => uploadImageWithWH(files[0],'article/cover/').then(cover => this.setState({cover},this.saveStorage)) //自动保存至storage this.saveStorage = this._saveStorage.bind(this) //editor的回调方法 @@ -61,7 +61,7 @@ export default class EditPage extends Component { this.addImage = this._addImage.bind(this) this.addVideo = () => this._addVideo() this.onChangeVideoCode = (e) => this.setState({videoCode: e.target.value}) - this.uploadImg = this._uploadImg.bind(this) + this.onDropImage = (files) => uploadFiles(files,'article/photo/').then(keys => keys.map(key => this.addImage(key))) this.onDropVideo = this._onDropVideo.bind(this) this.uploadQiniu = this._uploadQiniu.bind(this) //dialog controller @@ -114,34 +114,6 @@ export default class EditPage extends Component { return false } - _onDropCover(files) { - Request.get('/api/uptoken') - .end((err, res) => { - let uploadToken = res.body.uptoken - const file = files[0] - const img = new Image() - img.onload = () => { - if(img.width <320){ - return alert('图片太小') - } - const uploadKey = `article/cover/${Math.round(Date.now() / 1000)}_w_${img.width}_h_${img.height}_${makeId()}.${file.name.split('.').pop()}` - Request - .post(this.state.uploadUrl) - .field('key', uploadKey) - .field('token', uploadToken) - .field('x:filename', file.name) - .field('x:size', file.size) - .attach('file', file, file.name) - .set('Accept', 'application/json') - .end((err, res) =>{ - this.setState({ - cover: uploadKey - },() => this.saveStorage()) - }) - }; - img.src = file.preview - }) - } _saveStorage() { const { title, cover, tags, category, gallery,authorId,editorState @@ -165,27 +137,8 @@ export default class EditPage extends Component { title, cover, tags, category, gallery,authorId,editorState } = this.state const contentState = editorState.getCurrentContent() - const options = { - blockRenderers: { - atomic: (block) => { - const entity = contentState.getEntity(block.getEntityAt(0)) - const data = entity.getData() - if (data.type === 'image') { - return `
` - } else if (data.type === 'video') { - if(data.src) { - return `
` - }else { - return `
${data.html}
` - } - } else { - return null - } - }, - } - } const raw = convertToRaw(contentState) - const html = stateToHTML(contentState,options).replace(/


<\/p>\s?

/g,'
') + const html = draftToHtml(contentState) const data = { title, authorId, @@ -241,44 +194,6 @@ export default class EditPage extends Component { } return false } - _uploadImg(files) { - let _this = this - Request.get(`/api/uptoken`) - .withCredentials() - .end(function(err, res) { - let uploadToken = res.body.uptoken - files.forEach((file) => { - let d = new Date() - let id = makeId() - let uploadKey = 'article/photo/' + Math.round(d.getTime() / 1000) + '_' + id + '.' + file.name.split('.').pop() - file.request = _this.uploadToQiniu(file, uploadKey, uploadToken) - }) - }) - } - uploadToQiniu(file, uploadKey, uploadToken) { - if (!file || file.size === 0) { - return null; - } - let _this = this; - const req = Request - .post(this.state.uploadUrl) - .field('key', uploadKey) - .field('token', uploadToken) - .field('x:filename', file.name) - .field('x:size', file.size) - .attach('file', file, file.name) - .set('Accept', 'application/json'); - - req.end(function(err, res) { - let value = _this.state.gallery.slice(); - value.push(uploadKey); - _this.setState({ - gallery: value - }); - _this.addImage(uploadKey) - }); - return req; - } _uploadQiniu(file, uploadKey, uploadToken) { if (!file || file.size === 0) { return null; @@ -390,7 +305,7 @@ export default class EditPage extends Component { return (
- + { cover ?
@@ -410,7 +325,7 @@ export default class EditPage extends Component { this.setState({title:e.target.value},() => this.saveStorage())} placeholder="输入文章标题"/>
- + diff --git a/src/scripts/components/EditToy/index.jsx b/src/scripts/components/EditToy/index.jsx index 9f92717..bdda90a 100644 --- a/src/scripts/components/EditToy/index.jsx +++ b/src/scripts/components/EditToy/index.jsx @@ -3,6 +3,7 @@ import Request from 'superagent' import Dropzone from 'react-dropzone' import { Row, Col, Modal,InputGroup,FormControl } from 'react-bootstrap' import CDN from '../../widgets/cdn' +import { uploadImageWithWH,uploadFiles } from '../../widgets/upload' import PlaySwitch from '../Common/playSwitch' import Select from 'react-select' // import PlayHtmlEditor from '../Common/PlayHtmlEditor' @@ -71,8 +72,8 @@ export default class EditToy extends Component { this.addOtherInfo = this._addOtherInfo.bind(this) this.changeNewKey = (e) => this.setState({newKey:e.target.value}) this.changeNewValue = (e) => this.setState({newValue:e.target.value}) - this.onDropOfficialImage = this._onDropOfficialImage.bind(this) - this.onDropCover = this._onDropCover.bind(this) + this.onDropOfficialImage = (files) => uploadFiles(files,`toy/img/${this.props.match.params.id}_`).then(keys => this.setState(prevState => ({images:prevState.images.concat(...keys)}))) + this.onDropCover = (files) => uploadImageWithWH(files[0],'toy/cover/').then(cover => this.setState({cover})) this.submit = this._submit.bind(this) this.removeImg = this._removeImg.bind(this) @@ -114,49 +115,6 @@ export default class EditToy extends Component { this.state.otherInfo.push({ key:newKey, value:newValue }) this.setState({ newKey:'', newValue:'' }) } - _onDropOfficialImage(images) { - images.forEach((image,index) => { - let formData = new FormData() - formData.append('file', image) - $.ajax({ - url: `/api/upload?key=toy/img/${this.props.match.params.id}_${(Date.now().toString()+index)}_(size).${image.name.split('.').pop()}`, - type: 'POST', - data: formData, - processData: false, - contentType: false, - success: (data) => { - this.state.images.push(data) - this.setState({ - images: this.state.images - }) - } - }) - }) - } - _onDropCover(images) { - Request.get('/api/uptoken') - .withCredentials() - .end((err, res) => { - let uploadToken = res.body.uptoken - const file = images[0] - const img = new Image() - img.onload = () => { - const uploadKey = 'toy/cover/'+this.props.match.params.id+Date.now()+'_w_'+img.width+'_h_'+img.height+'.'+file.name.split('.').pop(); - Request - .post('http://upload.qiniu.com/') - .field('key', uploadKey) - .field('token', uploadToken) - .field('x:filename', file.name) - .field('x:size', file.size) - .attach('file', file, file.name) - .set('Accept', 'application/json') - .end((err, res) => { - this.setState({ cover: uploadKey }) - }) - } - img.src = file.preview - }) - } _removeImg(index) { if (confirm('删除这个图片?')) { const images = this.state.images @@ -172,7 +130,7 @@ export default class EditToy extends Component { if(name.trim() === ''){ return alert('名字不能为空') } - if(!release.match(/\d{4}\/\d{1,2}/)){ + if(!release.match(/\d{4}\/\d{1,2}/) && release !== ''){ return alert('发售日期格式不对') } Object.keys(data).forEach(key => data[key]=== '' ? delete data[key] : '') @@ -343,11 +301,11 @@ export default class EditToy extends Component {
-
+
详细描述 - {/* */} + {/* */}