From 5a26fc812d5b3fb865c6f6a906e0bfea0a8f06d0 Mon Sep 17 00:00:00 2001 From: Dick Choi Date: Sun, 29 May 2016 13:08:02 +0900 Subject: [PATCH] Star a note --- browser/lib/Repository.js | 24 ++++++++++- browser/main/Detail/NoteDetail.js | 44 +++++++++++++++++-- browser/main/Detail/NoteDetail.styl | 13 ++++++ browser/main/Detail/StarButton.js | 66 +++++++++++++++++++++++++++++ browser/main/Detail/StarButton.styl | 19 +++++++++ browser/main/NoteList/index.js | 15 +++++++ browser/main/store.js | 28 ++++++++++++ 7 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 browser/main/Detail/StarButton.js create mode 100644 browser/main/Detail/StarButton.styl 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 } }