diff --git a/browser/finder/NoteDetail.styl b/browser/finder/NoteDetail.styl
index 83e1a001..8fb3715a 100644
--- a/browser/finder/NoteDetail.styl
+++ b/browser/finder/NoteDetail.styl
@@ -27,20 +27,24 @@
border-bottom $ui-border
display flex
background-color $ui-backgroundColor
+
.tabList-item
position relative
flex 1
border-right $ui-border
+
.tabList-item--active
@extend .tabList-item
.tabList-item-button
border-color $brand-color
+
.tabList-item-button
width 100%
height 29px
navButtonColor()
outline none
border-left 4px solid transparent
+
.tabList-item-deleteButton
position absolute
top 5px
diff --git a/browser/finder/NoteItem.js b/browser/finder/NoteItem.js
index bc3ae253..7f2ff1d9 100644
--- a/browser/finder/NoteItem.js
+++ b/browser/finder/NoteItem.js
@@ -22,7 +22,7 @@ class NoteItem extends React.Component {
let tagList = _.isArray(note.tags)
? note.tags.map((tag) => {
return (
-
{tag}
@@ -37,9 +37,7 @@ class NoteItem extends React.Component {
key={note.storage + '-' + note.key}
onClick={(e) => this.handleClick(e)}
>
-
-
in {storage.name}
-
-
- {moment(note.updatedAt).fromNow()}
-
-
@@ -66,14 +59,20 @@ class NoteItem extends React.Component {
}
-
-
+
- {tagList.length > 0
- ? tagList
- : Not tagged yet
- }
+
+ {tagList.length > 0
+ ? tagList
+ : Not tagged yet
+ }
+
+
+
+ {moment(note.updatedAt).fromNow()}
+
)
diff --git a/browser/finder/NoteItem.styl b/browser/finder/NoteItem.styl
index 3664ca1d..84c37374 100644
--- a/browser/finder/NoteItem.styl
+++ b/browser/finder/NoteItem.styl
@@ -1,18 +1,33 @@
.root
position relative
- height 80px
border-bottom $ui-border
- padding 0 5px
+ padding 2px 5px
user-select none
cursor pointer
transition background-color 0.15s
&:hover
- background-color alpha($ui-active-color, 10%)
+ background-color alpha($ui-active-color, 20%)
.root--active
@extend .root
- .border
- border-color $ui-active-color
+ background-color $ui-active-color
+ &:hover
+ background-color $ui-active-color
+ color white
+ .info-left-folder
+ .info-left-folder-surfix
+ .title
+ .title-icon
+ .title-empty
+ .bottom-tagIcon
+ .bottom-tagList-item
+ .bottom-tagList-empty
+ .bottom-time
+ color white
+ .bottom-tagList-item
+ color white
+ background-color transparent
+
.border
absolute top bottom left right
@@ -22,11 +37,11 @@
transition 0.15s
.info
- height 30px
+ height 20px
clearfix()
font-size 12px
color $ui-inactive-text-color
- line-height 30px
+ line-height 20px
overflow-y hidden
.info-left
@@ -45,77 +60,120 @@
float right
.title
+ height 24px
+ box-sizing border-box
+ line-height 24px
height 20px
line-height 20px
padding 0 5px 0 0
- font-weight bold
overflow ellipsis
color $ui-text-color
+
.title-icon
font-size 12px
color $ui-inactive-text-color
padding-right 3px
+
.title-empty
font-weight normal
color $ui-inactive-text-color
-.tagList
- height 30px
+.bottom
+ margin-top 2px
+ height 20px
font-size 12px
- line-height 30px
+ line-height 20px
overflow ellipsis
+ display flex
-.tagList-icon
+.bottom-tagIcon
vertical-align middle
color $ui-button-color
+ height 20px
+ line-height 20px
-.tagList-item
+.bottom-tagList
+ flex 1
+ overflow ellipsis
+ line-height 20px
+
+.bottom-tagList-item
margin 0 4px
padding 0 4px
height 20px
+ box-sizing border-box
border-radius 3px
vertical-align middle
border-style solid
border-color $ui-button--focus-borderColor
border-width 0 0 0 3px
background-color $ui-backgroundColor
+ color $ui-text-color
+ transition 0.15s
-.tagList-empty
+.bottom-tagList-empty
color $ui-inactive-text-color
vertical-align middle
+ font-size 10px
+
+.bottom-time
+ color $ui-inactive-text-color
+ margin-left 5px
+ font-size 10px
body[data-theme="dark"]
.root
border-color $ui-dark-borderColor
- &:hover
- background-color alpha($ui-active-color, 20%)
.root--active
@extend .root
- .border
- border-color $ui-active-color
+ border-color $ui-dark-borderColor
+ &:hover
+ background-color $ui-active-color
+ .info-left-folder
+ .info-left-folder-surfix
+ .title
+ .title-icon
+ .title-empty
+ .bottom-tagIcon
+ .bottom-tagList-item
+ .bottom-tagList-empty
+ .bottom-time
+ color white
+ .bottom-tagList-item
+ color white
+ background-color transparent
.info
color $ui-dark-inactive-text-color
.info-left-folder
color $ui-dark-text-color
+
.info-left-folder-surfix
color $ui-dark-inactive-text-color
.title
color $ui-dark-text-color
+
.title-icon
color $ui-dark-inactive-text-color
+
.title-empty
color $ui-dark-inactive-text-color
- .tagList-icon
- color $ui-dark-button-color
-
- .tagList-item
- border-color $ui-dark-button--focus-borderColor
- background-color $ui-dark-backgroundColor
-
.tagList-empty
color $ui-dark-inactive-text-color
+
+ .bottom-tagIcon
+ color $ui-dark-button-color
+
+ .bottom-tagList-item
+ color $ui-dark-text-color
+ background-color $ui-dark-backgroundColor
+
+ .bottom-tagList-empty
+ color $ui-dark-inactive-text-color
+
+ .bottom-time
+ color $ui-dark-inactive-text-color
diff --git a/browser/finder/store.js b/browser/finder/store.js
index ab4a0884..b1a70076 100644
--- a/browser/finder/store.js
+++ b/browser/finder/store.js
@@ -1,34 +1,6 @@
import { combineReducers, createStore } from 'redux'
import { routerReducer } from 'react-router-redux'
-
-const OSX = global.process.platform === 'darwin'
-const defaultConfig = {
- zoom: 1,
- isSideNavFolded: false,
- listWidth: 250,
- hotkey: {
- toggleFinder: OSX ? 'Cmd + Alt + S' : 'Super + Alt + S',
- toggleMain: OSX ? 'Cmd + Alt + L' : 'Super + Alt + E'
- },
- ui: {
- theme: 'default',
- disableDirectWrite: false
- },
- editor: {
- theme: 'xcode',
- fontSize: '14',
- fontFamily: 'Monaco, Consolas',
- indentType: 'space',
- indentSize: '4',
- switchPreview: 'BLUR' // Available value: RIGHTCLICK, BLUR
- },
- preview: {
- fontSize: '14',
- fontFamily: 'Lato',
- codeBlockTheme: 'xcode',
- lineNumber: true
- }
-}
+import { DEFAULT_CONFIG } from 'browser/main/lib/ConfigManager'
let defaultData = {
storageMap: {},
@@ -48,7 +20,7 @@ function data (state = defaultData, action) {
return state
}
-function config (state = defaultConfig, action) {
+function config (state = DEFAULT_CONFIG, action) {
switch (action.type) {
case 'INIT_CONFIG':
case 'SET_CONFIG':
diff --git a/browser/main/NoteList/NoteList.styl b/browser/main/NoteList/NoteList.styl
index 27ff2173..cfd0b434 100644
--- a/browser/main/NoteList/NoteList.styl
+++ b/browser/main/NoteList/NoteList.styl
@@ -2,14 +2,64 @@
absolute left bottom
border-top $ui-border
border-bottom $ui-border
- overflow auto
top $topBar-height - 1
+.control
+ absolute top left right
+ user-select none
+ height 25px
+ font-size 10px
+ border-bottom $ui-border
+ line-height 25px
+ display flex
+ background-color $ui-backgroundColor
+ color $ui-inactive-text-color
+
+.control-sortBy
+ flex 1
+ padding-left 5px
+
+.control-sortBy-select
+ margin-left 5px
+ padding 0
+ border none
+ background-color transparent
+ font-size 10px
+
+.control-button
+ width 25px
+ padding 0
+ background-color transparent
+ border none
+ color $ui-inactive-text-color
+ &:hover
+ .control-button-tooltip
+ opacity 1
+
+.control-button--active
+ @extend .control-button
+ color $ui-active-color
+
+.control-button-tooltip
+ tooltip()
+ position absolute
+ top 20px
+ right 5px
+ padding 5px
+ opacity 0
+ white-space nowrap
+ border-radius 2px
+ z-index 1
+
+.list
+ absolute left right bottom
+ top 24px
+ overflow auto
+
.item
position relative
- height 80px
border-bottom $ui-border
- padding 0 5px
+ padding 2px 5px
user-select none
cursor pointer
transition background-color 0.15s
@@ -18,8 +68,23 @@
.item--active
@extend .item
- .item-border
- border-color $ui-active-color
+ background-color alpha($ui-active-color, 100%)
+ color white
+ .item-title
+ color white
+ .item-title-icon
+ color white
+ .item-bottom-tagIcon
+ color white
+ .item-bottom-tagList-empty
+ color white
+ .item-bottom-time
+ color white
+ .item-bottom-tagList-item
+ background-color transparent
+ color white
+ &:hover
+ background-color alpha($ui-active-color, 100%)
.item-border
absolute top bottom left right
@@ -28,68 +93,64 @@
border-color transparent
transition 0.15s
-.item-info
- height 30px
- clearfix()
- font-size 12px
- color $ui-inactive-text-color
- line-height 30px
- overflow-y hidden
-
-.item-info-left
- float left
- overflow ellipsis
-
-.item-info-left-folder
- border-left 4px solid transparent
- padding 2px 5px
- color $ui-text-color
-.item-info-left-folder-surfix
- font-size 10px
- margin-left 5px
- color $ui-inactive-text-color
-.item-info-right
- float right
-
.item-title
- height 20px
- line-height 20px
- padding 0 5px 0 0
- font-weight bold
+ height 24px
+ box-sizing border-box
+ line-height 24px
+ padding 0
overflow ellipsis
color $ui-text-color
+
.item-title-icon
font-size 12px
color $ui-inactive-text-color
padding-right 3px
+
.item-title-empty
font-weight normal
color $ui-inactive-text-color
-.item-tagList
- height 30px
+.item-bottom
+ margin-top 2px
+ height 20px
font-size 12px
- line-height 30px
+ line-height 20px
overflow ellipsis
+ display flex
-.item-tagList-icon
+.item-bottom-tagIcon
vertical-align middle
color $ui-button-color
+ height 20px
+ line-height 20px
-.item-tagList-item
+.item-bottom-tagList
+ flex 1
+ overflow ellipsis
+ line-height 20px
+
+.item-bottom-tagList-item
margin 0 4px
padding 0 4px
height 20px
+ box-sizing border-box
border-radius 3px
vertical-align middle
border-style solid
border-color $ui-button--focus-borderColor
border-width 0 0 0 3px
background-color $ui-backgroundColor
+ color $ui-text-color
-.item-tagList-empty
+.item-bottom-tagList-empty
color $ui-inactive-text-color
vertical-align middle
+ font-size 10px
+
+.item-bottom-time
+ color $ui-inactive-text-color
+ margin-left 5px
+ font-size 10px
body[data-theme="dark"]
.root
@@ -103,32 +164,40 @@ body[data-theme="dark"]
.item--active
@extend .item
- .item-border
- border-color $ui-active-color
-
- .item-info
- color $ui-dark-inactive-text-color
-
- .item-info-left-folder
- color $ui-dark-text-color
- .item-info-left-folder-surfix
- color $ui-dark-inactive-text-color
+ border-color $ui-dark-borderColor
+ .item-title
+ color white
+ .item-bottom-tagList-item
+ background-color transparent
+ color white
+ .item-bottom-tagList-empty
+ color white
+ &:hover
+ background-color alpha($ui-active-color, 100%)
.item-title
color $ui-dark-text-color
+
.item-title-icon
color $ui-darkinactive-text-color
+
.item-title-empty
color $ui-dark-inactive-text-color
- .item-tagList-icon
+ .item-bottom-tagIcon
color $ui-dark-button-color
- .item-tagList-item
+ .item-bottom-tagList-item
border-color $ui-dark-button--focus-borderColor
background-color $ui-dark-button--hover-backgroundColor
color $ui-dark-text-color
- .item-tagList-empty
+ .item-bottom-tagList-empty
color $ui-inactive-text-color
vertical-align middle
+
+ .control
+ background-color $ui-dark-backgroundColor
+ border-color $ui-dark-borderColor
+ .control-sortBy-select
+ color $ui-dark-text-color
diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js
index 15a8510b..b1b3dcdf 100644
--- a/browser/main/NoteList/index.js
+++ b/browser/main/NoteList/index.js
@@ -5,10 +5,23 @@ import moment from 'moment'
import _ from 'lodash'
import ee from 'browser/main/lib/eventEmitter'
import dataApi from 'browser/main/lib/dataApi'
+import ConfigManager from 'browser/main/lib/ConfigManager'
const { remote } = require('electron')
const { Menu, MenuItem, dialog } = remote
+function sortByCreatedAt (a, b) {
+ return new Date(b.createdAt) - new Date(a.createdAt)
+}
+
+function sortByAlphabetical (a, b) {
+ return a.title.localeCompare(b.title)
+}
+
+function sortByUpdatedAt (a, b) {
+ return new Date(b.updatedAt) - new Date(a.updatedAt)
+}
+
class NoteList extends React.Component {
constructor (props) {
super(props)
@@ -21,7 +34,7 @@ class NoteList extends React.Component {
this.selectPriorNote()
}
this.focusHandler = () => {
- this.refs.root.focus()
+ this.refs.list.focus()
}
this.state = {
@@ -43,7 +56,7 @@ class NoteList extends React.Component {
}
resetScroll () {
- this.refs.root.scrollTop = 0
+ this.refs.list.scrollTop = 0
this.setState({
range: 0
})
@@ -52,7 +65,7 @@ class NoteList extends React.Component {
handleScroll (e) {
let notes = this.notes
- if (e.target.offsetHeight + e.target.scrollTop > e.target.scrollHeight - 250 && notes.length > this.state.range * 10 + 10) {
+ if (e.target.offsetHeight + e.target.scrollTop > e.target.scrollHeight - 250 && notes.length > this.state.range * 20 + 20) {
this.setState({
range: this.state.range + 1
})
@@ -86,7 +99,7 @@ class NoteList extends React.Component {
return note != null && note.storage + '-' + note.key === location.query.key
})
if (targetIndex > -1) {
- let list = this.refs.root
+ let list = this.refs.list
let item = list.childNodes[targetIndex]
if (item == null) return false
@@ -274,20 +287,51 @@ class NoteList extends React.Component {
}
}
- render () {
- let { location, data, notes } = this.props
- this.notes = notes = this.getNotes()
- .sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt))
+ handleSortByChange (e) {
+ let { dispatch } = this.props
- let noteList = notes.slice(0, 10 + 10 * this.state.range)
+ let config = {
+ sortBy: e.target.value
+ }
+
+ ConfigManager.set(config)
+ dispatch({
+ type: 'SET_CONFIG',
+ config
+ })
+ }
+
+ handleListStyleButtonClick (e, style) {
+ let { dispatch } = this.props
+
+ let config = {
+ listStyle: style
+ }
+
+ ConfigManager.set(config)
+ dispatch({
+ type: 'SET_CONFIG',
+ config
+ })
+ }
+
+ render () {
+ let { location, notes, config } = this.props
+ let sortFunc = config.sortBy === 'CREATED_AT'
+ ? sortByCreatedAt
+ : config.sortBy === 'ALPHABETICAL'
+ ? sortByAlphabetical
+ : sortByUpdatedAt
+ this.notes = notes = this.getNotes()
+ .sort(sortFunc)
+
+ let noteList = notes.slice(0, 20 + 20 * this.state.range)
.map((note) => {
if (note == null) return null
- let storage = data.storageMap.get(note.storage)
- let folder = _.find(storage.folders, {key: note.folder})
let tagElements = _.isArray(note.tags)
? note.tags.map((tag) => {
return (
-
{tag}
@@ -304,24 +348,6 @@ class NoteList extends React.Component {
onClick={(e) => this.handleNoteClick(e, note.storage + '-' + note.key)}
onContextMenu={(e) => this.handleNoteContextMenu(e, note.storage + '-' + note.key)}
>
-
-
-
-
-
- {folder.name}
- in {storage.name}
-
-
-
-
- {moment(note.updatedAt).fromNow()}
-
-
-
-
{note.type === 'SNIPPET_NOTE'
?
@@ -333,15 +359,23 @@ class NoteList extends React.Component {
}
-
-
- {tagElements.length > 0
- ? tagElements
- : Not tagged yet
- }
-
+ {config.listStyle === 'DEFAULT' &&
+
+
+
+ {tagElements.length > 0
+ ? tagElements
+ : Not tagged yet
+ }
+
+
+
+ {moment(config.sortBy === 'CREATED_AT' ? note.createdAt : note.updatedAt).fromNow()}
+
+
+ }
)
})
@@ -349,13 +383,51 @@ class NoteList extends React.Component {
return (
this.handleNoteListKeyDown(e)}
style={this.props.style}
- onScroll={(e) => this.handleScroll(e)}
>
- {noteList}
+
+
+ Sort by
+
+
+
+
+
+
this.handleNoteListKeyDown(e)}
+ onScroll={(e) => this.handleScroll(e)}
+ >
+ {noteList}
+
)
}
diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js
index 62cd5aae..3df57b1b 100644
--- a/browser/main/lib/ConfigManager.js
+++ b/browser/main/lib/ConfigManager.js
@@ -7,11 +7,13 @@ const consts = require('browser/lib/consts')
let isInitialized = false
-const defaultConfig = {
+export const DEFAULT_CONFIG = {
zoom: 1,
isSideNavFolded: false,
listWidth: 250,
navWidth: 200,
+ sortBy: 'UPDATED_AT', // 'CREATED_AT', 'UPDATED_AT', 'APLHABETICAL'
+ listStyle: 'DEFAULT', // 'DEFAULT', 'SMALL'
hotkey: {
toggleFinder: OSX ? 'Cmd + Alt + S' : 'Super + Alt + S',
toggleMain: OSX ? 'Cmd + Alt + L' : 'Super + Alt + E'
@@ -55,15 +57,15 @@ function get () {
let config = window.localStorage.getItem('config')
try {
- config = Object.assign({}, defaultConfig, JSON.parse(config))
- config.hotkey = Object.assign({}, defaultConfig.hotkey, config.hotkey)
- config.ui = Object.assign({}, defaultConfig.ui, config.ui)
- config.editor = Object.assign({}, defaultConfig.editor, config.editor)
- config.preview = Object.assign({}, defaultConfig.preview, config.preview)
+ config = Object.assign({}, DEFAULT_CONFIG, JSON.parse(config))
+ config.hotkey = Object.assign({}, DEFAULT_CONFIG.hotkey, config.hotkey)
+ config.ui = Object.assign({}, DEFAULT_CONFIG.ui, config.ui)
+ config.editor = Object.assign({}, DEFAULT_CONFIG.editor, config.editor)
+ config.preview = Object.assign({}, DEFAULT_CONFIG.preview, config.preview)
if (!validate(config)) throw new Error('INVALID CONFIG')
} catch (err) {
console.warn('Boostnote resets the malformed configuration.')
- config = defaultConfig
+ config = DEFAULT_CONFIG
_save(config)
}
@@ -91,7 +93,7 @@ function get () {
function set (updates) {
let currentConfig = get()
- let newConfig = Object.assign({}, defaultConfig, currentConfig, updates)
+ let newConfig = Object.assign({}, DEFAULT_CONFIG, currentConfig, updates)
if (!validate(newConfig)) throw new Error('INVALID CONFIG')
_save(newConfig)