diff --git a/browser/main/Detail/TagSelect.js b/browser/main/Detail/TagSelect.js
index c5221f66..e3d9a567 100644
--- a/browser/main/Detail/TagSelect.js
+++ b/browser/main/Detail/TagSelect.js
@@ -1,5 +1,6 @@
import PropTypes from 'prop-types'
import React from 'react'
+import invertColor from 'invert-color'
import CSSModules from 'browser/lib/CSSModules'
import styles from './TagSelect.styl'
import _ from 'lodash'
@@ -185,19 +186,34 @@ class TagSelect extends React.Component {
}
render () {
- const { value, className, showTagsAlphabetically } = this.props
+ const { value, className, showTagsAlphabetically, coloredTags } = this.props
const tagList = _.isArray(value)
? (showTagsAlphabetically ? _.sortBy(value) : value).map((tag) => {
+ const wrapperStyle = {}
+ const textStyle = {}
+ const BLACK = '#333333'
+ const WHITE = '#f1f1f1'
+ const color = coloredTags[tag]
+ const invertedColor = color && invertColor(color, { black: BLACK, white: WHITE })
+ let iconRemove = '../resources/icon/icon-x.svg'
+ if (color) {
+ wrapperStyle.backgroundColor = color
+ textStyle.color = invertedColor
+ }
+ if (invertedColor === WHITE) {
+ iconRemove = '../resources/icon/icon-x-light.svg'
+ }
return (
- this.handleTagLabelClick(tag)}>#{tag}
+ this.handleTagLabelClick(tag)}>#{tag}
)
@@ -246,7 +262,8 @@ TagSelect.contextTypes = {
TagSelect.propTypes = {
className: PropTypes.string,
value: PropTypes.arrayOf(PropTypes.string),
- onChange: PropTypes.func
+ onChange: PropTypes.func,
+ coloredTags: PropTypes.object
}
export default CSSModules(TagSelect, styles)
diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js
index dbc9cfd3..ca513c04 100644
--- a/browser/main/NoteList/index.js
+++ b/browser/main/NoteList/index.js
@@ -1047,6 +1047,7 @@ class NoteList extends React.Component {
storageName={this.getNoteStorage(note).name}
viewType={viewType}
showTagsAlphabetically={config.ui.showTagsAlphabetically}
+ coloredTags={config.coloredTags}
/>
)
}
diff --git a/browser/main/SideNav/index.js b/browser/main/SideNav/index.js
index b98d859d..640bedbf 100644
--- a/browser/main/SideNav/index.js
+++ b/browser/main/SideNav/index.js
@@ -20,6 +20,7 @@ import i18n from 'browser/lib/i18n'
import context from 'browser/lib/context'
import { remote } from 'electron'
import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote'
+import ColorPicker from 'browser/components/ColorPicker'
function matchActiveTags (tags, activeTags) {
return _.every(activeTags, v => tags.indexOf(v) >= 0)
@@ -27,6 +28,22 @@ function matchActiveTags (tags, activeTags) {
class SideNav extends React.Component {
// TODO: should not use electron stuff v0.7
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ colorPicker: {
+ show: false,
+ color: null,
+ tagName: null,
+ targetRect: null
+ }
+ }
+
+ this.dismissColorPicker = this.dismissColorPicker.bind(this)
+ this.handleColorPickerConfirm = this.handleColorPickerConfirm.bind(this)
+ this.handleColorPickerReset = this.handleColorPickerReset.bind(this)
+ }
componentDidMount () {
EventEmitter.on('side:preferences', this.handleMenuButtonClick)
@@ -104,9 +121,64 @@ class SideNav extends React.Component {
click: this.deleteTag.bind(this, tag)
})
+ menu.push({
+ label: i18n.__('Customize Color'),
+ click: this.displayColorPicker.bind(this, tag, e.target.getBoundingClientRect())
+ })
+
context.popup(menu)
}
+ dismissColorPicker () {
+ this.setState({
+ colorPicker: {
+ show: false
+ }
+ })
+ }
+
+ displayColorPicker (tagName, rect) {
+ const { config } = this.props
+ this.setState({
+ colorPicker: {
+ show: true,
+ color: config.coloredTags[tagName],
+ tagName,
+ targetRect: rect
+ }
+ })
+ }
+
+ handleColorPickerConfirm (color) {
+ const { dispatch, config: {coloredTags} } = this.props
+ const { colorPicker: { tagName } } = this.state
+ const newColoredTags = Object.assign({}, coloredTags, {[tagName]: color.hex})
+
+ const config = { coloredTags: newColoredTags }
+ ConfigManager.set(config)
+ dispatch({
+ type: 'SET_CONFIG',
+ config
+ })
+ this.dismissColorPicker()
+ }
+
+ handleColorPickerReset () {
+ const { dispatch, config: {coloredTags} } = this.props
+ const { colorPicker: { tagName } } = this.state
+ const newColoredTags = Object.assign({}, coloredTags)
+
+ delete newColoredTags[tagName]
+
+ const config = { coloredTags: newColoredTags }
+ ConfigManager.set(config)
+ dispatch({
+ type: 'SET_CONFIG',
+ config
+ })
+ this.dismissColorPicker()
+ }
+
handleToggleButtonClick (e) {
const { dispatch, config } = this.props
@@ -207,6 +279,7 @@ class SideNav extends React.Component {
tagListComponent () {
const { data, location, config } = this.props
+ const { colorPicker } = this.state
const activeTags = this.getActiveTags(location.pathname)
const relatedTags = this.getRelatedTags(activeTags, data.noteMap)
let tagList = _.sortBy(data.tagNoteMap.map(
@@ -237,10 +310,11 @@ class SideNav extends React.Component {
handleClickTagListItem={this.handleClickTagListItem.bind(this)}
handleClickNarrowToTag={this.handleClickNarrowToTag.bind(this)}
handleContextMenu={this.handleTagContextMenu.bind(this)}
- isActive={this.getTagActive(location.pathname, tag.name)}
+ isActive={this.getTagActive(location.pathname, tag.name) || (colorPicker.tagName === tag.name)}
isRelated={tag.related}
key={tag.name}
count={tag.size}
+ color={config.coloredTags[tag.name]}
/>
)
})
@@ -333,6 +407,7 @@ class SideNav extends React.Component {
render () {
const { data, location, config, dispatch } = this.props
+ const { colorPicker: colorPickerState } = this.state
const isFolded = config.isSideNavFolded
@@ -349,6 +424,20 @@ class SideNav extends React.Component {
useDragHandle
/>
})
+
+ let colorPicker
+ if (colorPickerState.show) {
+ colorPicker = (
+
+ )
+ }
+
const style = {}
if (!isFolded) style.width = this.props.width
const isTagActive = location.pathname.match(/tag/)
@@ -368,6 +457,7 @@ class SideNav extends React.Component {