Skip to content

Commit 4c486c3

Browse files
authored
Merge pull request BoostIO#110 from BoostIO/ui-improvement
Ui improvement for v0.6.5
2 parents 22cf744 + 9f4dd90 commit 4c486c3

16 files changed

Lines changed: 411 additions & 76 deletions

File tree

browser/components/MarkdownPreview.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ export default class MarkdownPreview extends React.Component {
140140
`
141141

142142
this.refs.root.contentWindow.document.body.setAttribute('data-theme', theme)
143-
this.refs.root.contentWindow.document.body.innerHTML = markdown(value)
143+
this.refs.root.contentWindow.document.body.innerHTML = markdown.render(value)
144144

145145
Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
146146
el.addEventListener('click', this.anchorClickHandler)

browser/lib/markdown.js

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,40 @@ md.renderer.render = function render (tokens, options, env) {
129129
}
130130
window.md = md
131131

132-
export default function markdown (content) {
133-
if (!_.isString(content)) content = ''
132+
function strip (input) {
133+
var output = input
134+
try {
135+
output = output
136+
.replace(/^([\s\t]*)([\*\-\+]|\d\.)\s+/gm, '$1')
137+
.replace(/\n={2,}/g, '\n')
138+
.replace(/~~/g, '')
139+
.replace(/`{3}.*\n/g, '')
140+
.replace(/<(.*?)>/g, '$1')
141+
.replace(/^[=\-]{2,}\s*$/g, '')
142+
.replace(/\[\^.+?\](\: .*?$)?/g, '')
143+
.replace(/\s{0,2}\[.*?\]: .*?$/g, '')
144+
.replace(/\!\[.*?\][\[\(].*?[\]\)]/g, '')
145+
.replace(/\[(.*?)\][\[\(].*?[\]\)]/g, '$1')
146+
.replace(/>/g, '')
147+
.replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g, '')
148+
.replace(/^\#{1,6}\s*([^#]*)\s*(\#{1,6})?/gm, '$1')
149+
.replace(/([\*_]{1,3})(\S.*?\S)\1/g, '$2')
150+
.replace(/(`{3,})(.*?)\1/gm, '$2')
151+
.replace(/^-{3,}\s*$/g, '')
152+
.replace(/`(.+?)`/g, '$1')
153+
.replace(/\n{2,}/g, '\n\n')
154+
} catch (e) {
155+
console.error(e)
156+
return input
157+
}
158+
return output
159+
}
134160

135-
return md.render(content)
161+
const markdown = {
162+
render: function markdown (content) {
163+
if (!_.isString(content)) content = ''
164+
return md.render(content)
165+
},
166+
strip
136167
}
168+
export default markdown

browser/main/Detail/FolderSelect.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ class FolderSelect extends React.Component {
200200

201201
let currentOption = options.filter((option) => option.storage.key === storageKey && option.folder.key === folderKey)[0]
202202

203+
if (this.state.search.trim().length > 0) {
204+
let filter = new RegExp('^' + _.escapeRegExp(this.state.search), 'i')
205+
options = options.filter((option) => filter.test(option.folder.name))
206+
}
207+
203208
let optionList = options
204209
.map((option, index) => {
205210
return (

browser/main/Detail/FolderSelect.styl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,13 @@
5757

5858
.search-optionList
5959
position fixed
60+
max-height 450px
61+
overflow auto
6062
z-index 200
6163
background-color white
6264
border-radius 2px
6365
box-shadow 2px 2px 10px gray
6466

65-
6667
.search-optionList-item
6768
height 34px
6869
width 250px

browser/main/Detail/MarkdownNoteDetail.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import FolderSelect from './FolderSelect'
88
import dataApi from 'browser/main/lib/dataApi'
99
import { hashHistory } from 'react-router'
1010
import ee from 'browser/main/lib/eventEmitter'
11+
import markdown from 'browser/lib/markdown'
1112

1213
const electron = require('electron')
1314
const { remote } = electron
@@ -72,6 +73,8 @@ class MarkdownNoteDetail extends React.Component {
7273
}
7374
}
7475

76+
title = markdown.strip(title)
77+
7578
return title
7679
}
7780

browser/main/Detail/SnippetNoteDetail.js

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -247,27 +247,39 @@ class SnippetNoteDetail extends React.Component {
247247
})
248248
}
249249

250-
handleTabButtonClick (index) {
251-
return (e) => {
252-
this.setState({
253-
snippetIndex: index
254-
})
255-
}
250+
handleTabButtonClick (e, index) {
251+
this.setState({
252+
snippetIndex: index
253+
})
256254
}
257255

258-
handleTabDeleteButtonClick (index) {
259-
return (e) => {
260-
if (this.state.note.snippets.length > 1) {
261-
let snippets = this.state.note.snippets.slice()
262-
snippets.splice(index, 1)
263-
this.state.note.snippets = snippets
264-
this.setState({
265-
note: this.state.note
256+
handleTabDeleteButtonClick (e, index) {
257+
if (this.state.note.snippets.length > 1) {
258+
if (this.state.note.snippets[index].content.trim().length > 0) {
259+
let dialogIndex = dialog.showMessageBox(remote.getCurrentWindow(), {
260+
type: 'warning',
261+
message: 'Delete a snippet',
262+
detail: 'This work cannot be undone.',
263+
buttons: ['Confirm', 'Cancel']
266264
})
265+
if (dialogIndex === 0) {
266+
this.deleteSnippetByIndex(index)
267+
}
268+
} else {
269+
this.deleteSnippetByIndex(index)
267270
}
268271
}
269272
}
270273

274+
deleteSnippetByIndex (index) {
275+
let snippets = this.state.note.snippets.slice()
276+
snippets.splice(index, 1)
277+
this.state.note.snippets = snippets
278+
this.setState({
279+
note: this.state.note
280+
})
281+
}
282+
271283
handleNameInputChange (e, index) {
272284
let snippets = this.state.note.snippets.slice()
273285
snippets[index].name = e.target.value
@@ -344,7 +356,7 @@ class SnippetNoteDetail extends React.Component {
344356
key={index}
345357
>
346358
<button styleName='tabList-item-button'
347-
onClick={(e) => this.handleTabButtonClick(index)(e)}
359+
onClick={(e) => this.handleTabButtonClick(e, index)}
348360
>
349361
{snippet.name.trim().length > 0
350362
? snippet.name
@@ -355,7 +367,7 @@ class SnippetNoteDetail extends React.Component {
355367
</button>
356368
{note.snippets.length > 1 &&
357369
<button styleName='tabList-item-deleteButton'
358-
onClick={(e) => this.handleTabDeleteButtonClick(index)(e)}
370+
onClick={(e) => this.handleTabDeleteButtonClick(e, index)}
359371
>
360372
<i className='fa fa-times'/>
361373
</button>

browser/main/Main.js

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ class Main extends React.Component {
2020
let { config } = props
2121

2222
this.state = {
23-
isSliderFocused: false,
24-
listWidth: config.listWidth
23+
isRightSliderFocused: false,
24+
listWidth: config.listWidth,
25+
navWidth: config.listWidth,
26+
isLeftSliderFocused: false
2527
}
2628
}
2729

@@ -49,17 +51,24 @@ class Main extends React.Component {
4951
})
5052
}
5153

52-
handleSlideMouseDown (e) {
54+
handleLeftSlideMouseDown (e) {
5355
e.preventDefault()
5456
this.setState({
55-
isSliderFocused: true
57+
isLeftSliderFocused: true
58+
})
59+
}
60+
61+
handleRightSlideMouseDown (e) {
62+
e.preventDefault()
63+
this.setState({
64+
isRightSliderFocused: true
5665
})
5766
}
5867

5968
handleMouseUp (e) {
60-
if (this.state.isSliderFocused) {
69+
if (this.state.isRightSliderFocused) {
6170
this.setState({
62-
isSliderFocused: false
71+
isRightSliderFocused: false
6372
}, () => {
6473
let { dispatch } = this.props
6574
let newListWidth = this.state.listWidth
@@ -71,10 +80,24 @@ class Main extends React.Component {
7180
})
7281
})
7382
}
83+
if (this.state.isLeftSliderFocused) {
84+
this.setState({
85+
isLeftSliderFocused: false
86+
}, () => {
87+
let { dispatch } = this.props
88+
let navWidth = this.state.navWidth
89+
// TODO: ConfigManager should dispatch itself.
90+
ConfigManager.set({listWidth: navWidth})
91+
dispatch({
92+
type: 'SET_NAV_WIDTH',
93+
listWidth: navWidth
94+
})
95+
})
96+
}
7497
}
7598

7699
handleMouseMove (e) {
77-
if (this.state.isSliderFocused) {
100+
if (this.state.isRightSliderFocused) {
78101
let offset = this.refs.body.getBoundingClientRect().left
79102
let newListWidth = e.pageX - offset
80103
if (newListWidth < 10) {
@@ -86,6 +109,17 @@ class Main extends React.Component {
86109
listWidth: newListWidth
87110
})
88111
}
112+
if (this.state.isLeftSliderFocused) {
113+
let navWidth = e.pageX
114+
if (navWidth < 80) {
115+
navWidth = 80
116+
} else if (navWidth > 600) {
117+
navWidth = 600
118+
}
119+
this.setState({
120+
navWidth: navWidth
121+
})
122+
}
89123
}
90124

91125
render () {
@@ -105,9 +139,20 @@ class Main extends React.Component {
105139
'config',
106140
'location'
107141
])}
142+
width={this.state.navWidth}
108143
/>
144+
{!config.isSideNavFolded &&
145+
<div styleName={this.state.isLeftSliderFocused ? 'slider--active' : 'slider'}
146+
style={{left: this.state.navWidth - 1}}
147+
onMouseDown={(e) => this.handleLeftSlideMouseDown(e)}
148+
draggable='false'
149+
>
150+
<div styleName='slider-hitbox'/>
151+
</div>
152+
}
109153
<div styleName={config.isSideNavFolded ? 'body--expanded' : 'body'}
110154
ref='body'
155+
style={{left: config.isSideNavFolded ? 44 : this.state.navWidth}}
111156
>
112157
<TopBar style={{width: this.state.listWidth}}
113158
{..._.pick(this.props, [
@@ -127,9 +172,9 @@ class Main extends React.Component {
127172
'location'
128173
])}
129174
/>
130-
<div styleName={this.state.isSliderFocused ? 'slider--active' : 'slider'}
175+
<div styleName={this.state.isRightSliderFocused ? 'slider--active' : 'slider'}
131176
style={{left: this.state.listWidth}}
132-
onMouseDown={(e) => this.handleSlideMouseDown(e)}
177+
onMouseDown={(e) => this.handleRightSlideMouseDown(e)}
133178
draggable='false'
134179
>
135180
<div styleName='slider-hitbox'/>
@@ -143,7 +188,7 @@ class Main extends React.Component {
143188
'params',
144189
'location'
145190
])}
146-
ignorePreviewPointerEvents={this.state.isSliderFocused}
191+
ignorePreviewPointerEvents={this.state.isRightSliderFocused}
147192
/>
148193
</div>
149194
<StatusBar

0 commit comments

Comments
 (0)