Skip to content

Commit 2537b6b

Browse files
committed
No edit mode
1 parent 013a1b4 commit 2537b6b

9 files changed

Lines changed: 238 additions & 362 deletions

File tree

browser/components/ModeSelect.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export default class ModeSelect extends React.Component {
133133

134134
return (
135135
<div className={className + ' idle'} onClick={e => this.handleIdleSelectClick(e)}>
136-
<ModeIcon mode={modeName}/>
136+
<ModeIcon mode={modeName}/>{mode.label}
137137
</div>
138138
)
139139
}

browser/main/HomePage/ArticleDetail/index.js

Lines changed: 52 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,16 @@ import React, { PropTypes } from 'react'
22
import ReactDOM from 'react-dom'
33
import moment from 'moment'
44
import _ from 'lodash'
5-
import ModeIcon from 'browser/components/ModeIcon'
65
import MarkdownPreview from 'browser/components/MarkdownPreview'
76
import CodeEditor from 'browser/components/CodeEditor'
87
import {
9-
IDLE_MODE,
10-
EDIT_MODE,
11-
switchMode,
12-
switchArticle,
138
switchFolder,
14-
clearSearch,
15-
lockStatus,
16-
unlockStatus,
17-
updateArticle,
18-
destroyArticle,
19-
NEW
9+
cacheArticle,
10+
saveArticle,
11+
destroyArticle
2012
} from '../../actions'
2113
import linkState from 'browser/lib/linkState'
2214
import FolderMark from 'browser/components/FolderMark'
23-
import TagLink from '../TagLink'
2415
import TagSelect from 'browser/components/TagSelect'
2516
import ModeSelect from 'browser/components/ModeSelect'
2617
import activityRecord from 'browser/lib/activityRecord'
@@ -123,45 +114,31 @@ export default class ArticleDetail extends React.Component {
123114
clearInterval(this.refreshTimer)
124115
}
125116

126-
componentDidUpdate (prevProps) {
127-
let isModeChanged = prevProps.status.mode !== this.props.status.mode
128-
if (isModeChanged && this.props.status.mode === EDIT_MODE) {
129-
ReactDOM.findDOMNode(this.refs.title).focus()
130-
}
131-
}
132-
133117
componentWillReceiveProps (nextProps) {
134-
let nextState = {}
118+
if (nextProps.activeArticle == null || this.props.activeArticle == null || nextProps.activeArticle.key !== this.props.activeArticle.key) {
119+
let nextArticle = nextProps.activeArticle
120+
let nextModified = nextArticle != null ? _.findWhere(nextProps.modified, {key: nextArticle.key}) : null
135121

136-
let isArticleChanged = nextProps.activeArticle != null && (nextProps.activeArticle.key !== this.state.article.key)
137-
let isModeChanged = nextProps.status.mode !== this.props.status.mode
122+
let article = Object.assign({}, nextProps.activeArticle, nextModified)
138123

139-
// Reset article input
140-
if (isArticleChanged || (isModeChanged && nextProps.status.mode !== IDLE_MODE)) {
141-
Object.assign(nextState, {
142-
article: makeInstantArticle(nextProps.activeArticle)
124+
this.setState({
125+
article
143126
})
144127
}
128+
}
145129

146-
// Clean state
147-
if (isModeChanged) {
148-
Object.assign(nextState, {
149-
openDeleteConfirmMenu: false,
150-
previewMode: false,
151-
isArticleEdited: false,
152-
isTagChanged: false,
153-
isTitleChanged: false,
154-
isContentChanged: false
155-
})
156-
}
130+
cacheArticle () {
131+
let { dispatch } = this.props
157132

158-
this.setState(nextState)
133+
dispatch(cacheArticle(this.props.activeArticle.key, this.state.article))
159134
}
160135

161136
renderEmpty () {
162137
return (
163138
<div className='ArticleDetail empty'>
164-
Command(⌘) + Enter to create a new post
139+
<div className='ArticleDetail-empty-box'>
140+
<div className='ArticleDetail-empty-box-message'>Command(⌘) + N<br/>to create a new post</div>
141+
</div>
165142
</div>
166143
)
167144
}
@@ -176,123 +153,46 @@ export default class ArticleDetail extends React.Component {
176153

177154
handleSaveButtonClick (e) {
178155
let { dispatch, folders, status } = this.props
179-
let article = this.state.article
180-
let newArticle = Object.assign({}, article)
181-
182-
let folder = _.findWhere(folders, {key: article.FolderKey})
183-
if (folder == null) return false
184156

185-
dispatch(unlockStatus())
186-
187-
newArticle.status = null
188-
newArticle.updatedAt = new Date()
189-
newArticle.title = newArticle.title.trim()
190-
if (newArticle.createdAt == null) {
191-
newArticle.createdAt = new Date()
192-
if (newArticle.title.length === 0) {
193-
newArticle.title = `Created at ${moment(newArticle.createdAt).format('YYYY/MM/DD HH:mm')}`
194-
}
195-
activityRecord.emit('ARTICLE_CREATE', {mode: newArticle.mode})
196-
} else {
197-
activityRecord.emit('ARTICLE_UPDATE', {mode: newArticle.mode})
157+
let targetFolderKey = this.state.article.FolderKey
158+
dispatch(saveArticle(this.props.activeArticle.key, this.state.article), true)
159+
if (status.targetFolders.length > 0) {
160+
let targetFolder = _.findWhere(folders, {key: targetFolderKey})
161+
dispatch(switchFolder(targetFolder.name))
198162
}
199-
200-
dispatch(updateArticle(newArticle))
201-
dispatch(switchMode(IDLE_MODE))
202-
// Folder filterがかかっている時に、
203-
// Searchを初期化し、更新先のFolder filterをかける
204-
// かかれていない時に
205-
// Searchを初期化する
206-
if (status.targetFolders.length > 0) dispatch(switchFolder(folder.name))
207-
else dispatch(clearSearch())
208-
dispatch(switchArticle(newArticle.key))
209163
}
210164

211165
handleFolderKeyChange (e) {
212166
let article = this.state.article
213167
article.FolderKey = e.target.value
214168

215-
this.setState({article: article})
169+
this.setState({article: article}, () => this.cacheArticle())
216170
}
217171

218172
handleTitleChange (e) {
219173
let { article } = this.state
220174
article.title = e.target.value
221-
let _isTitleChanged = article.title !== this.props.activeArticle.title
222-
223-
let { isTagChanged, isContentChanged, isArticleEdited, isModeChanged } = this.state
224-
let _isArticleEdited = _isTitleChanged || isTagChanged || isContentChanged || isModeChanged
225175

226176
this.setState({
227-
article,
228-
isTitleChanged: _isTitleChanged,
229-
isArticleEdited: _isArticleEdited
230-
}, () => {
231-
if (isArticleEdited !== _isArticleEdited) {
232-
let { dispatch } = this.props
233-
if (_isArticleEdited) {
234-
console.log('lockit')
235-
dispatch(lockStatus())
236-
} else {
237-
console.log('unlockit')
238-
dispatch(unlockStatus())
239-
}
240-
}
241-
})
177+
article
178+
}, () => this.cacheArticle())
242179
}
243180

244181
handleTagsChange (newTag, tags) {
245182
let article = this.state.article
246183
article.tags = tags
247184

248-
let _isTagChanged = _.difference(article.tags, this.props.activeArticle.tags).length > 0 || _.difference(this.props.activeArticle.tags, article.tags).length > 0
249-
250-
let { isTitleChanged, isContentChanged, isArticleEdited, isModeChanged } = this.state
251-
let _isArticleEdited = _isTagChanged || isTitleChanged || isContentChanged || isModeChanged
252-
253185
this.setState({
254-
article,
255-
isTagChanged: _isTagChanged,
256-
isArticleEdited: _isArticleEdited
257-
}, () => {
258-
if (isArticleEdited !== _isArticleEdited) {
259-
let { dispatch } = this.props
260-
if (_isArticleEdited) {
261-
console.log('lockit')
262-
dispatch(lockStatus())
263-
} else {
264-
console.log('unlockit')
265-
dispatch(unlockStatus())
266-
}
267-
}
268-
})
186+
article
187+
}, () => this.cacheArticle())
269188
}
270189

271190
handleModeChange (value) {
272191
let { article } = this.state
273192
article.mode = value
274-
let _isModeChanged = article.mode !== this.props.activeArticle.mode
275-
276-
let { isTagChanged, isContentChanged, isArticleEdited, isTitleChanged } = this.state
277-
let _isArticleEdited = _isModeChanged || isTagChanged || isContentChanged || isTitleChanged
278-
279193
this.setState({
280-
article,
281-
previewMode: false,
282-
isModeChanged: _isModeChanged,
283-
isArticleEdited: _isArticleEdited
284-
}, () => {
285-
if (isArticleEdited !== _isArticleEdited) {
286-
let { dispatch } = this.props
287-
if (_isArticleEdited) {
288-
console.log('lockit')
289-
dispatch(lockStatus())
290-
} else {
291-
console.log('unlockit')
292-
dispatch(unlockStatus())
293-
}
294-
}
295-
})
194+
article
195+
}, () => this.cacheArticle())
296196
}
297197

298198
handleModeSelectBlur () {
@@ -302,34 +202,12 @@ export default class ArticleDetail extends React.Component {
302202
}
303203

304204
handleContentChange (e, value) {
305-
let { status } = this.props
306-
if (status.mode === IDLE_MODE) {
307-
return
308-
}
309-
310205
let { article } = this.state
311206
article.content = value
312-
let _isContentChanged = article.content !== this.props.activeArticle.content
313-
314-
let { isTagChanged, isModeChanged, isArticleEdited, isTitleChanged } = this.state
315-
let _isArticleEdited = _isContentChanged || isTagChanged || isModeChanged || isTitleChanged
316207

317208
this.setState({
318-
article,
319-
isContentChanged: _isContentChanged,
320-
isArticleEdited: _isArticleEdited
321-
}, () => {
322-
if (isArticleEdited !== _isArticleEdited) {
323-
let { dispatch } = this.props
324-
if (_isArticleEdited) {
325-
console.log('lockit')
326-
dispatch(lockStatus())
327-
} else {
328-
console.log('unlockit')
329-
dispatch(unlockStatus())
330-
}
331-
}
332-
})
209+
article
210+
}, () => this.cacheArticle())
333211
}
334212

335213
handleTogglePreviewButtonClick (e) {
@@ -373,14 +251,16 @@ export default class ArticleDetail extends React.Component {
373251
}
374252

375253
render () {
376-
let { folders, status, tags, activeArticle, user } = this.props
377-
254+
let { folders, status, tags, activeArticle, modified, user } = this.props
255+
if (activeArticle == null) return this.renderEmpty()
378256
let folderOptions = folders.map(folder => {
379257
return (
380258
<option key={folder.key} value={folder.key}>{folder.name}</option>
381259
)
382260
})
383261

262+
let isUnsaved = !!_.findWhere(modified, {key: activeArticle.key})
263+
384264
return (
385265
<div className='ArticleDetail'>
386266
<div className='ArticleDetail-info'>
@@ -392,7 +272,13 @@ export default class ArticleDetail extends React.Component {
392272
>
393273
{folderOptions}
394274
</select>
395-
{this.state.isArticleEdited ? ' (edited)' : ''}
275+
<span className='ArticleDetail-info-status'
276+
children={
277+
isUnsaved
278+
? <span> <span className='unsaved-mark'></span> Unsaved</span>
279+
: `Created : ${moment(this.state.article.createdAt).format('YYYY/MM/DD')} Updated : ${moment(this.state.article.updatedAt).format('YYYY/MM/DD')}`
280+
}
281+
/>
396282

397283
<div className='ArticleDetail-info-control'>
398284
<ShareButton
@@ -404,8 +290,8 @@ export default class ArticleDetail extends React.Component {
404290
<i className='fa fa-fw fa-clipboard'/><span className='tooltip'>Copy to clipboard</span>
405291
</button>
406292

407-
<button onClick={e => this.handleEditButtonClick(e)}>
408-
<i className='fa fa-fw fa-edit'/><span className='tooltip'>Save (⌘ + s)</span>
293+
<button onClick={e => this.handleSaveButtonClick(e)}>
294+
<i className='fa fa-fw fa-save'/><span className='tooltip'>Save (⌘ + s)</span>
409295
</button>
410296
<button onClick={e => this.handleDeleteButtonClick(e)}>
411297
<i className='fa fa-fw fa-trash'/><span className='tooltip'>Delete</span>
@@ -426,24 +312,22 @@ export default class ArticleDetail extends React.Component {
426312

427313
<div className='ArticleDetail-panel'>
428314
<div className='ArticleDetail-panel-header'>
429-
<ModeSelect
430-
ref='mode'
431-
onChange={e => this.handleModeChange(e)}
432-
value={this.state.article.mode}
433-
className='ArticleDetail-panel-header-mode'
434-
onBlur={() => this.handleModeSelectBlur()}
435-
/>
436315
<div className='ArticleDetail-panel-header-title'>
437316
<input
438317
onKeyDown={e => this.handleTitleKeyDown(e)}
439-
placeholder={this.state.article.createdAt == null
440-
? `Created at ${moment().format('YYYY/MM/DD HH:mm')}`
441-
: 'Title'}
318+
placeholder='(Untitled)'
442319
ref='title'
443320
value={this.state.article.title}
444321
onChange={e => this.handleTitleChange(e)}
445322
/>
446323
</div>
324+
<ModeSelect
325+
ref='mode'
326+
onChange={e => this.handleModeChange(e)}
327+
value={this.state.article.mode}
328+
className='ArticleDetail-panel-header-mode'
329+
onBlur={() => this.handleModeSelectBlur()}
330+
/>
447331
</div>
448332
{status.isTutorialOpen ? modeSelectTutorialElement : null}
449333

@@ -466,6 +350,7 @@ export default class ArticleDetail extends React.Component {
466350
ArticleDetail.propTypes = {
467351
status: PropTypes.shape(),
468352
activeArticle: PropTypes.shape(),
353+
modified: PropTypes.array,
469354
user: PropTypes.shape(),
470355
folders: PropTypes.array,
471356
tags: PropTypes.array,

0 commit comments

Comments
 (0)