1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 01:36:22 +00:00

update design of Note List

add list style
remove folder info
enhance design
This commit is contained in:
Dick Choi
2016-10-12 20:02:50 +09:00
parent 823da07a5e
commit 6e0def310f
7 changed files with 348 additions and 172 deletions

View File

@@ -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

View File

@@ -22,7 +22,7 @@ class NoteItem extends React.Component {
let tagList = _.isArray(note.tags)
? note.tags.map((tag) => {
return (
<span styleName='item-tagList-item'
<span styleName='bottom-tagList-item'
key={tag}>
{tag}
</span>
@@ -37,9 +37,7 @@ class NoteItem extends React.Component {
key={note.storage + '-' + note.key}
onClick={(e) => this.handleClick(e)}
>
<div styleName='border'/>
<div styleName='info'>
<div styleName='info-left'>
<span styleName='info-left-folder'
style={{borderColor: folder.color}}
@@ -48,11 +46,6 @@ class NoteItem extends React.Component {
<span styleName='info-left-folder-surfix'>in {storage.name}</span>
</span>
</div>
<div styleName='info-right'>
{moment(note.updatedAt).fromNow()}
</div>
</div>
<div styleName='title'>
@@ -66,14 +59,20 @@ class NoteItem extends React.Component {
}
</div>
<div styleName='tagList'>
<i styleName='tagList-icon'
<div styleName='bottom'>
<i styleName='bottom-tagIcon'
className='fa fa-tags fa-fw'
/>
{tagList.length > 0
? tagList
: <span styleName='tagList-empty'>Not tagged yet</span>
}
<div styleName='bottom-tagList'>
{tagList.length > 0
? tagList
: <span styleName='bottom-tagList-empty'>Not tagged yet</span>
}
</div>
<div styleName='bottom-time'>
{moment(note.updatedAt).fromNow()}
</div>
</div>
</div>
)

View File

@@ -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

View File

@@ -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':

View File

@@ -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

View File

@@ -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 (
<span styleName='item-tagList-item'
<span styleName='item-bottom-tagList-item'
key={tag}>
{tag}
</span>
@@ -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)}
>
<div styleName='item-border'/>
<div styleName='item-info'>
<div styleName='item-info-left'>
<span styleName='item-info-left-folder'
style={{borderColor: folder.color}}
>
{folder.name}
<span styleName='item-info-left-folder-surfix'>in {storage.name}</span>
</span>
</div>
<div styleName='item-info-right'>
{moment(note.updatedAt).fromNow()}
</div>
</div>
<div styleName='item-title'>
{note.type === 'SNIPPET_NOTE'
? <i styleName='item-title-icon' className='fa fa-fw fa-code'/>
@@ -333,15 +359,23 @@ class NoteList extends React.Component {
}
</div>
<div styleName='item-tagList'>
<i styleName='item-tagList-icon'
className='fa fa-tags fa-fw'
/>
{tagElements.length > 0
? tagElements
: <span styleName='item-tagList-empty'>Not tagged yet</span>
}
</div>
{config.listStyle === 'DEFAULT' &&
<div styleName='item-bottom'>
<i styleName='item-bottom-tagIcon'
className='fa fa-tags fa-fw'
/>
<div styleName='item-bottom-tagList'>
{tagElements.length > 0
? tagElements
: <span styleName='item-bottom-tagList-empty'>Not tagged yet</span>
}
</div>
<div styleName='item-bottom-time'>
{moment(config.sortBy === 'CREATED_AT' ? note.createdAt : note.updatedAt).fromNow()}
</div>
</div>
}
</div>
)
})
@@ -349,13 +383,51 @@ class NoteList extends React.Component {
return (
<div className='NoteList'
styleName='root'
ref='root'
tabIndex='-1'
onKeyDown={(e) => this.handleNoteListKeyDown(e)}
style={this.props.style}
onScroll={(e) => this.handleScroll(e)}
>
{noteList}
<div styleName='control'>
<div styleName='control-sortBy'>
Sort by
<select styleName='control-sortBy-select'
value={config.sortBy}
onChange={(e) => this.handleSortByChange(e)}
>
<option value='UPDATED_AT'>Updated Time</option>
<option value='CREATED_AT'>Created Time</option>
<option value='ALPHABETICAL'>Alphabetical</option>
</select>
</div>
<button styleName={config.listStyle === 'DEFAULT'
? 'control-button--active'
: 'control-button'
}
onClick={(e) => this.handleListStyleButtonClick(e, 'DEFAULT')}
>
<i className='fa fa-th-list'/>
<span styleName='control-button-tooltip'>
Default Size
</span>
</button>
<button styleName={config.listStyle === 'SMALL'
? 'control-button--active'
: 'control-button'
}
onClick={(e) => this.handleListStyleButtonClick(e, 'SMALL')}
>
<i className='fa fa-list'/>
<span styleName='control-button-tooltip'>
Small Size
</span>
</button>
</div>
<div styleName='list'
ref='list'
tabIndex='-1'
onKeyDown={(e) => this.handleNoteListKeyDown(e)}
onScroll={(e) => this.handleScroll(e)}
>
{noteList}
</div>
</div>
)
}

View File

@@ -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)