Skip to content

Commit 92b793f

Browse files
committed
feat: 编辑器增加预览功能
1 parent 020ab0b commit 92b793f

5 files changed

Lines changed: 89 additions & 2 deletions

File tree

modules/NewTicket.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types'
44
import {FormGroup, ControlLabel, FormControl, Button, Tooltip, OverlayTrigger} from 'react-bootstrap'
55
import AV from 'leancloud-storage/live-query'
66

7+
import TextareaWithPreview from './components/TextareaWithPreview'
78
const {uploadFiles, getTinyCategoryInfo} = require('./common')
89

910
export default class NewTicket extends React.Component {
@@ -140,7 +141,7 @@ export default class NewTicket extends React.Component {
140141
<b className="has-required" title="支持 Markdown 语法">M↓</b>
141142
</OverlayTrigger>
142143
</ControlLabel>
143-
<FormControl componentClass="textarea" placeholder="在这里输入,粘贴图片即可上传。" rows="8"
144+
<TextareaWithPreview componentClass="textarea" placeholder="在这里输入,粘贴图片即可上传。" rows="8"
144145
value={this.state.content}
145146
onChange={this.handleContentChange.bind(this)}
146147
inputRef={(ref) => this.contentTextarea = ref }

modules/Ticket.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import AV from 'leancloud-storage/live-query'
1010
import {UserLabel, TicketStatusLabel, uploadFiles, getTinyCategoryInfo} from './common'
1111
import common from './common'
1212
import UpdateTicket from './UpdateTicket'
13+
import TextareaWithPreview from './components/TextareaWithPreview'
1314
import css from './Ticket.css'
1415
import csCss from './CustomerServiceTickets.css'
1516
import DocumentTitle from 'react-document-title'
@@ -595,7 +596,7 @@ class TicketReply extends Component {
595596
<div>
596597
<form className="form-group">
597598
<FormGroup>
598-
<FormControl componentClass="textarea" placeholder="在这里输入,粘贴图片即可上传。" rows="8"
599+
<TextareaWithPreview componentClass="textarea" placeholder="在这里输入,粘贴图片即可上传。" rows="8"
599600
value={this.state.reply}
600601
onChange={this.handleReplyOnChange.bind(this)}
601602
onKeyDown={this.handleReplyOnKeyDown.bind(this)}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.textareaWrapper {
2+
position: relative;
3+
}
4+
5+
.preview {
6+
position: absolute;
7+
right: 5px;
8+
bottom: 5px;
9+
border-radius: 4px;
10+
height: 40px;
11+
width: 40px;
12+
line-height: 40px;
13+
text-align: center;
14+
background: rgba(0, 0, 0, 0.06);
15+
cursor: pointer;
16+
}
17+
18+
.preview:hover {
19+
background: rgba(0, 0, 0, 0.15);
20+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import React, {Component} from 'react'
2+
import PropTypes from 'prop-types'
3+
import {FormControl} from 'react-bootstrap'
4+
import Stackedit from 'stackedit-js'
5+
import css from './index.css'
6+
7+
export default class TextareaWithPreview extends Component {
8+
constructor(props) {
9+
super(props)
10+
11+
this.state = {
12+
value: props.value
13+
}
14+
15+
this.inputRef = (ref, ...params) => {
16+
this.ref = ref
17+
if (this.props.inputRef) {
18+
this.props.inputRef(ref, ...params)
19+
}
20+
}
21+
}
22+
23+
componentWillReceiveProps(nextProps) {
24+
if (nextProps.value !== this.state.value) {
25+
this.setState({ value: nextProps.value })
26+
}
27+
}
28+
29+
enterPreviewMode() {
30+
const editor = this._editor = this._editor || new Stackedit()
31+
editor.openFile({
32+
content: {
33+
text: this.state.value,
34+
}
35+
})
36+
37+
// Listen to StackEdit events and apply the changes to the textarea.
38+
editor.off('fileChange')
39+
editor.on('fileChange', (file) => {
40+
this.setState({
41+
value: file.content.text,
42+
})
43+
})
44+
45+
46+
editor.off('close')
47+
editor.on('close', () => this.ref.focus())
48+
}
49+
50+
render() {
51+
return (
52+
<div className={css.textareaWrapper}>
53+
<FormControl {...this.props} value={this.state.value} componentClass="textarea" inputRef={this.inputRef.bind(this)}/>
54+
<div onClick={this.enterPreviewMode.bind(this)} title="预览" className={css.preview}><span className="glyphicon glyphicon-fullscreen" aria-hidden="true"></span></div>
55+
</div>
56+
)
57+
}
58+
}
59+
60+
TextareaWithPreview.propTypes = {
61+
value: PropTypes.any,
62+
inputRef: PropTypes.func
63+
}
64+

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"request": "^2.79.0",
5858
"request-promise": "^4.1.1",
5959
"serve-favicon": "^2.4.3",
60+
"stackedit-js": "^1.0.5",
6061
"style-loader": "^0.18.1",
6162
"uuid": "^3.1.0",
6263
"webpack": "^1.12.13",

0 commit comments

Comments
 (0)