mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-15 02:36:36 +00:00
Merge branch 'master' into filter-tags-and-folders
# Conflicts: # browser/main/SideNav/index.js
This commit is contained in:
@@ -17,7 +17,7 @@ import PreferenceButton from './PreferenceButton'
|
||||
import SearchButton from './SearchButton'
|
||||
import ListButton from './ListButton'
|
||||
import TagButton from './TagButton'
|
||||
import {SortableContainer} from 'react-sortable-hoc'
|
||||
import { SortableContainer } from 'react-sortable-hoc'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
import context from 'browser/lib/context'
|
||||
import { remote } from 'electron'
|
||||
@@ -25,13 +25,13 @@ import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote'
|
||||
import ColorPicker from 'browser/components/ColorPicker'
|
||||
import { every, sortBy } from 'lodash'
|
||||
|
||||
function matchActiveTags (tags, activeTags) {
|
||||
function matchActiveTags(tags, activeTags) {
|
||||
return every(activeTags, v => tags.indexOf(v) >= 0)
|
||||
}
|
||||
|
||||
class SideNav extends React.Component {
|
||||
// TODO: should not use electron stuff v0.7
|
||||
constructor (props) {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
@@ -53,24 +53,32 @@ class SideNav extends React.Component {
|
||||
this.handleSearchInputClear = this.handleSearchInputClear.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
EventEmitter.on('side:preferences', this.handlePreferenceButtonClick)
|
||||
componentDidMount() {
|
||||
EventEmitter.on('side:preferences', this.handleMenuButtonClick)
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
EventEmitter.off('side:preferences', this.handlePreferenceButtonClick)
|
||||
componentWillUnmount() {
|
||||
EventEmitter.off('side:preferences', this.handleMenuButtonClick)
|
||||
}
|
||||
|
||||
deleteTag (tag) {
|
||||
const selectedButton = remote.dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||
type: 'warning',
|
||||
message: i18n.__('Confirm tag deletion'),
|
||||
detail: i18n.__('This will permanently remove this tag.'),
|
||||
buttons: [i18n.__('Confirm'), i18n.__('Cancel')]
|
||||
})
|
||||
deleteTag(tag) {
|
||||
const selectedButton = remote.dialog.showMessageBox(
|
||||
remote.getCurrentWindow(),
|
||||
{
|
||||
type: 'warning',
|
||||
message: i18n.__('Confirm tag deletion'),
|
||||
detail: i18n.__('This will permanently remove this tag.'),
|
||||
buttons: [i18n.__('Confirm'), i18n.__('Cancel')]
|
||||
}
|
||||
)
|
||||
|
||||
if (selectedButton === 0) {
|
||||
const { data, dispatch, location, match: { params } } = this.props
|
||||
const {
|
||||
data,
|
||||
dispatch,
|
||||
location,
|
||||
match: { params }
|
||||
} = this.props
|
||||
|
||||
const notes = data.noteMap
|
||||
.map(note => note)
|
||||
@@ -84,34 +92,38 @@ class SideNav extends React.Component {
|
||||
return note
|
||||
})
|
||||
|
||||
Promise
|
||||
.all(notes.map(note => dataApi.updateNote(note.storage, note.key, note)))
|
||||
.then(updatedNotes => {
|
||||
updatedNotes.forEach(note => {
|
||||
dispatch({
|
||||
type: 'UPDATE_NOTE',
|
||||
note
|
||||
})
|
||||
Promise.all(
|
||||
notes.map(note => dataApi.updateNote(note.storage, note.key, note))
|
||||
).then(updatedNotes => {
|
||||
updatedNotes.forEach(note => {
|
||||
dispatch({
|
||||
type: 'UPDATE_NOTE',
|
||||
note
|
||||
})
|
||||
|
||||
if (location.pathname.match('/tags')) {
|
||||
const tags = params.tagname.split(' ')
|
||||
const index = tags.indexOf(tag)
|
||||
if (index !== -1) {
|
||||
tags.splice(index, 1)
|
||||
|
||||
dispatch(push(`/tags/${tags.map(tag => encodeURIComponent(tag)).join(' ')}`))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (location.pathname.match('/tags')) {
|
||||
const tags = params.tagname.split(' ')
|
||||
const index = tags.indexOf(tag)
|
||||
if (index !== -1) {
|
||||
tags.splice(index, 1)
|
||||
|
||||
dispatch(
|
||||
push(
|
||||
`/tags/${tags.map(tag => encodeURIComponent(tag)).join(' ')}`
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handlePreferenceButtonClick (e) {
|
||||
handleMenuButtonClick(e) {
|
||||
openModal(PreferencesModal)
|
||||
}
|
||||
|
||||
handleSearchButtonClick (e) {
|
||||
handleSearchButtonClick(e) {
|
||||
const { showSearch } = this.state
|
||||
this.setState({
|
||||
showSearch: !showSearch,
|
||||
@@ -119,29 +131,29 @@ class SideNav extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
handleSearchInputClear (e) {
|
||||
handleSearchInputClear(e) {
|
||||
this.setState({
|
||||
searchText: ''
|
||||
})
|
||||
}
|
||||
|
||||
handleSearchInputChange (e) {
|
||||
handleSearchInputChange(e) {
|
||||
this.setState({
|
||||
searchText: e.target.value
|
||||
})
|
||||
}
|
||||
|
||||
handleHomeButtonClick (e) {
|
||||
handleHomeButtonClick(e) {
|
||||
const { dispatch } = this.props
|
||||
dispatch(push('/home'))
|
||||
}
|
||||
|
||||
handleStarredButtonClick (e) {
|
||||
handleStarredButtonClick(e) {
|
||||
const { dispatch } = this.props
|
||||
dispatch(push('/starred'))
|
||||
}
|
||||
|
||||
handleTagContextMenu (e, tag) {
|
||||
handleTagContextMenu(e, tag) {
|
||||
const menu = []
|
||||
|
||||
menu.push({
|
||||
@@ -151,13 +163,17 @@ class SideNav extends React.Component {
|
||||
|
||||
menu.push({
|
||||
label: i18n.__('Customize Color'),
|
||||
click: this.displayColorPicker.bind(this, tag, e.target.getBoundingClientRect())
|
||||
click: this.displayColorPicker.bind(
|
||||
this,
|
||||
tag,
|
||||
e.target.getBoundingClientRect()
|
||||
)
|
||||
})
|
||||
|
||||
context.popup(menu)
|
||||
}
|
||||
|
||||
dismissColorPicker () {
|
||||
dismissColorPicker() {
|
||||
this.setState({
|
||||
colorPicker: {
|
||||
show: false
|
||||
@@ -165,7 +181,7 @@ class SideNav extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
displayColorPicker (tagName, rect) {
|
||||
displayColorPicker(tagName, rect) {
|
||||
const { config } = this.props
|
||||
this.setState({
|
||||
colorPicker: {
|
||||
@@ -177,10 +193,17 @@ class SideNav extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
handleColorPickerConfirm (color) {
|
||||
const { dispatch, config: {coloredTags} } = this.props
|
||||
const { colorPicker: { tagName } } = this.state
|
||||
const newColoredTags = Object.assign({}, coloredTags, {[tagName]: color.hex})
|
||||
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)
|
||||
@@ -191,9 +214,14 @@ class SideNav extends React.Component {
|
||||
this.dismissColorPicker()
|
||||
}
|
||||
|
||||
handleColorPickerReset () {
|
||||
const { dispatch, config: {coloredTags} } = this.props
|
||||
const { colorPicker: { tagName } } = this.state
|
||||
handleColorPickerReset() {
|
||||
const {
|
||||
dispatch,
|
||||
config: { coloredTags }
|
||||
} = this.props
|
||||
const {
|
||||
colorPicker: { tagName }
|
||||
} = this.state
|
||||
const newColoredTags = Object.assign({}, coloredTags)
|
||||
|
||||
delete newColoredTags[tagName]
|
||||
@@ -207,11 +235,11 @@ class SideNav extends React.Component {
|
||||
this.dismissColorPicker()
|
||||
}
|
||||
|
||||
handleToggleButtonClick (e) {
|
||||
handleToggleButtonClick(e) {
|
||||
const { dispatch, config } = this.props
|
||||
const { showSearch, searchText } = this.state
|
||||
|
||||
ConfigManager.set({isSideNavFolded: !config.isSideNavFolded})
|
||||
ConfigManager.set({ isSideNavFolded: !config.isSideNavFolded })
|
||||
dispatch({
|
||||
type: 'SET_IS_SIDENAV_FOLDED',
|
||||
isFolded: !config.isSideNavFolded
|
||||
@@ -224,33 +252,31 @@ class SideNav extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleTrashedButtonClick (e) {
|
||||
handleTrashedButtonClick(e) {
|
||||
const { dispatch } = this.props
|
||||
dispatch(push('/trashed'))
|
||||
}
|
||||
|
||||
handleSwitchFoldersButtonClick () {
|
||||
handleSwitchFoldersButtonClick() {
|
||||
const { dispatch } = this.props
|
||||
dispatch(push('/home'))
|
||||
}
|
||||
|
||||
handleSwitchTagsButtonClick () {
|
||||
handleSwitchTagsButtonClick() {
|
||||
const { dispatch } = this.props
|
||||
dispatch(push('/alltags'))
|
||||
}
|
||||
|
||||
onSortEnd (storage) {
|
||||
return ({oldIndex, newIndex}) => {
|
||||
onSortEnd(storage) {
|
||||
return ({ oldIndex, newIndex }) => {
|
||||
const { dispatch } = this.props
|
||||
dataApi
|
||||
.reorderFolder(storage.key, oldIndex, newIndex)
|
||||
.then((data) => {
|
||||
dispatch({ type: 'REORDER_FOLDER', storage: data.storage })
|
||||
})
|
||||
dataApi.reorderFolder(storage.key, oldIndex, newIndex).then(data => {
|
||||
dispatch({ type: 'REORDER_FOLDER', storage: data.storage })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
SideNavComponent (isFolded) {
|
||||
SideNavComponent(isFolded) {
|
||||
const { location, data, config, dispatch } = this.props
|
||||
const { showSearch, searchText } = this.state
|
||||
|
||||
@@ -261,27 +287,35 @@ class SideNav extends React.Component {
|
||||
let component
|
||||
|
||||
// TagsMode is not selected
|
||||
if (!location.pathname.match('/tags') && !location.pathname.match('/alltags')) {
|
||||
if (
|
||||
!location.pathname.match('/tags') &&
|
||||
!location.pathname.match('/alltags')
|
||||
) {
|
||||
let storageMap = data.storageMap
|
||||
if (showSearch && searchText.length > 0) {
|
||||
storageMap = storageMap.map((storage) => {
|
||||
const folders = storage.folders.filter(folder => folder.name.toLowerCase().indexOf(searchText.toLowerCase()) !== -1)
|
||||
storageMap = storageMap.map(storage => {
|
||||
const folders = storage.folders.filter(
|
||||
folder =>
|
||||
folder.name.toLowerCase().indexOf(searchText.toLowerCase()) !== -1
|
||||
)
|
||||
return Object.assign({}, storage, { folders })
|
||||
})
|
||||
}
|
||||
|
||||
const storageList = storageMap.map((storage, key) => {
|
||||
const SortableStorageItem = SortableContainer(StorageItem)
|
||||
return <SortableStorageItem
|
||||
key={storage.key}
|
||||
storage={storage}
|
||||
data={data}
|
||||
location={location}
|
||||
isFolded={isFolded}
|
||||
dispatch={dispatch}
|
||||
onSortEnd={this.onSortEnd.bind(this)(storage)}
|
||||
useDragHandle
|
||||
/>
|
||||
return (
|
||||
<SortableStorageItem
|
||||
key={storage.key}
|
||||
storage={storage}
|
||||
data={data}
|
||||
location={location}
|
||||
isFolded={isFolded}
|
||||
dispatch={dispatch}
|
||||
onSortEnd={this.onSortEnd.bind(this)(storage)}
|
||||
useDragHandle
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
component = (
|
||||
@@ -289,19 +323,26 @@ class SideNav extends React.Component {
|
||||
<SideNavFilter
|
||||
isFolded={isFolded}
|
||||
isHomeActive={isHomeActive}
|
||||
handleAllNotesButtonClick={(e) => this.handleHomeButtonClick(e)}
|
||||
handleAllNotesButtonClick={e => this.handleHomeButtonClick(e)}
|
||||
isStarredActive={isStarredActive}
|
||||
isTrashedActive={isTrashedActive}
|
||||
handleStarredButtonClick={(e) => this.handleStarredButtonClick(e)}
|
||||
handleTrashedButtonClick={(e) => this.handleTrashedButtonClick(e)}
|
||||
counterTotalNote={data.noteMap._map.size - data.trashedSet._set.size}
|
||||
handleStarredButtonClick={e => this.handleStarredButtonClick(e)}
|
||||
handleTrashedButtonClick={e => this.handleTrashedButtonClick(e)}
|
||||
counterTotalNote={
|
||||
data.noteMap._map.size - data.trashedSet._set.size
|
||||
}
|
||||
counterStarredNote={data.starredSet._set.size}
|
||||
counterDelNote={data.trashedSet._set.size}
|
||||
handleFilterButtonContextMenu={this.handleFilterButtonContextMenu.bind(this)}
|
||||
handleFilterButtonContextMenu={this.handleFilterButtonContextMenu.bind(
|
||||
this
|
||||
)}
|
||||
/>
|
||||
|
||||
<StorageList storageList={storageList} isFolded={isFolded} />
|
||||
<NavToggleButton isFolded={isFolded} handleToggleButtonClick={this.handleToggleButtonClick.bind(this)} />
|
||||
<NavToggleButton
|
||||
isFolded={isFolded}
|
||||
handleToggleButtonClick={this.handleToggleButtonClick.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
@@ -313,22 +354,26 @@ class SideNav extends React.Component {
|
||||
</div>
|
||||
<div styleName='tag-control-sortTagsBy'>
|
||||
<i className='fa fa-angle-down' />
|
||||
<select styleName='tag-control-sortTagsBy-select'
|
||||
<select
|
||||
styleName='tag-control-sortTagsBy-select'
|
||||
title={i18n.__('Select filter mode')}
|
||||
value={config.sortTagsBy}
|
||||
onChange={(e) => this.handleSortTagsByChange(e)}
|
||||
onChange={e => this.handleSortTagsByChange(e)}
|
||||
>
|
||||
<option title='Sort alphabetically'
|
||||
value='ALPHABETICAL'>{i18n.__('Alphabetically')}</option>
|
||||
<option title='Sort by update time'
|
||||
value='COUNTER'>{i18n.__('Counter')}</option>
|
||||
<option title='Sort alphabetically' value='ALPHABETICAL'>
|
||||
{i18n.__('Alphabetically')}
|
||||
</option>
|
||||
<option title='Sort by update time' value='COUNTER'>
|
||||
{i18n.__('Counter')}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='tagList'>
|
||||
{this.tagListComponent(data)}
|
||||
</div>
|
||||
<NavToggleButton isFolded={isFolded} handleToggleButtonClick={this.handleToggleButtonClick.bind(this)} />
|
||||
<div styleName='tagList'>{this.tagListComponent(data)}</div>
|
||||
<NavToggleButton
|
||||
isFolded={isFolded}
|
||||
handleToggleButtonClick={this.handleToggleButtonClick.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -336,85 +381,89 @@ class SideNav extends React.Component {
|
||||
return component
|
||||
}
|
||||
|
||||
tagListComponent () {
|
||||
tagListComponent() {
|
||||
const { data, location, config } = this.props
|
||||
const { colorPicker, showSearch, searchText } = this.state
|
||||
const activeTags = this.getActiveTags(location.pathname)
|
||||
const relatedTags = this.getRelatedTags(activeTags, data.noteMap)
|
||||
let tagList = sortBy(data.tagNoteMap.map(
|
||||
(tag, name) => ({ name, size: tag.size, related: relatedTags.has(name) })
|
||||
).filter(
|
||||
tag => tag.size > 0
|
||||
), ['name'])
|
||||
let tagList = sortBy(
|
||||
data.tagNoteMap
|
||||
.map((tag, name) => ({
|
||||
name,
|
||||
size: tag.size,
|
||||
related: relatedTags.has(name)
|
||||
}))
|
||||
.filter(tag => tag.size > 0),
|
||||
['name']
|
||||
)
|
||||
if (showSearch && searchText.length > 0) {
|
||||
tagList = tagList.filter(tag => tag.name.toLowerCase().indexOf(searchText.toLowerCase()) !== -1)
|
||||
tagList = tagList.filter(
|
||||
tag => tag.name.toLowerCase().indexOf(searchText.toLowerCase()) !== -1
|
||||
)
|
||||
}
|
||||
if (config.ui.enableLiveNoteCounts && activeTags.length !== 0) {
|
||||
const notesTags = data.noteMap.map(note => note.tags)
|
||||
tagList = tagList.map(tag => {
|
||||
tag.size = notesTags.filter(tags => tags.includes(tag.name) && matchActiveTags(tags, activeTags)).length
|
||||
tag.size = notesTags.filter(
|
||||
tags => tags.includes(tag.name) && matchActiveTags(tags, activeTags)
|
||||
).length
|
||||
return tag
|
||||
})
|
||||
}
|
||||
if (config.sortTagsBy === 'COUNTER') {
|
||||
tagList = sortBy(tagList, item => (0 - item.size))
|
||||
tagList = sortBy(tagList, item => 0 - item.size)
|
||||
}
|
||||
if (config.ui.showOnlyRelatedTags && (relatedTags.size > 0)) {
|
||||
tagList = tagList.filter(
|
||||
tag => tag.related
|
||||
if (config.ui.showOnlyRelatedTags && relatedTags.size > 0) {
|
||||
tagList = tagList.filter(tag => tag.related)
|
||||
}
|
||||
return tagList.map(tag => {
|
||||
return (
|
||||
<TagListItem
|
||||
name={tag.name}
|
||||
handleClickTagListItem={this.handleClickTagListItem.bind(this)}
|
||||
handleClickNarrowToTag={this.handleClickNarrowToTag.bind(this)}
|
||||
handleContextMenu={this.handleTagContextMenu.bind(this)}
|
||||
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]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
return (
|
||||
tagList.map(tag => {
|
||||
return (
|
||||
<TagListItem
|
||||
name={tag.name}
|
||||
handleClickTagListItem={this.handleClickTagListItem.bind(this)}
|
||||
handleClickNarrowToTag={this.handleClickNarrowToTag.bind(this)}
|
||||
handleContextMenu={this.handleTagContextMenu.bind(this)}
|
||||
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]}
|
||||
/>
|
||||
)
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
getRelatedTags (activeTags, noteMap) {
|
||||
getRelatedTags(activeTags, noteMap) {
|
||||
if (activeTags.length === 0) {
|
||||
return new Set()
|
||||
}
|
||||
const relatedNotes = noteMap.map(
|
||||
note => ({key: note.key, tags: note.tags})
|
||||
).filter(
|
||||
note => activeTags.every(tag => note.tags.includes(tag))
|
||||
)
|
||||
const relatedNotes = noteMap
|
||||
.map(note => ({ key: note.key, tags: note.tags }))
|
||||
.filter(note => activeTags.every(tag => note.tags.includes(tag)))
|
||||
const relatedTags = new Set()
|
||||
relatedNotes.forEach(note => note.tags.map(tag => relatedTags.add(tag)))
|
||||
return relatedTags
|
||||
}
|
||||
|
||||
getTagActive (path, tag) {
|
||||
getTagActive(path, tag) {
|
||||
return this.getActiveTags(path).includes(tag)
|
||||
}
|
||||
|
||||
getActiveTags (path) {
|
||||
getActiveTags(path) {
|
||||
const pathSegments = path.split('/')
|
||||
const tags = pathSegments[pathSegments.length - 1]
|
||||
return (tags === 'alltags')
|
||||
? []
|
||||
: decodeURIComponent(tags).split(' ')
|
||||
return tags === 'alltags' ? [] : decodeURIComponent(tags).split(' ')
|
||||
}
|
||||
|
||||
handleClickTagListItem (name) {
|
||||
handleClickTagListItem(name) {
|
||||
const { dispatch } = this.props
|
||||
dispatch(push(`/tags/${encodeURIComponent(name)}`))
|
||||
}
|
||||
|
||||
handleSortTagsByChange (e) {
|
||||
handleSortTagsByChange(e) {
|
||||
const { dispatch } = this.props
|
||||
|
||||
const config = {
|
||||
@@ -428,7 +477,7 @@ class SideNav extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
handleClickNarrowToTag (tag) {
|
||||
handleClickNarrowToTag(tag) {
|
||||
const { dispatch, location } = this.props
|
||||
const listOfTags = this.getActiveTags(location.pathname)
|
||||
const indexOfTag = listOfTags.indexOf(tag)
|
||||
@@ -440,33 +489,38 @@ class SideNav extends React.Component {
|
||||
dispatch(push(`/tags/${encodeURIComponent(listOfTags.join(' '))}`))
|
||||
}
|
||||
|
||||
emptyTrash (entries) {
|
||||
emptyTrash(entries) {
|
||||
const { dispatch } = this.props
|
||||
const deletionPromises = entries.map((note) => {
|
||||
const deletionPromises = entries.map(note => {
|
||||
return dataApi.deleteNote(note.storage, note.key)
|
||||
})
|
||||
const { confirmDeletion } = this.props.config.ui
|
||||
if (!confirmDeleteNote(confirmDeletion, true)) return
|
||||
Promise.all(deletionPromises)
|
||||
.then((arrayOfStorageAndNoteKeys) => {
|
||||
arrayOfStorageAndNoteKeys.forEach(({ storageKey, noteKey }) => {
|
||||
dispatch({ type: 'DELETE_NOTE', storageKey, noteKey })
|
||||
.then(arrayOfStorageAndNoteKeys => {
|
||||
arrayOfStorageAndNoteKeys.forEach(({ storageKey, noteKey }) => {
|
||||
dispatch({ type: 'DELETE_NOTE', storageKey, noteKey })
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Cannot Delete note: ' + err)
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Cannot Delete note: ' + err)
|
||||
})
|
||||
}
|
||||
|
||||
handleFilterButtonContextMenu (event) {
|
||||
handleFilterButtonContextMenu(event) {
|
||||
const { data } = this.props
|
||||
const trashedNotes = data.trashedSet.toJS().map((uniqueKey) => data.noteMap.get(uniqueKey))
|
||||
const trashedNotes = data.trashedSet
|
||||
.toJS()
|
||||
.map(uniqueKey => data.noteMap.get(uniqueKey))
|
||||
context.popup([
|
||||
{ label: i18n.__('Empty Trash'), click: () => this.emptyTrash(trashedNotes) }
|
||||
{
|
||||
label: i18n.__('Empty Trash'),
|
||||
click: () => this.emptyTrash(trashedNotes)
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
render () {
|
||||
render() {
|
||||
const { location, config } = this.props
|
||||
const { showSearch, searchText, colorPicker: colorPickerState } = this.state
|
||||
|
||||
@@ -489,7 +543,7 @@ class SideNav extends React.Component {
|
||||
const isTagActive = /tag/.test(location.pathname)
|
||||
|
||||
const navSearch = (
|
||||
<div styleName='search' style={{maxHeight: showSearch ? '3em' : '0'}}>
|
||||
<div styleName='search' style={{ maxHeight: showSearch ? '3em' : '0' }}>
|
||||
<input
|
||||
styleName='search-input'
|
||||
type='text'
|
||||
@@ -497,21 +551,38 @@ class SideNav extends React.Component {
|
||||
value={searchText}
|
||||
placeholder={i18n.__('Filter tags/folders...')}
|
||||
/>
|
||||
<img styleName='search-clear' src='../resources/icon/icon-x.svg' onClick={this.handleSearchInputClear} />
|
||||
{isFolded && <img styleName='search-folded' src='../resources/icon/icon-search-active.svg' onClick={this.handleSearchButtonClick} />}
|
||||
<img
|
||||
styleName='search-clear'
|
||||
src='../resources/icon/icon-x.svg'
|
||||
onClick={this.handleSearchInputClear}
|
||||
/>
|
||||
{isFolded && (
|
||||
<img
|
||||
styleName='search-folded'
|
||||
src='../resources/icon/icon-search-active.svg'
|
||||
onClick={this.handleSearchButtonClick}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className='SideNav'
|
||||
<div
|
||||
className='SideNav'
|
||||
styleName={isFolded ? 'root--folded' : 'root'}
|
||||
tabIndex='1'
|
||||
style={style}
|
||||
>
|
||||
<div styleName='top'>
|
||||
<div styleName='switch-buttons'>
|
||||
<ListButton onClick={this.handleSwitchFoldersButtonClick.bind(this)} isTagActive={isTagActive} />
|
||||
<TagButton onClick={this.handleSwitchTagsButtonClick.bind(this)} isTagActive={isTagActive} />
|
||||
<ListButton
|
||||
onClick={this.handleSwitchFoldersButtonClick.bind(this)}
|
||||
isTagActive={isTagActive}
|
||||
/>
|
||||
<TagButton
|
||||
onClick={this.handleSwitchTagsButtonClick.bind(this)}
|
||||
isTagActive={isTagActive}
|
||||
/>
|
||||
</div>
|
||||
<div styleName='extra-buttons'>
|
||||
<SearchButton
|
||||
|
||||
Reference in New Issue
Block a user