1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-26 16:11:45 +00:00

embed hotkey, config to preferences modal & fix datasaving sequence(Async, Queue)

This commit is contained in:
Rokt33r
2016-01-08 14:38:29 +09:00
parent ee280d5c7b
commit 09735b7f47
14 changed files with 461 additions and 194 deletions

View File

@@ -17,6 +17,14 @@ export default class ArticleEditor extends React.Component {
}
}
componentWillReceiveProps (nextProps) {
if (nextProps.article.key !== this.props.article.key) {
this.setState({
content: this.props.article.content
})
}
}
resetCursorPosition () {
this.setState({
cursorPosition: null,
@@ -77,13 +85,19 @@ export default class ArticleEditor extends React.Component {
}
handleBlurCodeEditor () {
if (this.props.mode === 'markdown') {
let { article } = this.props
if (article.mode === 'markdown') {
this.switchPreviewMode()
}
}
handleCodeEditorChange (value) {
this.props.onChange(value)
}
render () {
let showPreview = this.props.mode === 'markdown' && this.state.status === PREVIEW_MODE
let { article } = this.props
let showPreview = article.mode === 'markdown' && this.state.status === PREVIEW_MODE
if (showPreview) {
return (
<div className='ArticleEditor'>
@@ -92,7 +106,7 @@ export default class ArticleEditor extends React.Component {
onMouseUp={e => this.handlePreviewMouseUp(e)}
onMouseDown={e => this.handlePreviewMouseDown(e)}
onMouseMove={e => this.handlePreviewMouseMove(e)}
content={this.props.content}
content={article.content}
/>
<div className='ArticleDetail-panel-content-tooltip'>Click to Edit</div>
</div>
@@ -104,11 +118,10 @@ export default class ArticleEditor extends React.Component {
<CodeEditor
ref='editor'
onBlur={e => this.handleBlurCodeEditor(e)}
onChange={this.props.onChange}
mode={this.props.mode}
code={this.props.content}
onChange={value => this.handleCodeEditorChange(value)}
article={article}
/>
{this.props.mode === 'markdown'
{article.mode === 'markdown'
? (
<div className='ArticleDetail-panel-content-tooltip'>Press ESC to watch Preview</div>
)
@@ -120,7 +133,10 @@ export default class ArticleEditor extends React.Component {
}
ArticleEditor.propTypes = {
content: PropTypes.string,
mode: PropTypes.string,
article: PropTypes.shape({
content: PropTypes.string,
key: PropTypes.string,
mode: PropTypes.string
}),
onChange: PropTypes.func
}

View File

@@ -18,9 +18,9 @@ import DeleteArticleModal from '../../modal/DeleteArticleModal'
import ArticleEditor from './ArticleEditor'
const electron = require('electron')
const ipc = electron.ipcRenderer
const remote = electron.remote
const { Menu, MenuItem } = remote
let count = 0
// const remote = electron.remote
// const { Menu, MenuItem } = remote
// const othersMenu = new Menu()
// othersMenu.append(new MenuItem({
// label: 'Delete Post',
@@ -152,18 +152,6 @@ export default class ArticleDetail extends React.Component {
ipc.removeListener('detail-edit', this.editHandler)
}
componentWillReceiveProps (nextProps) {
let nextArticle = nextProps.activeArticle
let nextModified = nextArticle != null ? _.findWhere(nextProps.modified, {key: nextArticle.key}) : null
let article = Object.assign({content: ''}, nextProps.activeArticle, nextModified)
let nextState = {
article
}
this.setState(nextState)
}
componentDidUpdate (prevProps, prevState) {
if (this.props.activeArticle == null || prevProps.activeArticle == null || this.props.activeArticle.key !== prevProps.activeArticle.key) {
this.refs.editor.resetCursorPosition()
@@ -175,20 +163,6 @@ export default class ArticleDetail extends React.Component {
ReactDOM.findDOMNode(this.refs.title).select()
}
cacheArticle () {
let { dispatch, status, folders } = this.props
let input = Object.assign({}, this.props.activeArticle.key, this.state.article, {updatedAt: new Date()})
dispatch(updateArticle(input))
let targetFolderKey = this.state.article.FolderKey
if (status.targetFolders.length > 0) {
let targetFolder = _.findWhere(folders, {key: targetFolderKey})
dispatch(switchFolder(targetFolder.name))
}
}
renderEmpty () {
return (
<div className='ArticleDetail empty'>
@@ -199,68 +173,64 @@ export default class ArticleDetail extends React.Component {
)
}
handleSaveButtonClick (e) {
// let { dispatch, folders, status } = this.props
// let targetFolderKey = this.state.article.FolderKey
// dispatch(saveArticle(this.props.activeArticle.key, this.state.article), true)
// if (status.targetFolders.length > 0) {
// let targetFolder = _.findWhere(folders, {key: targetFolderKey})
// dispatch(switchFolder(targetFolder.name))
// }
}
handleOthersButtonClick (e) {
this.deleteHandler()
}
handleFolderKeyChange (e) {
let article = this.state.article
article.FolderKey = e.target.value
let { dispatch, activeArticle, status, folders } = this.props
let article = Object.assign({}, activeArticle, {
FolderKey: e.target.value,
updatedAt: new Date()
})
this.setState({article: article}, () => this.cacheArticle())
dispatch(updateArticle(article))
let targetFolderKey = this.state.article.FolderKey
if (status.targetFolders.length > 0) {
let targetFolder = _.findWhere(folders, {key: targetFolderKey})
dispatch(switchFolder(targetFolder.name))
}
}
handleTitleChange (e) {
let { article } = this.state
article.title = e.target.value
this.setState({
article
}, () => this.cacheArticle())
let { dispatch, activeArticle } = this.props
let article = Object.assign({}, activeArticle, {
title: e.target.value,
updatedAt: new Date()
})
dispatch(updateArticle(article))
}
handleTagsChange (newTag, tags) {
let article = this.state.article
article.tags = tags
let { dispatch, activeArticle } = this.props
let article = Object.assign({}, activeArticle, {
tags: tags,
updatedAt: new Date()
})
this.setState({
article
}, () => this.cacheArticle())
dispatch(updateArticle(article))
}
handleModeChange (value) {
let { article } = this.state
article.mode = value
this.setState({
article
}, () => this.cacheArticle())
let { dispatch, activeArticle } = this.props
let article = Object.assign({}, activeArticle, {
mode: value,
updatedAt: new Date()
})
dispatch(updateArticle(article))
}
handleContentChange (e, value) {
let { article } = this.state
article.content = value
this.setState({
article
}, () => this.cacheArticle())
}
handleCodeEditorBlur (e) {
if (this.state.article.mode === 'markdown' && !this.state.previewMode) {
this.setState({
previewMode: true
handleContentChange (value) {
let { dispatch, activeArticle } = this.props
if (activeArticle.content !== value) {
let article = Object.assign({}, activeArticle, {
content: value,
updatedAt: new Date()
})
dispatch(updateArticle(article))
}
}
@@ -270,13 +240,6 @@ export default class ArticleDetail extends React.Component {
}
}
handleUncache (e) {
if (this.props.activeArticle) {
let { dispatch, activeArticle } = this.props
dispatch(uncacheArticle(activeArticle.key))
}
}
handleTitleKeyDown (e) {
if (e.keyCode === 9 && !e.shiftKey) {
e.preventDefault()
@@ -312,7 +275,7 @@ export default class ArticleDetail extends React.Component {
<div className='ArticleDetail-info-row'>
<select
className='ArticleDetail-info-folder'
value={this.state.article.FolderKey}
value={activeArticle.FolderKey}
onChange={e => this.handleFolderKeyChange(e)}
>
{folderOptions}
@@ -321,7 +284,7 @@ export default class ArticleDetail extends React.Component {
children={
isUnsaved
? <span> <span className='unsaved-mark'></span> Unsaved</span>
: `Created : ${moment(this.state.article.createdAt).format('YYYY/MM/DD')} Updated : ${moment(this.state.article.updatedAt).format('YYYY/MM/DD')}`
: `Created : ${moment(activeArticle.createdAt).format('YYYY/MM/DD')} Updated : ${moment(activeArticle.updatedAt).format('YYYY/MM/DD')}`
}
/>
@@ -351,7 +314,7 @@ export default class ArticleDetail extends React.Component {
{status.isTutorialOpen ? editDeleteTutorialElement : null}
<div>
<TagSelect
tags={this.state.article.tags}
tags={activeArticle.tags}
onChange={(tags, tag) => this.handleTagsChange(tags, tag)}
suggestTags={tags}
/>
@@ -367,7 +330,7 @@ export default class ArticleDetail extends React.Component {
onKeyDown={e => this.handleTitleKeyDown(e)}
placeholder='(Untitled)'
ref='title'
value={this.state.article.title}
value={activeArticle.title}
onChange={e => this.handleTitleChange(e)}
/>
</div>
@@ -375,16 +338,15 @@ export default class ArticleDetail extends React.Component {
ref='mode'
onChange={e => this.handleModeChange(e)}
onKeyDown={e => this.handleModeSelectKeyDown(e)}
value={this.state.article.mode}
value={activeArticle.mode}
className='ArticleDetail-panel-header-mode'
/>
</div>
{status.isTutorialOpen ? modeSelectTutorialElement : null}
<ArticleEditor
ref='editor'
content={this.state.article.content}
mode={this.state.article.mode}
onChange={(e, content) => this.handleContentChange(e, content)}
article={activeArticle}
onChange={content => this.handleContentChange(content)}
/>
</div>
</div>

View File

@@ -130,7 +130,7 @@ export default class ArticleList extends React.Component {
let modifiedArticle = _.findWhere(modified, {key: article.key})
let originalArticle = article
if (modifiedArticle) {
article = Object.assign({}, article, modifiedArticle)
article = Object.assign({}, article)
}
let tagElements = Array.isArray(article.tags) && article.tags.length > 0
? article.tags.slice().map(tag => {

View File

@@ -33,7 +33,7 @@ export default class CreateNewFolder extends React.Component {
name,
color
}
console.log(input)
try {
store.dispatch(createFolder(input))
} catch (e) {

View File

@@ -6,10 +6,13 @@ const electron = require('electron')
const ipc = electron.ipcRenderer
const remote = electron.remote
const OSX = global.process.platform === 'darwin'
export default class AppSettingTab extends React.Component {
constructor (props) {
super(props)
let keymap = remote.getGlobal('keymap')
let keymap = Object.assign({}, remote.getGlobal('keymap'))
let config = Object.assign({}, remote.getGlobal('config'))
let userName = props.user != null ? props.user.name : null
this.state = {
@@ -18,10 +21,10 @@ export default class AppSettingTab extends React.Component {
alert: null
},
userAlert: null,
keymap: {
toggleFinder: keymap.toggleFinder
},
keymapAlert: null
keymap: keymap,
keymapAlert: null,
config: config,
configAlert: null
}
}
@@ -48,21 +51,33 @@ export default class AppSettingTab extends React.Component {
}
submitHotKey () {
ipc.send('hotkeyUpdated', {
toggleFinder: this.state.keymap.toggleFinder
})
ipc.send('hotkeyUpdated', this.state.keymap)
}
submitConfig () {
ipc.send('configUpdated', this.state.config)
}
handleSaveButtonClick (e) {
this.submitHotKey()
}
handleConfigSaveButtonClick (e) {
this.submitConfig()
}
handleKeyDown (e) {
if (e.keyCode === 13) {
this.submitHotKey()
}
}
handleConfigKeyDown (e) {
if (e.keyCode === 13) {
this.submitConfig()
}
}
handleNameSaveButtonClick (e) {
let { dispatch } = this.props
@@ -104,8 +119,61 @@ export default class AppSettingTab extends React.Component {
{userAlertElement}
</div>
</div>
<div className='section'>
<div className='sectionTitle'>Text</div>
<div className='sectionInput'>
<label>Editor Font Size</label>
<input valueLink={this.linkState('config.editor-font-size')} onKeyDown={e => this.handleConfigKeyDown(e)} type='text'/>
</div>
<div className='sectionInput'>
<label>Editor Font Family</label>
<input valueLink={this.linkState('config.editor-font-family')} onKeyDown={e => this.handleConfigKeyDown(e)} type='text'/>
</div>
<div className='sectionSelect'>
<label>Editor Indent Style</label>
<div className='sectionSelect-input'>
type
<select valueLink={this.linkState('config.editor-indent-type')}>
<option value='space'>Space</option>
<option value='tab'>Tab</option>
</select>
size
<select valueLink={this.linkState('config.editor-indent-size')}>
<option value='2'>2</option>
<option value='4'>4</option>
<option value='8'>8</option>
</select>
</div>
</div>
<div className='sectionInput'>
<label>Preview Font Size</label>
<input valueLink={this.linkState('config.preview-font-size')} onKeyDown={e => this.handleConfigKeyDown(e)} type='text'/>
</div>
<div className='sectionInput'>
<label>Preview Font Family</label>
<input valueLink={this.linkState('config.preview-font-family')} onKeyDown={e => this.handleConfigKeyDown(e)} type='text'/>
</div>
{
true// !OSX
? (
<div className='sectionInput'>
<label>Direct write(Windows only)</label>
<input disabled={OSX} onKeyDown={e => this.handleConfigKeyDown(e)} type='checkbox'/>
</div>
)
: null
}
<div className='sectionConfirm'>
<button onClick={e => this.handleConfigSaveButtonClick(e)}>Save</button>
</div>
</div>
<div className='section'>
<div className='sectionTitle'>Hotkey</div>
<div className='sectionInput'>
<label>Toggle Main</label>
<input onKeyDown={e => this.handleKeyDown(e)} valueLink={this.linkState('keymap.toggleMain')} type='text'/>
</div>
<div className='sectionInput'>
<label>Toggle Finder(popup)</label>
<input onKeyDown={e => this.handleKeyDown(e)} valueLink={this.linkState('keymap.toggleFinder')} type='text'/>
@@ -142,5 +210,8 @@ export default class AppSettingTab extends React.Component {
AppSettingTab.prototype.linkState = linkState
AppSettingTab.propTypes = {
user: PropTypes.shape({
name: PropTypes.string
}),
dispatch: PropTypes.func
}

View File

@@ -89,7 +89,7 @@ export default class Tutorial extends React.Component {
<div className='title'>Easy to access with Finder</div>
<div className='content'>
The Finder helps you organize all of the files and documents.<br/>
There is a short-cut key [control + shift + tab] to open the Finder.<br/>
There is a short-cut key [ + alt + s] to open the Finder.<br/>
It is available to save your articles on the Clipboard<br/>
by selecting your file with pressing Enter key,<br/>
and to paste the contents of the Clipboard with [{process.platform === 'darwin' ? 'Command' : 'Control'}-V]