1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 09:46:22 +00:00
This commit is contained in:
Dick Choi
2016-07-21 03:21:53 +09:00
parent b6d34472fe
commit 6c67b96e30
3 changed files with 148 additions and 22 deletions

View File

@@ -102,6 +102,7 @@ class Main extends React.Component {
'dispatch', 'dispatch',
'storages', 'storages',
'config', 'config',
'notes',
'params', 'params',
'location' 'location'
])} ])}

View File

@@ -36,6 +36,46 @@ $control-height = 34px
outline none outline none
border none border none
.control-search-optionList
position fixed
z-index 200
width 275px
height 175px
overflow-y auto
background-color $modal-background
border-radius 2px
box-shadow 2px 2px 10px gray
.control-search-optionList-item
height 50px
border-bottom $ui-border
transition background-color 0.15s
padding 5px
cursor pointer
overflow ellipsis
&:hover
background-color alpha($ui-active-color, 10%)
.control-search-optionList-item-folder
border-left 4px solid transparent
padding 2px 5px
color $ui-text-color
overflow ellipsis
font-size 12px
height 16px
margin-bottom 4px
.control-search-optionList-item-folder-surfix
font-size 10px
margin-left 5px
color $ui-inactive-text-color
.control-search-optionList-item-type
font-size 12px
color $ui-inactive-text-color
padding-right 3px
.control-search-optionList-empty
height 150px
color $ui-inactive-text-color
line-height 150px
text-align center
.control-newPostButton .control-newPostButton
display block display block
absolute top right bottom absolute top right bottom
@@ -51,7 +91,6 @@ $control-height = 34px
&:hover .left-control-newPostButton-tooltip &:hover .left-control-newPostButton-tooltip
display block display block
.control-newPostButton-tooltip .control-newPostButton-tooltip
position fixed position fixed
line-height 1.4 line-height 1.4

View File

@@ -7,6 +7,7 @@ import Commander from 'browser/main/lib/Commander'
import dataApi from 'browser/main/lib/dataApi' import dataApi from 'browser/main/lib/dataApi'
import modal from 'browser/main/lib/modal' import modal from 'browser/main/lib/modal'
import NewNoteModal from 'browser/main/modals/NewNoteModal' import NewNoteModal from 'browser/main/modals/NewNoteModal'
import { hashHistory } from 'react-router'
const OSX = window.process.platform === 'darwin' const OSX = window.process.platform === 'darwin'
@@ -15,25 +16,12 @@ class TopBar extends React.Component {
super(props) super(props)
this.state = { this.state = {
search: '' search: '',
searchOptions: [],
searchPopupOpen: false
} }
} }
isInputFocused () {
return document.activeElement === this.refs.searchInput
}
escape () {
}
focusInput () {
this.searchInput.focus()
}
blurInput () {
this.searchInput.blur()
}
handleNewPostButtonClick (e) { handleNewPostButtonClick (e) {
let { storages, params, dispatch, location } = this.props let { storages, params, dispatch, location } = this.props
let storage = _.find(storages, {key: params.storageKey}) let storage = _.find(storages, {key: params.storageKey})
@@ -51,11 +39,98 @@ class TopBar extends React.Component {
}) })
} }
handleTutorialButtonClick (e) { handleSearchChange (e) {
this.setState({
search: this.refs.searchInput.value
})
}
getOptions () {
let { notes } = this.props
let { search } = this.state
if (search.trim().length === 0) return []
let searchBlocks = search.split(' ')
searchBlocks.forEach((block) => {
if (block.match(/^#.+/)) {
let tag = block.match(/#(.+)/)[1]
notes = notes.filter((note) => note.tags.some((_tag) => _tag === tag))
}
notes = notes.filter((note) => {
if (note.type === 'SNIPPET_NOTE') {
return note.description.match(block)
} else if (note.type === 'MARKDOWN_NOTE') {
return note.content.match(block)
}
return false
})
})
return notes
}
handleOptionClick (uniqueKey) {
return (e) => {
this.setState({
searchPopupOpen: false
}, () => {
let { location } = this.props
hashHistory.push({
pathname: location.pathname,
query: {
key: uniqueKey
}
})
})
}
}
handleSearchFocus (e) {
this.setState({
searchPopupOpen: true
})
}
handleSearchBlur (e) {
e.stopPropagation()
let el = e.relatedTarget
let isStillFocused = false
while (el != null) {
if (el === this.refs.search) {
isStillFocused = true
break
}
el = el.parentNode
}
if (!isStillFocused) {
this.setState({
searchPopupOpen: false
})
}
} }
render () { render () {
let { config, style } = this.props let { config, style, storages } = this.props
let searchOptionList = this.getOptions()
.map((note) => {
let storage = _.find(storages, {key: note.storage})
let folder = _.find(storage.folders, {key: note.folder})
return <div styleName='control-search-optionList-item'
key={note.uniqueKey}
onClick={(e) => this.handleOptionClick(note.uniqueKey)(e)}
>
<div styleName='control-search-optionList-item-folder'
style={{borderColor: folder.color}}>
{folder.name}
<span styleName='control-search-optionList-item-folder-surfix'>in {storage.name}</span>
</div>
{note.type === 'SNIPPET_NOTE'
? <i styleName='control-search-optionList-item-type' className='fa fa-code'/>
: <i styleName='control-search-optionList-item-type' className='fa fa-file-text-o'/>
}&nbsp;
{note.title}
</div>
})
return ( return (
<div className='TopBar' <div className='TopBar'
styleName={config.isSideNavFolded ? 'root--expanded' : 'root'} styleName={config.isSideNavFolded ? 'root--expanded' : 'root'}
@@ -64,16 +139,27 @@ class TopBar extends React.Component {
<div styleName='control'> <div styleName='control'>
<div styleName='control-search'> <div styleName='control-search'>
<i styleName='control-search-icon' className='fa fa-search fa-fw'/> <i styleName='control-search-icon' className='fa fa-search fa-fw'/>
<div styleName='control-search-input'> <div styleName='control-search-input'
onFocus={(e) => this.handleSearchFocus(e)}
onBlur={(e) => this.handleSearchBlur(e)}
tabIndex='-1'
ref='search'
>
<input <input
ref='searchInput' ref='searchInput'
onFocus={(e) => this.handleSearchChange(e)}
onBlur={(e) => this.handleSearchChange(e)}
value={this.state.search} value={this.state.search}
onChange={(e) => this.handleSearchChange(e)} onChange={(e) => this.handleSearchChange(e)}
placeholder='Search' placeholder='Search'
type='text' type='text'
/> />
{this.state.searchPopupOpen &&
<div styleName='control-search-optionList'>
{searchOptionList.length > 0
? searchOptionList
: <div styleName='control-search-optionList-empty'>Empty List</div>
}
</div>
}
</div> </div>
{this.state.search > 0 && {this.state.search > 0 &&
<button styleName='left-search-clearButton' <button styleName='left-search-clearButton'