mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 09:46:22 +00:00
handle new note button & note list
This commit is contained in:
@@ -1,52 +0,0 @@
|
|||||||
import React, { PropTypes } from 'react'
|
|
||||||
|
|
||||||
const BLUE = '#3460C7'
|
|
||||||
const LIGHTBLUE = '#2BA5F7'
|
|
||||||
const ORANGE = '#FF8E00'
|
|
||||||
const YELLOW = '#E8D252'
|
|
||||||
const GREEN = '#3FD941'
|
|
||||||
const DARKGREEN = '#1FAD85'
|
|
||||||
const RED = '#E10051'
|
|
||||||
const PURPLE = '#B013A4'
|
|
||||||
|
|
||||||
function getColorByIndex (index) {
|
|
||||||
switch (index % 8) {
|
|
||||||
case 0:
|
|
||||||
return RED
|
|
||||||
case 1:
|
|
||||||
return ORANGE
|
|
||||||
case 2:
|
|
||||||
return YELLOW
|
|
||||||
case 3:
|
|
||||||
return GREEN
|
|
||||||
case 4:
|
|
||||||
return DARKGREEN
|
|
||||||
case 5:
|
|
||||||
return LIGHTBLUE
|
|
||||||
case 6:
|
|
||||||
return BLUE
|
|
||||||
case 7:
|
|
||||||
return PURPLE
|
|
||||||
default:
|
|
||||||
return DARKGREEN
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class FolderMark extends React.Component {
|
|
||||||
render () {
|
|
||||||
let color = getColorByIndex(this.props.color)
|
|
||||||
let className = 'FolderMark fa fa-square fa-fw'
|
|
||||||
if (this.props.className != null) {
|
|
||||||
className += ' active'
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<i className={className} style={{color: color}}/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FolderMark.propTypes = {
|
|
||||||
color: PropTypes.number,
|
|
||||||
className: PropTypes.string
|
|
||||||
}
|
|
||||||
@@ -87,7 +87,6 @@ let repositories = []
|
|||||||
* ##### `note.cson`
|
* ##### `note.cson`
|
||||||
*
|
*
|
||||||
* ```cson
|
* ```cson
|
||||||
* name: String
|
|
||||||
* tags: [String] // tags
|
* tags: [String] // tags
|
||||||
* folder: String // hash key of folder
|
* folder: String // hash key of folder
|
||||||
* mode: String // syntax mode
|
* mode: String // syntax mode
|
||||||
@@ -151,7 +150,7 @@ class Repository {
|
|||||||
let noteNames = fs.readdirSync(dataPath)
|
let noteNames = fs.readdirSync(dataPath)
|
||||||
let notes = noteNames
|
let notes = noteNames
|
||||||
.map((noteName) => {
|
.map((noteName) => {
|
||||||
let notePath = path.join(dataPath, noteNames)
|
let notePath = path.join(dataPath, noteName)
|
||||||
|
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
CSON.readFile(notePath, function (err, obj) {
|
CSON.readFile(notePath, function (err, obj) {
|
||||||
@@ -218,7 +217,9 @@ class Repository {
|
|||||||
this.isMount = true
|
this.isMount = true
|
||||||
|
|
||||||
// Put in `repositories` array if it isn't in.
|
// Put in `repositories` array if it isn't in.
|
||||||
let targetIndex = _.findIndex(repositories, {cached: {key: this.cached.key}})
|
let targetIndex = _.findIndex(repositories, (repo) => {
|
||||||
|
this.cached.key === repo.cached.key
|
||||||
|
})
|
||||||
if (targetIndex < 0) {
|
if (targetIndex < 0) {
|
||||||
repositories.push(this)
|
repositories.push(this)
|
||||||
}
|
}
|
||||||
@@ -241,7 +242,9 @@ class Repository {
|
|||||||
this.isMount = false
|
this.isMount = false
|
||||||
|
|
||||||
// Discard from `repositories` array if it is in.
|
// Discard from `repositories` array if it is in.
|
||||||
let targetIndex = _.findIndex(repositories, {cached: {key: this.cached.key}})
|
let targetIndex = _.findIndex(repositories, (repo) => {
|
||||||
|
this.cached.key === repo.cached.key
|
||||||
|
})
|
||||||
if (targetIndex > -1) {
|
if (targetIndex > -1) {
|
||||||
repositories.splice(targetIndex, 1)
|
repositories.splice(targetIndex, 1)
|
||||||
}
|
}
|
||||||
@@ -586,6 +589,7 @@ class Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static saveAllCached (allCached) {
|
static saveAllCached (allCached) {
|
||||||
|
console.info('cach updated > ', allCached)
|
||||||
localStorage.setItem('repositories', JSON.stringify(allCached))
|
localStorage.setItem('repositories', JSON.stringify(allCached))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,18 +84,35 @@ class Main extends React.Component {
|
|||||||
<SideNav
|
<SideNav
|
||||||
{..._.pick(this.props, ['dispatch', 'repositories', 'config', 'location'])}
|
{..._.pick(this.props, ['dispatch', 'repositories', 'config', 'location'])}
|
||||||
/>
|
/>
|
||||||
<TopBar/>
|
<TopBar
|
||||||
|
{..._.pick(this.props, [
|
||||||
|
'dispatch',
|
||||||
|
'repositories',
|
||||||
|
'config',
|
||||||
|
'params'
|
||||||
|
])}
|
||||||
|
/>
|
||||||
<div styleName={config.isSideNavFolded ? 'body--expanded' : 'body'}
|
<div styleName={config.isSideNavFolded ? 'body--expanded' : 'body'}
|
||||||
ref='body'
|
ref='body'
|
||||||
>
|
>
|
||||||
<NoteList style={{width: this.state.listWidth}}/>
|
<NoteList style={{width: this.state.listWidth}}
|
||||||
|
{..._.pick(this.props, [
|
||||||
|
'dispatch',
|
||||||
|
'repositories',
|
||||||
|
'config',
|
||||||
|
'params',
|
||||||
|
'location'
|
||||||
|
])}
|
||||||
|
/>
|
||||||
<div styleName={this.state.isSliderFocused ? 'slider--active' : 'slider'}
|
<div styleName={this.state.isSliderFocused ? 'slider--active' : 'slider'}
|
||||||
style={{left: this.state.listWidth}}
|
style={{left: this.state.listWidth}}
|
||||||
onMouseDown={(e) => this.handleSlideMouseDown(e)}
|
onMouseDown={(e) => this.handleSlideMouseDown(e)}
|
||||||
draggable='false'
|
draggable='false'
|
||||||
/>
|
>
|
||||||
|
<div styleName='slider-hitbox'/>
|
||||||
|
</div>
|
||||||
<NoteDetail
|
<NoteDetail
|
||||||
style={{left: this.state.listWidth + 5}}
|
style={{left: this.state.listWidth + 1}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<StatusBar
|
<StatusBar
|
||||||
|
|||||||
@@ -13,13 +13,18 @@
|
|||||||
|
|
||||||
.slider
|
.slider
|
||||||
absolute top bottom
|
absolute top bottom
|
||||||
width 5px
|
width 1px
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-borderColor
|
||||||
border-width 0 1px 0
|
border-width 0
|
||||||
border-style solid
|
border-style solid
|
||||||
border-color $ui-borderColor
|
border-color $ui-borderColor
|
||||||
cursor ew-resize
|
cursor col-resize
|
||||||
|
|
||||||
.slider--active
|
.slider--active
|
||||||
@extend .slider
|
@extend .slider
|
||||||
background-color $ui-button--active-backgroundColor
|
background-color $ui-button--active-backgroundColor
|
||||||
|
|
||||||
|
.slider-hitbox
|
||||||
|
absolute top bottom left right
|
||||||
|
width 7px
|
||||||
|
left -3px
|
||||||
|
|||||||
@@ -2,3 +2,36 @@
|
|||||||
absolute top left bottom
|
absolute top left bottom
|
||||||
border-top $ui-border
|
border-top $ui-border
|
||||||
border-bottom $ui-border
|
border-bottom $ui-border
|
||||||
|
overflow auto
|
||||||
|
|
||||||
|
.item
|
||||||
|
height 80px
|
||||||
|
border-bottom $ui-border
|
||||||
|
padding 0 5px
|
||||||
|
user-select none
|
||||||
|
cursor pointer
|
||||||
|
&:hover
|
||||||
|
background-color alpha(black, 5%)
|
||||||
|
|
||||||
|
.item-info
|
||||||
|
height 30px
|
||||||
|
clearfix()
|
||||||
|
font-size 12px
|
||||||
|
line-height 30px
|
||||||
|
|
||||||
|
.item-info-left
|
||||||
|
float left
|
||||||
|
|
||||||
|
.item-info-right
|
||||||
|
float right
|
||||||
|
|
||||||
|
.item-title
|
||||||
|
height 20px
|
||||||
|
line-height 20px
|
||||||
|
font-weight bold
|
||||||
|
overflow ellipsis
|
||||||
|
|
||||||
|
.item-tags
|
||||||
|
height 30px
|
||||||
|
font-size 12px
|
||||||
|
line-height 30px
|
||||||
|
|||||||
@@ -123,8 +123,81 @@ class NoteList extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNotes () {
|
||||||
|
let { repositories, params, location } = this.props
|
||||||
|
let repositoryKey = params.repositoryKey
|
||||||
|
let folderKey = params.folderKey
|
||||||
|
|
||||||
|
if (location.pathname.match(/\/home/)) {
|
||||||
|
return repositories
|
||||||
|
.reduce((sum, repository) => {
|
||||||
|
return sum.concat(repository.notes
|
||||||
|
.map((note) => {
|
||||||
|
note._repository = repository
|
||||||
|
return note
|
||||||
|
}))
|
||||||
|
}, [])
|
||||||
|
}
|
||||||
|
|
||||||
|
let repository = _.find(repositories, {key: repositoryKey})
|
||||||
|
if (repository == null) return []
|
||||||
|
|
||||||
|
let folder = _.find(repository.folders, {key: folderKey})
|
||||||
|
if (folder == null) {
|
||||||
|
return repository.notes
|
||||||
|
.map((note) => {
|
||||||
|
note._repository = repository
|
||||||
|
return note
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return repository.notes
|
||||||
|
.filter((note) => note.folder === folderKey)
|
||||||
|
.map((note) => {
|
||||||
|
note._repository = repository
|
||||||
|
return note
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNoteClick (key) {
|
||||||
|
return (e) => {
|
||||||
|
console.log(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
let articleElements = []
|
let notes = this.getNotes()
|
||||||
|
let noteElements = notes.map((note) => {
|
||||||
|
let folder = _.find(note._repository.folders, {key: note.folder})
|
||||||
|
let tagElements = note.tags.map((tag) => {
|
||||||
|
return <span key='tag'>{tag}</span>
|
||||||
|
})
|
||||||
|
let key = `${note._repository.key}/${note.key}`
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div styleName='item'
|
||||||
|
key={key}
|
||||||
|
onClick={(e) => this.handleNoteClick(key)(e)}
|
||||||
|
>
|
||||||
|
<div styleName='item-info'>
|
||||||
|
|
||||||
|
<div styleName='item-info-left'>
|
||||||
|
<i className='fa fa-cube fa-fw' style={{color: folder.color}}/> {folder.name}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div styleName='item-info-right'>
|
||||||
|
{moment(note.createdAt).fromNow()}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div styleName='item-title'>{note.title}</div>
|
||||||
|
|
||||||
|
<div styleName='item-tags'><i className='fa fa-tags fa-fw'/>{tagElements.length > 0 ? tagElements : <span>Not tagged yet</span>}</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='NoteList'
|
<div className='NoteList'
|
||||||
@@ -133,11 +206,14 @@ class NoteList extends React.Component {
|
|||||||
onKeyDown={(e) => this.handleNoteListKeyDown(e)}
|
onKeyDown={(e) => this.handleNoteListKeyDown(e)}
|
||||||
style={this.props.style}
|
style={this.props.style}
|
||||||
>
|
>
|
||||||
{articleElements}
|
{noteElements}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NoteList.contextTypes = {
|
||||||
|
router: PropTypes.shape([])
|
||||||
|
}
|
||||||
|
|
||||||
NoteList.propTypes = {
|
NoteList.propTypes = {
|
||||||
dispatch: PropTypes.func,
|
dispatch: PropTypes.func,
|
||||||
|
|||||||
@@ -61,6 +61,8 @@
|
|||||||
border-radius 5px
|
border-radius 5px
|
||||||
border $ui-border
|
border $ui-border
|
||||||
outline none
|
outline none
|
||||||
|
background-color white
|
||||||
|
z-index 1
|
||||||
&:focus
|
&:focus
|
||||||
border-color $ui-input--focus-borderColor
|
border-color $ui-input--focus-borderColor
|
||||||
&:disabled
|
&:disabled
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from 'react'
|
||||||
import { connect } from 'react-redux'
|
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './TopBar.styl'
|
import styles from './TopBar.styl'
|
||||||
import activityRecord from 'browser/lib/activityRecord'
|
import activityRecord from 'browser/lib/activityRecord'
|
||||||
|
import Repository from 'browser/lib/Repository'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
const OSX = window.process.platform === 'darwin'
|
const OSX = window.process.platform === 'darwin'
|
||||||
|
|
||||||
@@ -30,23 +31,56 @@ class TopBar extends React.Component {
|
|||||||
this.searchInput.blur()
|
this.searchInput.blur()
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSearchChange (e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSearchClearButton (e) {
|
|
||||||
this.searchInput.value = ''
|
|
||||||
this.focusInput()
|
|
||||||
}
|
|
||||||
|
|
||||||
handleNewPostButtonClick (e) {
|
handleNewPostButtonClick (e) {
|
||||||
activityRecord.emit('ARTICLE_CREATE')
|
activityRecord.emit('ARTICLE_CREATE')
|
||||||
|
|
||||||
|
let { params, repositories } = this.props
|
||||||
|
|
||||||
|
let folderKey = params.folderKey
|
||||||
|
let repositoryKey = params.repositoryKey
|
||||||
|
if (folderKey == null) {
|
||||||
|
let repository = _.find(repositories, {key: repositoryKey})
|
||||||
|
if (repository == null) {
|
||||||
|
repository = repositories[0]
|
||||||
|
}
|
||||||
|
if (repository != null) {
|
||||||
|
repositoryKey = repository.key
|
||||||
|
folderKey = repository.folders[0] != null && repository.folders[0].key
|
||||||
|
}
|
||||||
|
if (folderKey == null) throw new Error('no folder exists')
|
||||||
|
}
|
||||||
|
|
||||||
|
let newNote = {
|
||||||
|
title: 'New Note',
|
||||||
|
content: '',
|
||||||
|
folder: folderKey,
|
||||||
|
tags: [],
|
||||||
|
mode: 'markdown'
|
||||||
|
}
|
||||||
|
|
||||||
|
Repository
|
||||||
|
.find(repositoryKey)
|
||||||
|
.then((repo) => {
|
||||||
|
console.log(repo)
|
||||||
|
return repo.addNote(newNote)
|
||||||
|
})
|
||||||
|
.then((note) => {
|
||||||
|
let { dispatch } = this.props
|
||||||
|
dispatch({
|
||||||
|
type: 'ADD_NOTE',
|
||||||
|
repository: repositoryKey,
|
||||||
|
note: note
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTutorialButtonClick (e) {
|
handleTutorialButtonClick (e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLinksButton (e) {
|
handleLinksButton (e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@@ -112,4 +146,4 @@ TopBar.propTypes = {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect((x) => x)(CSSModules(TopBar, styles))
|
export default CSSModules(TopBar, styles)
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ ipc.on('open-finder', function () {
|
|||||||
|
|
||||||
let el = document.getElementById('content')
|
let el = document.getElementById('content')
|
||||||
const history = syncHistoryWithStore(hashHistory, store)
|
const history = syncHistoryWithStore(hashHistory, store)
|
||||||
history.listen((location) => console.info(location))
|
|
||||||
ReactDOM.render((
|
ReactDOM.render((
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<Router history={history}>
|
<Router history={history}>
|
||||||
|
|||||||
@@ -105,6 +105,16 @@ function repositories (state = initialRepositories, action) {
|
|||||||
targetRepo.folders.splice(targetFolderIndex, 1)
|
targetRepo.folders.splice(targetFolderIndex, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return repos
|
||||||
|
}
|
||||||
|
case 'ADD_NOTE':
|
||||||
|
{
|
||||||
|
let repos = state.slice()
|
||||||
|
let targetRepo = _.find(repos, {key: action.repository})
|
||||||
|
|
||||||
|
if (targetRepo == null) return state
|
||||||
|
targetRepo.notes.push(action.note)
|
||||||
|
|
||||||
return repos
|
return repos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
index.js
2
index.js
@@ -1,6 +1,6 @@
|
|||||||
function isFinderCalled () {
|
function isFinderCalled () {
|
||||||
var argv = process.argv.slice(1)
|
var argv = process.argv.slice(1)
|
||||||
return argv.some(arg => arg.match(/--finder/))
|
return argv.some((arg) => arg.match(/--finder/))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFinderCalled()) {
|
if (isFinderCalled()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user