Skip to content

Commit 00360c7

Browse files
committed
add unsaved list & move new post button to top bar
1 parent 8a62cd3 commit 00360c7

7 files changed

Lines changed: 240 additions & 229 deletions

File tree

browser/main/HomePage/ArticleDetail/index.js

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -138,22 +138,15 @@ export default class ArticleDetail extends React.Component {
138138
}
139139

140140
componentWillReceiveProps (nextProps) {
141-
if (nextProps.activeArticle == null || this.props.activeArticle == null || nextProps.activeArticle.key !== this.props.activeArticle.key) {
142-
let nextArticle = nextProps.activeArticle
143-
let nextModified = nextArticle != null ? _.findWhere(nextProps.modified, {key: nextArticle.key}) : null
144-
145-
let article = Object.assign({content: ''}, nextProps.activeArticle, nextModified)
146-
let nextState = {
147-
article,
148-
previewMode: false
149-
}
150-
151-
if (article.content.trim().length > 0 && article.mode === 'markdown') {
152-
nextState.previewMode = true
153-
}
141+
let nextArticle = nextProps.activeArticle
142+
let nextModified = nextArticle != null ? _.findWhere(nextProps.modified, {key: nextArticle.key}) : null
154143

155-
this.setState(nextState)
144+
let article = Object.assign({content: ''}, nextProps.activeArticle, nextModified)
145+
let nextState = {
146+
article
156147
}
148+
149+
this.setState(nextState)
157150
}
158151

159152
editArticle () {
@@ -404,12 +397,12 @@ export default class ArticleDetail extends React.Component {
404397
}
405398

406399
ArticleDetail.propTypes = {
400+
dispatch: PropTypes.func,
407401
status: PropTypes.shape(),
408-
activeArticle: PropTypes.shape(),
409-
modified: PropTypes.array,
402+
tags: PropTypes.array,
410403
user: PropTypes.shape(),
411404
folders: PropTypes.array,
412-
tags: PropTypes.array,
413-
dispatch: PropTypes.func
405+
modified: PropTypes.array,
406+
activeArticle: PropTypes.shape()
414407
}
415408
ArticleDetail.prototype.linkState = linkState

browser/main/HomePage/ArticleList.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,16 @@ export default class ArticleList extends React.Component {
8585
}
8686

8787
handleArticleListKeyDown (e) {
88-
console.log(e.keyCode)
8988
if (e.metaKey || e.ctrlKey) return true
9089

91-
if (e.keyCode === 65) {
90+
if (e.keyCode === 65 && !e.shiftKey) {
9291
e.preventDefault()
93-
remote.getCurrentWebContents().send('nav-new-post')
92+
remote.getCurrentWebContents().send('top-new-post')
93+
}
94+
95+
if (e.keyCode === 65 && e.shiftKey) {
96+
e.preventDefault()
97+
remote.getCurrentWebContents().send('nav-new-folder')
9498
}
9599

96100
if (e.keyCode === 68) {
@@ -129,7 +133,7 @@ export default class ArticleList extends React.Component {
129133
article = Object.assign({}, article, modifiedArticle)
130134
}
131135
let tagElements = Array.isArray(article.tags) && article.tags.length > 0
132-
? article.tags.map(tag => {
136+
? article.tags.slice().map(tag => {
133137
return (<TagLink key={tag} tag={tag}/>)
134138
})
135139
: (<span>Not tagged yet</span>)
@@ -189,9 +193,9 @@ export default class ArticleList extends React.Component {
189193
}
190194

191195
ArticleList.propTypes = {
196+
dispatch: PropTypes.func,
192197
folders: PropTypes.array,
193198
articles: PropTypes.array,
194199
modified: PropTypes.array,
195-
activeArticle: PropTypes.shape(),
196-
dispatch: PropTypes.func
200+
activeArticle: PropTypes.shape()
197201
}

browser/main/HomePage/ArticleNavigator.js

Lines changed: 72 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import React, { PropTypes } from 'react'
22
import { findWhere } from 'lodash'
3-
import { setSearchFilter, switchFolder, saveArticle } from '../actions'
3+
import { setSearchFilter, switchFolder, uncacheArticle, saveAllArticles, switchArticle, clearSearch } from '../actions'
44
import { openModal, isModalOpen } from 'browser/lib/modal'
55
import FolderMark from 'browser/components/FolderMark'
66
import Preferences from '../modal/Preferences'
77
import CreateNewFolder from '../modal/CreateNewFolder'
8-
import keygen from 'browser/lib/keygen'
8+
import _ from 'lodash'
9+
import ModeIcon from 'browser/components/ModeIcon'
910

1011
const ipc = require('electron').ipcRenderer
1112

1213
const BRAND_COLOR = '#18AF90'
14+
const OSX = global.process.platform === 'darwin'
1315

1416
const preferenceTutorialElement = (
1517
<svg width='300' height='300' className='tutorial'>
@@ -29,7 +31,7 @@ c-4,0-7.9,0-11.9-0.1C164,294,164,297,165.9,297L165.9,297z'/>
2931
const newPostTutorialElement = (
3032
<svg width='900' height='900' className='tutorial'>
3133
<text x='290' y='155' fill={BRAND_COLOR} fontSize='24'>Create a new post!!</text>
32-
<text x='300' y='180' fill={BRAND_COLOR} fontSize='16' children={`press \`${process.platform === 'darwin' ? '⌘' : '^'} + Enter\` or \`a\``}/>
34+
<text x='300' y='180' fill={BRAND_COLOR} fontSize='16' children={`press \`${OSX === 'darwin' ? '⌘' : '^'} + Enter\` or \`a\``}/>
3335
<svg x='130' y='-20' width='400' height='400'>
3436
<path fill='white' d='M56.2,132.5c11.7-2.9,23.9-6,36.1-4.1c8.7,1.4,16.6,5.5,23.7,10.5c13.3,9.4,24.5,21.5,40.2,27
3537
c1.8,0.6,2.6-2.3,0.8-2.9c-17.1-6-28.9-20.3-44-29.7c-7-4.4-14.8-7.4-23-8.2c-11.7-1.1-23.3,1.7-34.5,4.5
@@ -62,54 +64,24 @@ c-3.4-6.1-8.2-11.3-13.8-15.4C50.2,11.6,31,10.9,15.3,19C13.6,19.8,15.1,22.4,16.8,
6264
export default class ArticleNavigator extends React.Component {
6365
constructor (props) {
6466
super(props)
65-
this.newPostHandler = e => {
66-
if (isModalOpen()) return true
67-
this.handleNewPostButtonClick(e)
68-
}
6967
this.newFolderHandler = e => {
7068
if (isModalOpen()) return true
7169
this.handleNewFolderButton(e)
7270
}
7371
}
7472

7573
componentDidMount () {
76-
ipc.on('nav-new-post', this.newPostHandler)
7774
ipc.on('nav-new-folder', this.newFolderHandler)
7875
}
7976

8077
componentWillUnmount () {
81-
ipc.removeListener('nav-new-post', this.newPostHandler)
8278
ipc.removeListener('nav-new-folder', this.newFolderHandler)
8379
}
8480

8581
handlePreferencesButtonClick (e) {
8682
openModal(Preferences)
8783
}
8884

89-
handleNewPostButtonClick (e) {
90-
let { dispatch, folders, status } = this.props
91-
let { targetFolders } = status
92-
93-
let isFolderFilterApplied = targetFolders.length > 0
94-
let FolderKey = isFolderFilterApplied
95-
? targetFolders[0].key
96-
: folders[0].key
97-
98-
let newArticle = {
99-
key: keygen(),
100-
title: '',
101-
content: '',
102-
mode: 'markdown',
103-
tags: [],
104-
FolderKey: FolderKey,
105-
craetedAt: new Date(),
106-
updatedAt: new Date()
107-
}
108-
109-
dispatch(saveArticle(newArticle.key, newArticle, true))
110-
if (isFolderFilterApplied) dispatch(switchFolder(targetFolders[0].name))
111-
}
112-
11385
handleNewFolderButton (e) {
11486
let { user } = this.props
11587
openModal(CreateNewFolder, {user: user})
@@ -127,11 +99,52 @@ export default class ArticleNavigator extends React.Component {
12799
dispatch(setSearchFilter(''))
128100
}
129101

102+
handleUnsavedItemClick (article) {
103+
let { dispatch } = this.props
104+
return e => {
105+
let { articles } = this.props
106+
let isInArticleList = articles.some(_article => _article.key === article.key)
107+
if (!isInArticleList) dispatch(clearSearch())
108+
dispatch(switchArticle(article.key))
109+
}
110+
}
111+
112+
handleUncacheButtonClick (article) {
113+
let { dispatch } = this.props
114+
return e => {
115+
dispatch(uncacheArticle(article.key))
116+
}
117+
}
118+
119+
handleSaveAllClick (e) {
120+
let { dispatch } = this.props
121+
dispatch(saveAllArticles())
122+
}
123+
130124
render () {
131-
let { status, user, folders, allArticles } = this.props
125+
let { status, user, folders, allArticles, modified, activeArticle } = this.props
132126
let { targetFolders } = status
133127
if (targetFolders == null) targetFolders = []
134128

129+
let modifiedElements = modified.map(modifiedArticle => {
130+
let originalArticle = _.findWhere(allArticles, {key: modifiedArticle.key})
131+
if (originalArticle == null) return false
132+
let combinedArticle = Object.assign({}, originalArticle, modifiedArticle)
133+
134+
let className = 'ArticleNavigator-unsaved-list-item'
135+
if (activeArticle && activeArticle.key === combinedArticle.key) className += ' active'
136+
137+
return (
138+
<div key={modifiedArticle.key} onClick={e => this.handleUnsavedItemClick(combinedArticle)(e)} className={className}>
139+
<div className='ArticleNavigator-unsaved-list-item-label'>
140+
<ModeIcon mode={combinedArticle.mode}/>&nbsp;
141+
{combinedArticle.title}
142+
</div>
143+
<button onClick={e => this.handleUncacheButtonClick(combinedArticle)(e)} className='ArticleNavigator-unsaved-list-item-discard-button'><i className='fa fa-times'/></button>
144+
</div>
145+
)
146+
}).filter(modifiedArticle => modifiedArticle).sort((a, b) => a.updatedAt - b.updatedAt)
147+
135148
let folderElememts = folders.map((folder, index) => {
136149
let isActive = findWhere(targetFolders, {key: folder.key})
137150
let articleCount = allArticles.filter(article => article.FolderKey === folder.key && article.status !== 'NEW').length
@@ -157,22 +170,27 @@ export default class ArticleNavigator extends React.Component {
157170

158171
</div>
159172

160-
<div className='controlSection'>
161-
<button onClick={e => this.handleNewPostButtonClick(e)} className='newPostBtn'>
162-
New Post
163-
<span className='tooltip'>Create a new Post ({process.platform === 'darwin' ? '⌘' : '^'} + n)</span>
164-
</button>
165-
166-
{status.isTutorialOpen ? newPostTutorialElement : null}
167-
173+
<div className='ArticleNavigator-unsaved'>
174+
<div className='ArticleNavigator-unsaved-header'>Work in progress</div>
175+
<div className='ArticleNavigator-unsaved-list'>
176+
{modifiedElements.length > 0
177+
? modifiedElements
178+
: (
179+
<div className='ArticleNavigator-unsaved-list-empty'>Empty list</div>
180+
)
181+
}
182+
</div>
183+
<div className='ArticleNavigator-unsaved-control'>
184+
<button onClick={e => this.handleSaveAllClick()} className='ArticleNavigator-unsaved-control-save-all-button' disabled={modifiedElements.length === 0}>Save all</button>
185+
</div>
168186
</div>
169187

170-
<div className='folders'>
171-
<div className='header'>
188+
<div className='ArticleNavigator-folders'>
189+
<div className='ArticleNavigator-folders-header'>
172190
<div className='title'>Folders</div>
173191
<button onClick={e => this.handleNewFolderButton(e)} className='addBtn'>
174192
<i className='fa fa-fw fa-plus'/>
175-
<span className='tooltip'>Create a new folder ({process.platform === 'darwin' ? '⌘' : '^'} + Shift + n)</span>
193+
<span className='tooltip'>Create a new folder ({OSX === 'darwin' ? '⌘' : '^'} + Shift + n)</span>
176194
</button>
177195

178196
{status.isTutorialOpen ? newFolderTutorialElement : null}
@@ -189,12 +207,17 @@ export default class ArticleNavigator extends React.Component {
189207
}
190208

191209
ArticleNavigator.propTypes = {
192-
user: PropTypes.object,
193-
folders: PropTypes.array,
194-
allArticles: PropTypes.array,
210+
dispatch: PropTypes.func,
195211
status: PropTypes.shape({
196212
folderId: PropTypes.number
197213
}),
198-
dispatch: PropTypes.func
214+
user: PropTypes.object,
215+
folders: PropTypes.array,
216+
allArticles: PropTypes.array,
217+
articles: PropTypes.array,
218+
modified: PropTypes.array,
219+
activeArticle: PropTypes.shape({
220+
key: PropTypes.string
221+
})
199222
}
200223

0 commit comments

Comments
 (0)