1
0
mirror of https://github.com/BoostIo/Boostnote synced 2026-01-30 09:07:21 +00:00
This commit is contained in:
Dick Choi
2016-05-25 17:09:39 +09:00
parent 1a98afee92
commit 7f8733796e
17 changed files with 901 additions and 650 deletions

View File

@@ -0,0 +1,17 @@
.root
absolute top bottom right
border-width 1px 0
border-style solid
border-color $ui-borderColor
.empty
height 320px
display flex
align-items center
.empty-message
width 100%
font-size 42px
line-height 72px
text-align center
color $ui-inactive-text-color

View File

@@ -0,0 +1,155 @@
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './NoteDetail.styl'
import MarkdownEditor from 'browser/components/MarkdownEditor'
import queue from 'browser/main/lib/queue'
class NoteDetail extends React.Component {
constructor (props) {
super(props)
this.state = {
note: Object.assign({}, props.note),
isDispatchQueued: false
}
this.dispatchTimer = null
}
componentDidUpdate (prevProps, prevState) {
}
componentWillReceiveProps (nextProps) {
if (nextProps.note.key !== this.props.note.key) {
if (this.state.isDispatchQueued) {
this.dispatch()
}
this.setState({
note: Object.assign({}, nextProps.note),
isDispatchQueued: false
}, () => {
this.refs.content.reload()
})
}
}
findTitle (value) {
let splitted = value.split('\n')
let title = null
for (let i = 0; i < splitted.length; i++) {
let trimmedLine = splitted[i].trim()
if (trimmedLine.match(/^# .+/)) {
title = trimmedLine.substring(1, trimmedLine.length).trim()
break
}
}
if (title == null) {
for (let i = 0; i < splitted.length; i++) {
let trimmedLine = splitted[i].trim()
if (trimmedLine.length > 0) {
title = trimmedLine
break
}
}
if (title == null) {
title = ''
}
}
return title
}
handleChange (e) {
let { note } = this.state
note.content = this.refs.content.value
this.setState({
note,
isDispatchQueued: true
}, () => {
this.queueDispatch()
})
}
cancelDispatchQueue () {
if (this.dispatchTimer != null) {
window.clearTimeout(this.dispatchTimer)
this.dispatchTimer = null
}
}
queueDispatch () {
this.cancelDispatchQueue()
this.dispatchTimer = window.setTimeout(() => {
this.dispatch()
this.setState({
isDispatchQueued: false
})
}, 500)
}
dispatch () {
let { note } = this.state
note = Object.assign({}, note)
let repoKey = note._repository.key
note.title = this.findTitle(note.content)
let { dispatch } = this.props
dispatch({
type: 'SAVE_NOTE',
repository: repoKey,
note: note
})
queue.save(repoKey, note)
}
render () {
return (
<div className='NoteDetail'
style={this.props.style}
styleName='root'
>
<div styleName='info'>
<div styleName='info-left'>
<div styleName='info-left-folderSelect'>FOLDER SELECT</div>
<div styleName='info-left-tagSelect'>TAG SELECT</div>
</div>
<div styleName='info-right'>
<button styleName='info-right-button'>
<i className='fa fa-clipboard fa-fw'/>
</button>
<button styleName='info-right-button'>
<i className='fa fa-share-alt fa-fw'/>
</button>
<button styleName='info-right-button'>
<i className='fa fa-ellipsis-v'/>
</button>
</div>
</div>
<div styleName='body'>
<MarkdownEditor
ref='content'
styleName='body-noteEditor'
value={this.state.note.content}
onChange={(e) => this.handleChange(e)}
ignorePreviewPointerEvents={this.props.ignorePreviewPointerEvents}
/>
</div>
</div>
)
}
}
NoteDetail.propTypes = {
dispatch: PropTypes.func,
repositories: PropTypes.array,
style: PropTypes.shape({
left: PropTypes.number
}),
ignorePreviewPointerEvents: PropTypes.bool
}
export default CSSModules(NoteDetail, styles)

View File

@@ -0,0 +1,38 @@
.root
absolute top bottom right
border-width 1px 0
border-style solid
border-color $ui-borderColor
.info
absolute top left right
height 50px
border-bottom $ui-border
background-color $ui-backgroundColor
.info-left
float left
.info-right
float right
.info-right-button
width 34px
height 34px
border-radius 17px
navButtonColor()
border $ui-border
font-size 14px
margin 8px 2px
padding 0
&:active
border-color $ui-button--active-backgroundColor
&:hover .left-control-newPostButton-tooltip
display block
.body
absolute bottom left right
top 50px
.body-noteEditor
absolute top bottom left right

View File

@@ -0,0 +1,65 @@
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './Detail.styl'
import _ from 'lodash'
import NoteDetail from './NoteDetail'
const electron = require('electron')
const OSX = global.process.platform === 'darwin'
class Detail extends React.Component {
componentDidUpdate (prevProps, prevState) {
}
render () {
let { repositories, location } = this.props
let note = null
if (location.query.key != null) {
let splitted = location.query.key.split('-')
let repoKey = splitted.shift()
let noteKey = splitted.shift()
let repo = _.find(repositories, {key: repoKey})
if (_.isObject(repo) && _.isArray(repo.notes)) {
note = _.find(repo.notes, {key: noteKey})
}
}
if (note == null) {
return (
<div className='Detail'
style={this.props.style}
styleName='root'
tabIndex='0'
>
<div styleName='empty'>
<div styleName='empty-message'>{OSX ? 'Command(⌘)' : 'Ctrl(^)'} + N<br/>to create a new post</div>
</div>
</div>
)
}
return (
<NoteDetail
note={note}
{..._.pick(this.props, [
'dispatch',
'repositories',
'style',
'ignorePreviewPointerEvents'
])}
/>
)
}
}
Detail.propTypes = {
dispatch: PropTypes.func,
repositories: PropTypes.array,
style: PropTypes.shape({
left: PropTypes.number
}),
ignorePreviewPointerEvents: PropTypes.bool
}
export default CSSModules(Detail, styles)