Skip to content

Commit 8f0789b

Browse files
committed
renew SideNav
add contextmenu fix MutableSet bug
1 parent 2fdea6c commit 8f0789b

10 files changed

Lines changed: 569 additions & 41 deletions

File tree

browser/lib/Mutable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class MutableSet {
6161
constructor (iterable) {
6262
this._set = new Set(iterable)
6363
Object.defineProperty(this, 'size', {
64-
get: () => this._map.size,
64+
get: () => this._set.size,
6565
set: function (value) {
6666
this['size'] = value
6767
}

browser/main/NoteList/index.js

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ class NoteList extends React.Component {
3838
}
3939

4040
this.state = {
41-
range: 0
4241
}
4342
}
4443

@@ -57,19 +56,6 @@ class NoteList extends React.Component {
5756

5857
resetScroll () {
5958
this.refs.list.scrollTop = 0
60-
this.setState({
61-
range: 0
62-
})
63-
}
64-
65-
handleScroll (e) {
66-
let notes = this.notes
67-
68-
if (e.target.offsetHeight + e.target.scrollTop > e.target.scrollHeight - 250 && notes.length > this.state.range * 20 + 20) {
69-
this.setState({
70-
range: this.state.range + 1
71-
})
72-
}
7359
}
7460

7561
componentWillUnmount () {
@@ -82,6 +68,7 @@ class NoteList extends React.Component {
8268

8369
componentDidUpdate (prevProps) {
8470
let { location } = this.props
71+
8572
if (this.notes.length > 0 && location.query.key == null) {
8673
let { router } = this.context
8774
router.replace({
@@ -325,7 +312,7 @@ class NoteList extends React.Component {
325312
this.notes = notes = this.getNotes()
326313
.sort(sortFunc)
327314

328-
let noteList = notes.slice(0, 20 + 20 * this.state.range)
315+
let noteList = notes
329316
.map((note) => {
330317
if (note == null) return null
331318
let tagElements = _.isArray(note.tags)
@@ -424,7 +411,6 @@ class NoteList extends React.Component {
424411
ref='list'
425412
tabIndex='-1'
426413
onKeyDown={(e) => this.handleNoteListKeyDown(e)}
427-
onScroll={(e) => this.handleScroll(e)}
428414
>
429415
{noteList}
430416
</div>

browser/main/SideNav/StorageItem.js

Lines changed: 125 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ import React, { PropTypes } from 'react'
22
import CSSModules from 'browser/lib/CSSModules'
33
import styles from './StorageItem.styl'
44
import { hashHistory } from 'react-router'
5+
import modal from 'browser/main/lib/modal'
6+
import CreateFolderModal from 'browser/main/modals/CreateFolderModal'
7+
import RenameFolderModal from 'browser/main/modals/RenameFolderModal'
8+
import dataApi from 'browser/main/lib/dataApi'
9+
10+
const { remote } = require('electron')
11+
const { Menu, MenuItem, dialog } = remote
512

613
class StorageItem extends React.Component {
714
constructor (props) {
@@ -12,12 +19,59 @@ class StorageItem extends React.Component {
1219
}
1320
}
1421

22+
handleHeaderContextMenu (e) {
23+
let menu = new Menu()
24+
menu.append(new MenuItem({
25+
label: 'Add Folder',
26+
click: (e) => this.handleAddFolderButtonClick(e)
27+
}))
28+
menu.append(new MenuItem({
29+
type: 'separator'
30+
}))
31+
menu.append(new MenuItem({
32+
label: 'Unlink Storage',
33+
click: (e) => this.handleUnlinkStorageClick(e)
34+
}))
35+
menu.popup()
36+
}
37+
38+
handleUnlinkStorageClick (e) {
39+
let index = dialog.showMessageBox(remote.getCurrentWindow(), {
40+
type: 'warning',
41+
message: 'Unlink Storage',
42+
detail: 'This work will just detatches a storage from Boostnote. (Any data won\'t be deleted.)',
43+
buttons: ['Confirm', 'Cancel']
44+
})
45+
46+
if (index === 0) {
47+
let { storage, dispatch } = this.props
48+
dataApi.removeStorage(storage.key)
49+
.then(() => {
50+
dispatch({
51+
type: 'REMOVE_STORAGE',
52+
storageKey: storage.key
53+
})
54+
})
55+
.catch((err) => {
56+
throw err
57+
})
58+
}
59+
}
60+
1561
handleToggleButtonClick (e) {
1662
this.setState({
1763
isOpen: !this.state.isOpen
1864
})
1965
}
2066

67+
handleAddFolderButtonClick (e) {
68+
let { storage } = this.props
69+
70+
modal.open(CreateFolderModal, {
71+
storage
72+
})
73+
}
74+
2175
handleHeaderInfoClick (e) {
2276
let { storage } = this.props
2377
hashHistory.push('/storages/' + storage.key)
@@ -30,22 +84,78 @@ class StorageItem extends React.Component {
3084
}
3185
}
3286

87+
handleFolderButtonContextMenu (e, folder) {
88+
let menu = new Menu()
89+
menu.append(new MenuItem({
90+
label: 'Rename Folder',
91+
click: (e) => this.handleRenameFolderClick(e, folder)
92+
}))
93+
menu.append(new MenuItem({
94+
type: 'separator'
95+
}))
96+
menu.append(new MenuItem({
97+
label: 'Delete Folder',
98+
click: (e) => this.handleFolderDeleteClick(e, folder)
99+
}))
100+
menu.popup()
101+
}
102+
103+
handleRenameFolderClick (e, folder) {
104+
let { storage } = this.props
105+
modal.open(RenameFolderModal, {
106+
storage,
107+
folder
108+
})
109+
}
110+
111+
handleFolderDeleteClick (e, folder) {
112+
let index = dialog.showMessageBox(remote.getCurrentWindow(), {
113+
type: 'warning',
114+
message: 'Delete Folder',
115+
detail: 'This work will deletes all notes in the folder and can not be undone.',
116+
buttons: ['Confirm', 'Cancel']
117+
})
118+
119+
if (index === 0) {
120+
let { storage, dispatch } = this.props
121+
dataApi
122+
.deleteFolder(storage.key, folder.key)
123+
.then((data) => {
124+
dispatch({
125+
type: 'DELETE_FOLDER',
126+
storage: data.storage,
127+
folderKey: data.folderKey
128+
})
129+
})
130+
}
131+
}
132+
33133
render () {
34-
let { storage, location, isFolded } = this.props
134+
let { storage, location, isFolded, data } = this.props
135+
let { folderNoteMap } = data
35136
let folderList = storage.folders.map((folder) => {
36137
let isActive = location.pathname.match(new RegExp('\/storages\/' + storage.key + '\/folders\/' + folder.key))
138+
let noteSet = folderNoteMap.get(storage.key + '-' + folder.key)
139+
140+
let noteCount = noteSet != null
141+
? noteSet.size
142+
: 0
37143
return <button styleName={isActive
38144
? 'folderList-item--active'
39145
: 'folderList-item'
40146
}
41147
key={folder.key}
42148
onClick={(e) => this.handleFolderButtonClick(folder.key)(e)}
149+
onContextMenu={(e) => this.handleFolderButtonContextMenu(e, folder)}
43150
>
44151
<span styleName='folderList-item-name'
45152
style={{borderColor: folder.color}}
46153
>
47154
{isFolded ? folder.name.substring(0, 1) : folder.name}
48155
</span>
156+
{!isFolded &&
157+
<span styleName='folderList-item-noteCount'>{noteCount}</span>
158+
}
49159
{isFolded &&
50160
<span styleName='folderList-item-tooltip'>
51161
{folder.name}
@@ -61,9 +171,11 @@ class StorageItem extends React.Component {
61171
key={storage.key}
62172
>
63173
<div styleName={isActive
64-
? 'header--active'
65-
: 'header'
66-
}>
174+
? 'header--active'
175+
: 'header'
176+
}
177+
onContextMenu={(e) => this.handleHeaderContextMenu(e)}
178+
>
67179
<button styleName='header-toggleButton'
68180
onMouseDown={(e) => this.handleToggleButtonClick(e)}
69181
>
@@ -73,21 +185,24 @@ class StorageItem extends React.Component {
73185
}
74186
/>
75187
</button>
188+
189+
{!isFolded &&
190+
<button styleName='header-addFolderButton'
191+
onClick={(e) => this.handleAddFolderButtonClick(e)}
192+
>
193+
<i className='fa fa-plus'/>
194+
</button>
195+
}
196+
76197
<button styleName='header-info'
77198
onClick={(e) => this.handleHeaderInfoClick(e)}
78199
>
79200
<span styleName='header-info-name'>
80201
{isFolded ? storage.name.substring(0, 1) : storage.name}
81202
</span>
82-
<span styleName='header-info-path'>
83-
({storage.path})
84-
</span>
85203
{isFolded &&
86204
<span styleName='header-info--folded-tooltip'>
87205
{storage.name}
88-
<span styleName='header-info--folded-tooltip-path'>
89-
({storage.path})
90-
</span>
91206
</span>
92207
}
93208
</button>

browser/main/SideNav/StorageItem.styl

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,22 @@
99
background-color $ui-button--hover-backgroundColor
1010
&:active
1111
.header-toggleButton
12+
.header-addFolderButton
1213
color white
14+
&:active
15+
color $ui-active-color
16+
1317
.header--active
1418
@extend .header
1519
.header-info
1620
color $ui-button--active-color
1721
background-color $ui-button--active-backgroundColor
1822
.header-toggleButton
23+
.header-addFolderButton
1924
color white
2025
&:active
26+
&:hover
27+
&:hover:active
2128
color white
2229

2330
.header-toggleButton
@@ -55,8 +62,23 @@
5562
.header-info-path
5663
font-size 10px
5764
margin 0 5px
65+
66+
.header-addFolderButton
67+
position absolute
68+
right 0
69+
width 25px
70+
height 26px
71+
padding 0
72+
border none
73+
color $ui-inactive-text-color
74+
background-color transparent
75+
&:hover
76+
color $ui-text-color
77+
&:active
78+
color $ui-active-color
79+
5880
.folderList-item
59-
display block
81+
display flex
6082
width 100%
6183
height 26px
6284
background-color transparent
@@ -74,21 +96,31 @@
7496
&:active
7597
color $ui-button--active-color
7698
background-color $ui-button--active-backgroundColor
99+
77100
.folderList-item--active
78101
@extend .folderList-item
79102
color $ui-button--active-color
80103
background-color $ui-button--active-backgroundColor
81104
&:hover
82105
color $ui-button--active-color
83106
background-color $ui-button--active-backgroundColor
107+
84108
.folderList-item-name
85109
display block
110+
flex 1
86111
padding 0 10px
87112
height 26px
88113
line-height 26px
89114
border-width 0 0 0 6px
90115
border-style solid
91116
border-color transparent
117+
118+
.folderList-item-noteCount
119+
float right
120+
line-height 26px
121+
padding-right 5px
122+
font-size 12px
123+
92124
.folderList-item-tooltip
93125
tooltip()
94126
position fixed
@@ -102,6 +134,7 @@
102134
height 26px
103135
margin-top -26px
104136
line-height 26px
137+
105138
.root--folded
106139
@extend .root
107140
.header
@@ -133,3 +166,17 @@
133166
opacity 1
134167
.folderList-item-name
135168
padding-left 14px
169+
body[data-theme="dark"]
170+
.header-toggleButton
171+
.header-addFolderButton
172+
color $ui-dark-inactive-text-color
173+
&:hover
174+
color $ui-dark-text-color
175+
&:active
176+
color $ui-dark-active-color
177+
.header--active
178+
.header-toggleButton
179+
.header-addFolderButton
180+
color white
181+
&:active
182+
color white

browser/main/SideNav/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class SideNav extends React.Component {
3636
}
3737

3838
render () {
39-
let { data, location, config } = this.props
39+
let { data, location, config, dispatch } = this.props
4040

4141
let isFolded = config.isSideNavFolded
4242
let isHomeActive = location.pathname.match(/^\/home$/)
@@ -46,8 +46,10 @@ class SideNav extends React.Component {
4646
return <StorageItem
4747
key={storage.key}
4848
storage={storage}
49+
data={data}
4950
location={location}
5051
isFolded={isFolded}
52+
dispatch={dispatch}
5153
/>
5254
})
5355
let style = {}

0 commit comments

Comments
 (0)