diff --git a/browser/lib/Repository.js b/browser/lib/Repository.js
index a3c0edc2..6a47b101 100644
--- a/browser/lib/Repository.js
+++ b/browser/lib/Repository.js
@@ -441,6 +441,27 @@ class Repository {
})
}
+ starNote (noteKey) {
+ let note = _.find(this.notes, {key: noteKey})
+ if (note != null) {
+ let json = this.json
+ json.starred.push(noteKey)
+
+ return this.saveJSON(json)
+ }
+ }
+
+ unstarNote (noteKey) {
+ let note = _.find(this.notes, {key: noteKey})
+ if (note != null) {
+ let json = this.json
+ json.starred = json.starred
+ .filter((starredKey) => starredKey !== noteKey)
+
+ return this.saveJSON(json)
+ }
+ }
+
removeNote (noteKey) {
let noteIndex = _.findIndex(this.notes, {key: noteKey})
@@ -473,7 +494,8 @@ class Repository {
key: keygen(),
name: 'general',
color: this.randomColor()
- }]
+ }],
+ starred: []
}, override)
}
diff --git a/browser/main/Detail/NoteDetail.js b/browser/main/Detail/NoteDetail.js
index b6b1a737..ebce7262 100644
--- a/browser/main/Detail/NoteDetail.js
+++ b/browser/main/Detail/NoteDetail.js
@@ -3,7 +3,9 @@ import CSSModules from 'browser/lib/CSSModules'
import styles from './NoteDetail.styl'
import MarkdownEditor from 'browser/components/MarkdownEditor'
import queue from 'browser/main/lib/queue'
+import StarButton from './StarButton'
import TagSelect from './TagSelect'
+import Repository from 'browser/lib/Repository'
class NoteDetail extends React.Component {
constructor (props) {
@@ -106,7 +108,42 @@ class NoteDetail extends React.Component {
queue.save(repoKey, note)
}
+ handleStarButtonClick (e) {
+ let { note } = this.state
+ let { dispatch } = this.props
+ let isStarred = note._repository.starred.some((starredKey) => starredKey === note.key)
+
+ if (isStarred) {
+ Repository
+ .find(note._repository.key)
+ .then((repo) => {
+ return repo.unstarNote(note.key)
+ })
+
+ dispatch({
+ type: 'UNSTAR_NOTE',
+ repository: note._repository.key,
+ note: note.key
+ })
+ } else {
+ Repository
+ .find(note._repository.key)
+ .then((repo) => {
+ return repo.starNote(note.key)
+ })
+
+ dispatch({
+ type: 'STAR_NOTE',
+ repository: note._repository.key,
+ note: note.key
+ })
+ }
+ }
+
render () {
+ let { note } = this.state
+ let isStarred = note._repository.starred.some((starredKey) => starredKey === note.key)
+
return (
-
+
this.handleStarButtonClick(e)}
+ isActive={isStarred}
+ />
FolderSelect
diff --git a/browser/main/Detail/NoteDetail.styl b/browser/main/Detail/NoteDetail.styl
index 5a6d6430..7d424c6b 100644
--- a/browser/main/Detail/NoteDetail.styl
+++ b/browser/main/Detail/NoteDetail.styl
@@ -18,6 +18,19 @@ $info-height = 80px
.info-left-top
height 40px
+.info-left-top-starButton
+ display inline-block
+ height 40px
+ width 40px
+ line-height 40px
+ vertical-align top
+
+.info-left-top-folderSelect
+ display inline-block
+ height 40px
+ width 100px
+ vertical-align top
+
.info-left-bottom
height 40px
diff --git a/browser/main/Detail/StarButton.js b/browser/main/Detail/StarButton.js
new file mode 100644
index 00000000..e3f98a97
--- /dev/null
+++ b/browser/main/Detail/StarButton.js
@@ -0,0 +1,66 @@
+import React, { PropTypes } from 'react'
+import CSSModules from 'browser/lib/CSSModules'
+import styles from './StarButton.styl'
+import _ from 'lodash'
+
+class StarButton extends React.Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ isActive: false
+ }
+ }
+
+ handleMouseDown (e) {
+ this.setState({
+ isActive: true
+ })
+ }
+
+ handleMouseUp (e) {
+ this.setState({
+ isActive: false
+ })
+ }
+
+ handleMouseLeave (e) {
+ this.setState({
+ isActive: false
+ })
+ }
+
+ render () {
+ let { className } = this.props
+
+ return (
+
+ )
+ }
+}
+
+StarButton.propTypes = {
+ isActive: PropTypes.bool,
+ onClick: PropTypes.func,
+ className: PropTypes.string
+}
+
+export default CSSModules(StarButton, styles)
diff --git a/browser/main/Detail/StarButton.styl b/browser/main/Detail/StarButton.styl
new file mode 100644
index 00000000..acd92035
--- /dev/null
+++ b/browser/main/Detail/StarButton.styl
@@ -0,0 +1,19 @@
+.root
+ position relative
+ color $ui-inactive-text-color
+ font-size 18px
+ text-align center
+ background-color transparent
+ border none
+ padding 0
+ transition transform 0.15s
+ &:hover
+ color $ui-text-color
+ transform rotate(-72deg)
+
+.root--active
+ @extend .root
+ color $ui-active-color
+ transform rotate(-72deg)
+ &:hover
+ color $ui-active-color
diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js
index 82da69d7..15988da5 100644
--- a/browser/main/NoteList/index.js
+++ b/browser/main/NoteList/index.js
@@ -136,6 +136,21 @@ class NoteList extends React.Component {
}, [])
}
+ if (location.pathname.match(/\/starred/)) {
+ return repositories
+ .reduce((sum, repository) => {
+ return sum.concat(repository.starred
+ .map((starredKey) => {
+ return _.find(repository.notes, {key: starredKey})
+ })
+ .filter((note) => _.isObject(note))
+ .map((note) => {
+ note._repository = repository
+ return note
+ }))
+ }, [])
+ }
+
let repository = _.find(repositories, {key: repositoryKey})
if (repository == null) return []
diff --git a/browser/main/store.js b/browser/main/store.js
index cc4194a4..3eba7c04 100644
--- a/browser/main/store.js
+++ b/browser/main/store.js
@@ -132,6 +132,34 @@ function repositories (state = initialRepositories, action) {
targetRepo.notes.push(action.note)
}
+ return repos
+ }
+ case 'STAR_NOTE':
+ {
+ let repos = state.slice()
+ let targetRepo = _.find(repos, {key: action.repository})
+
+ if (targetRepo == null) return state
+
+ let targetNoteIndex = _.findIndex(targetRepo.notes, {key: action.note})
+ if (targetNoteIndex > -1) {
+ targetRepo.starred.push(action.note)
+ } else {
+ return state
+ }
+
+ return repos
+ }
+ case 'UNSTAR_NOTE':
+ {
+ let repos = state.slice()
+ let targetRepo = _.find(repos, {key: action.repository})
+
+ if (targetRepo == null) return state
+
+ targetRepo.starred = targetRepo.starred
+ .filter((starredKey) => starredKey !== action.note)
+
return repos
}
}