From 6e0def310faaec63079159ae82dc96fc26e61187 Mon Sep 17 00:00:00 2001 From: Dick Choi Date: Wed, 12 Oct 2016 20:02:50 +0900 Subject: [PATCH] update design of Note List add list style remove folder info enhance design --- browser/finder/NoteDetail.styl | 4 + browser/finder/NoteItem.js | 27 +++-- browser/finder/NoteItem.styl | 108 ++++++++++++++---- browser/finder/store.js | 32 +----- browser/main/NoteList/NoteList.styl | 171 +++++++++++++++++++--------- browser/main/NoteList/index.js | 160 +++++++++++++++++++------- browser/main/lib/ConfigManager.js | 18 +-- 7 files changed, 348 insertions(+), 172 deletions(-) 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)