diff --git a/.boostnoterc.sample b/.boostnoterc.sample
index 2caa2c1a..8419061d 100644
--- a/.boostnoterc.sample
+++ b/.boostnoterc.sample
@@ -10,7 +10,6 @@
"theme": "monokai"
},
"hotkey": {
- "toggleFinder": "Cmd + Alt + S",
"toggleMain": "Cmd + Alt + L"
},
"isSideNavFolded": false,
diff --git a/.travis.yml b/.travis.yml
index 013169e8..c68d1063 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,6 @@
language: node_js
node_js:
- - stable
- - lts/*
+ - 6
script:
- npm run lint && npm run test
- 'if [[ ${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} = "master" ]]; then npm install -g grunt npm@5.2 && grunt pre-build; fi'
diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js
index d50f3d8e..7e59ea65 100644
--- a/browser/components/CodeEditor.js
+++ b/browser/components/CodeEditor.js
@@ -51,9 +51,10 @@ export default class CodeEditor extends React.Component {
componentDidMount () {
this.value = this.props.value
+
this.editor = CodeMirror(this.refs.root, {
value: this.props.value,
- lineNumbers: true,
+ lineNumbers: this.props.displayLineNumbers,
lineWrapping: true,
theme: this.props.theme,
indentUnit: this.props.indentSize,
@@ -71,7 +72,7 @@ export default class CodeEditor extends React.Component {
if (cm.somethingSelected()) cm.indentSelection('add')
else {
const tabs = cm.getOption('indentWithTabs')
- if (line.trimLeft().match(/^(-|\*|\+) (\[( |x)\] )?$/)) {
+ if (line.trimLeft().match(/^(-|\*|\+) (\[( |x)] )?$/)) {
cm.execCommand('goLineStart')
if (tabs) {
cm.execCommand('insertTab')
@@ -156,6 +157,10 @@ export default class CodeEditor extends React.Component {
this.editor.setOption('indentWithTabs', this.props.indentType !== 'space')
}
+ if (prevProps.displayLineNumbers !== this.props.displayLineNumbers) {
+ this.editor.setOption('lineNumbers', this.props.displayLineNumbers)
+ }
+
if (prevProps.scrollPastEnd !== this.props.scrollPastEnd) {
this.editor.setOption('scrollPastEnd', this.props.scrollPastEnd)
}
diff --git a/browser/components/MarkdownEditor.js b/browser/components/MarkdownEditor.js
index 62c4414a..19f9e280 100644
--- a/browser/components/MarkdownEditor.js
+++ b/browser/components/MarkdownEditor.js
@@ -242,6 +242,7 @@ class MarkdownEditor extends React.Component {
fontSize={editorFontSize}
indentType={config.editor.indentType}
indentSize={editorIndentSize}
+ displayLineNumbers={config.editor.displayLineNumbers}
scrollPastEnd={config.editor.scrollPastEnd}
storageKey={storageKey}
fetchUrlTitle={config.editor.fetchUrlTitle}
diff --git a/browser/components/MarkdownSplitEditor.js b/browser/components/MarkdownSplitEditor.js
index 15498662..38ce903c 100644
--- a/browser/components/MarkdownSplitEditor.js
+++ b/browser/components/MarkdownSplitEditor.js
@@ -62,6 +62,7 @@ class MarkdownSplitEditor extends React.Component {
keyMap={config.editor.keyMap}
fontFamily={config.editor.fontFamily}
fontSize={editorFontSize}
+ displayLineNumbers={config.editor.displayLineNumbers}
indentType={config.editor.indentType}
indentSize={editorIndentSize}
scrollPastEnd={config.editor.scrollPastEnd}
diff --git a/browser/components/TodoListPercentage.styl b/browser/components/TodoListPercentage.styl
index d4cb7485..329663f9 100644
--- a/browser/components/TodoListPercentage.styl
+++ b/browser/components/TodoListPercentage.styl
@@ -1,6 +1,6 @@
.percentageBar
position absolute
- top 50px
+ top 72px
right 0px
left 0px
background-color #DADFE1
diff --git a/browser/finder/FinderMain.styl b/browser/finder/FinderMain.styl
deleted file mode 100644
index 8ba7c3b9..00000000
--- a/browser/finder/FinderMain.styl
+++ /dev/null
@@ -1,156 +0,0 @@
-$search-height = 50px
-$nav-width = 175px
-$list-width = 250px
-
-.root
- absolute top left right bottom
-
-.search
- height $search-height
- padding 10px
- box-sizing border-box
- border-bottom $ui-border
- text-align center
-
-.search-input
- height 30px
- width 100%
- margin 0 auto
- font-size 18px
- border none
- outline none
- text-align center
- background-color transparent
-
-.result
- absolute left right bottom
- top $search-height
- background-color $ui-noteDetail-backgroundColor
-
-.result-nav
- user-select none
- absolute left top bottom
- width $nav-width
- background-color $ui-backgroundColor
-
-.result-nav-filter
- margin-bottom 10px
-
-.result-nav-filter-option
- height 25px
- line-height 25px
- padding 0 10px
- label
- cursor pointer
-
-.result-nav-menu
- navButtonColor()
- height 32px
- padding 0 10px
- font-size 14px
- width 100%
- outline none
- text-align left
- line-height 32px
- box-sizing border-box
- cursor pointer
-
-.result-nav-menu--active
- @extend .result-nav-menu
- background-color $ui-button--active-backgroundColor
- color $ui-button--active-color
- &:hover
- background-color $ui-button--active-backgroundColor
-
-.result-nav-storageList
- absolute bottom left right
- top 110px + 32px + 10px + 10px + 20px
- overflow-y auto
-
-.result-list
- user-select none
- absolute top bottom
- left $nav-width
- width $list-width
- box-sizing border-box
- overflow-y auto
- box-shadow 2px 0 15px -8px #b1b1b1
- z-index 1
-
-.result-detail
- absolute top bottom right
- left $nav-width + $list-width
- background-color $ui-noteDetail-backgroundColor
-
-body[data-theme="dark"]
- .root
- background-color $ui-dark-backgroundColor
- .search
- border-color $ui-dark-borderColor
- .search-input
- color $ui-dark-text-color
-
- .result
- background-color $ui-dark-noteList-backgroundColor
-
- .result-nav
- background-color $ui-dark-backgroundColor
- label
- color $ui-dark-text-color
-
- .result-nav-menu
- navDarkButtonColor()
-
- .result-nav-menu--active
- background-color $ui-dark-button--active-backgroundColor
- color $ui-dark-button--active-color
- &:hover
- background-color $ui-dark-button--active-backgroundColor
-
- .result-list
- border-color $ui-dark-borderColor
- box-shadow none
- top 0
-
- .result-detail
- absolute top bottom right
- left $nav-width + $list-width
- background-color $ui-dark-noteDetail-backgroundColor
-
-
-
-body[data-theme="solarized-dark"]
- .root
- background-color $ui-solarized-dark-backgroundColor
- .search
- border-color $ui-solarized-dark-borderColor
- .search-input
- color $ui-dark-text-color
-
- .result
- background-color $ui-solarized-dark-backgroundColor
-
- .result-nav
- background-color $ui-solarized-dark-backgroundColor
- label
- color $ui-dark-text-color
-
- .result-nav-menu
- navDarkButtonColor()
-
- .result-nav-menu--active
- background-color $ui-solarized-dark-button-backgroundColor
- color $ui-dark-button--active-color
- &:hover
- background-color $ui-dark-button--active-backgroundColor
-
- .result-list
- border-color $ui-solarized-dark-borderColor
- box-shadow none
- top 0
-
- .result-detail
- absolute top bottom right
- left $nav-width + $list-width
- background-color $ui-solarized-dark-backgroundColor
-
diff --git a/browser/finder/NoteDetail.js b/browser/finder/NoteDetail.js
index 1325e87f..e69de29b 100644
--- a/browser/finder/NoteDetail.js
+++ b/browser/finder/NoteDetail.js
@@ -1,212 +0,0 @@
-import React from 'react'
-import CSSModules from 'browser/lib/CSSModules'
-import styles from './NoteDetail.styl'
-import MarkdownPreview from 'browser/components/MarkdownPreview'
-import MarkdownEditor from 'browser/components/MarkdownEditor'
-import CodeEditor from 'browser/components/CodeEditor'
-import CodeMirror from 'codemirror'
-import 'codemirror-mode-elixir'
-import { findStorage } from 'browser/lib/findStorage'
-
-const electron = require('electron')
-const { clipboard } = electron
-const path = require('path')
-
-function pass (name) {
- switch (name) {
- case 'ejs':
- return 'Embedded Javascript'
- case 'html_ruby':
- return 'Embedded Ruby'
- case 'objectivec':
- return 'Objective C'
- case 'text':
- return 'Plain Text'
- default:
- return name
- }
-}
-function notify (title, options) {
- if (global.process.platform === 'win32') {
- options.icon = path.join('file://', global.__dirname, '../../resources/app.png')
- }
- return new window.Notification(title, options)
-}
-
-class NoteDetail extends React.Component {
- constructor (props) {
- super(props)
-
- this.state = {
- snippetIndex: 0
- }
- }
-
- componentWillReceiveProps (nextProps) {
- if (nextProps.note !== this.props.note) {
- this.setState({
- snippetIndex: 0
- }, () => {
- if (nextProps.note.type === 'SNIPPET_NOTE') {
- nextProps.note.snippets.forEach((snippet, index) => {
- this.refs['code-' + index].reload()
- })
- }
- })
- }
- }
-
- selectPriorSnippet () {
- const { note } = this.props
- if (note.type === 'SNIPPET_NOTE' && note.snippets.length > 1) {
- this.setState({
- snippetIndex: (this.state.snippetIndex + note.snippets.length - 1) % note.snippets.length
- })
- }
- }
-
- selectNextSnippet () {
- const { note } = this.props
- if (note.type === 'SNIPPET_NOTE' && note.snippets.length > 1) {
- this.setState({
- snippetIndex: (this.state.snippetIndex + 1) % note.snippets.length
- })
- }
- }
-
- saveToClipboard () {
- const { note } = this.props
-
- if (note.type === 'MARKDOWN_NOTE') {
- clipboard.writeText(note.content)
- } else {
- clipboard.writeText(note.snippets[this.state.snippetIndex].content)
- }
-
- notify('Saved to Clipboard!', {
- body: 'Paste it wherever you want!',
- silent: true
- })
- }
-
- handleTabButtonClick (e, index) {
- this.setState({
- snippetIndex: index
- })
- }
-
- render () {
- const { note, config } = this.props
- if (note == null) {
- return (
-
- )
- }
-
- let editorFontSize = parseInt(config.editor.fontSize, 10)
- if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
- let editorIndentSize = parseInt(config.editor.indentSize, 10)
- if (!(editorFontSize > 0 && editorFontSize < 132)) editorIndentSize = 4
-
- const storage = findStorage(note.storage)
-
- if (note.type === 'SNIPPET_NOTE') {
- const tabList = note.snippets.map((snippet, index) => {
- const isActive = this.state.snippetIndex === index
- return
-
-
- })
-
- const viewList = note.snippets.map((snippet, index) => {
- const isActive = this.state.snippetIndex === index
-
- let syntax = CodeMirror.findModeByName(pass(snippet.mode))
- if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text')
-
- return
- {snippet.mode === 'markdown'
- ?
- :
- }
-
- })
-
- return (
-
-
-
-
-
- {tabList}
-
- {viewList}
-
- )
- }
-
- return (
-
- )
- }
-}
-
-NoteDetail.propTypes = {
-}
-
-export default CSSModules(NoteDetail, styles)
diff --git a/browser/finder/NoteDetail.styl b/browser/finder/NoteDetail.styl
deleted file mode 100644
index dfa4948e..00000000
--- a/browser/finder/NoteDetail.styl
+++ /dev/null
@@ -1,129 +0,0 @@
-@import('../main/Detail/DetailVars.styl')
-
-.root
- absolute top bottom left right
- bottom 30px
- margin 0 25px
- height 100%
- width 365px
- background-color $ui-noteDetail-backgroundColor
-
-.description
- absolute top left right
- height 80px
- box-sizing border-box
-
-.description-textarea
- display block
- height 100%
- width 100%
- resize none
- border none
- padding 10px
- line-height 1.6
- box-sizing border-box
- background-color $ui-noteDetail-backgroundColor
-
-.tabList
- absolute left right
- top 80px
- box-sizing border-box
- height 30px
- display flex
- background-color $ui-noteDetail-backgroundColor
-
-.tabList-item
- position relative
- flex 1
- overflow hidden
- &:hover
- background-color $ui-button--hover-backgroundColorg
-
-.tabList-item--active
- @extend .tabList-item
- border-bottom $ui-border
-
-.tabList-item-button
- width 100%
- height 29px
- overflow ellipsis
- text-align left
- padding-right 30px
- padding-left 10px
- border none
- background-color transparent
- transition 0.15s
- &:hover
- background-color $ui-button--hover-backgroundColor
-
-.tabView
- absolute left right bottom
- top 130px
-
-.tabView-content
- absolute top left right bottom
- box-sizing border-box
- height 100%
- width 100%
-
-body[data-theme="dark"]
- .root
- background-color $ui-dark-noteDetail-backgroundColor
-
- .description
- border-color $ui-dark-borderColor
- background-color $ui-dark-noteDetail-backgroundColor
-
- .description-textarea
- background-color $ui-dark-noteDetail-backgroundColor
- color white
-
- .tabList
- background-color $ui-dark-noteDetail-backgroundColor
-
- .tabList-item
- border-color $ui-dark-borderColor
- &:hover
- background-color $ui-dark-button--hover-backgroundColor
-
- .tabList-item-button
- border none
- color $ui-dark-text-color
- background-color transparent
- transition color background-color 0.15s
- border-left 4px solid transparent
- &:hover
- color white
- background-color $ui-dark-button--hover-backgroundColor
-
-
-body[data-theme="solarized-dark"]
- .root
- background-color $ui-solarized-dark-backgroundColor
-
- .description
- border-color $ui-dark-borderColor
- background-color $ui-solarized-dark-backgroundColor
-
- .description-textarea
- background-color $ui-solarized-dark-backgroundColor
- color white
-
- .tabList
- background-color $ui-solarized-dark-backgroundColor
-
- .tabList-item
- border-color $ui-dark-borderColor
- &:hover
- background-color $ui-dark-button--hover-backgroundColor
-
- .tabList-item-button
- border none
- color $ui-dark-text-color
- background-color transparent
- transition color background-color 0.15s
- border-left 4px solid transparent
- &:hover
- color white
- background-color $ui-dark-button--hover-backgroundColor
-
diff --git a/browser/finder/NoteList.js b/browser/finder/NoteList.js
deleted file mode 100644
index 17af8cf8..00000000
--- a/browser/finder/NoteList.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import React from 'react'
-import NoteItem from 'browser/components/NoteItem'
-import moment from 'moment'
-
-class NoteList extends React.Component {
- constructor (props) {
- super(props)
-
- this.state = {
- range: 0
- }
- }
-
- componentWillReceiveProps (nextProps) {
- if (this.props.search !== nextProps.search) {
- this.resetScroll()
- }
- }
-
- componentDidUpdate () {
- const { index } = this.props
-
- if (index > -1) {
- const list = this.refs.root
- const item = list.childNodes[index]
- if (item == null) return null
-
- const overflowBelow = item.offsetTop + item.clientHeight - list.clientHeight - list.scrollTop > 0
- if (overflowBelow) {
- list.scrollTop = item.offsetTop + item.clientHeight - list.clientHeight
- }
- const overflowAbove = list.scrollTop > item.offsetTop
- if (overflowAbove) {
- list.scrollTop = item.offsetTop
- }
- }
- }
-
- resetScroll () {
- this.refs.root.scrollTop = 0
- this.setState({
- range: 0
- })
- }
-
- handleScroll (e) {
- const { notes } = this.props
-
- if (e.target.offsetHeight + e.target.scrollTop > e.target.scrollHeight - 100 && notes.length > this.state.range * 10 + 10) {
- this.setState({
- range: this.state.range + 1
- })
- }
- }
-
- render () {
- const { notes, index } = this.props
-
- const notesList = notes
- .slice(0, 10 + 10 * this.state.range)
- .map((note, _index) => {
- const isActive = (index === _index)
- const key = `${note.storage}-${note.key}`
- const dateDisplay = moment(note.updatedAt).fromNow()
-
- return (
- this.props.handleNoteClick(e, _index)}
- />
- )
- })
- return (
- this.handleScroll(e)}
- ref='root'
- >
- {notesList}
-
- )
- }
-}
-
-NoteList.propTypes = {
-}
-
-export default NoteList
diff --git a/browser/finder/StorageSection.js b/browser/finder/StorageSection.js
deleted file mode 100644
index e775743e..00000000
--- a/browser/finder/StorageSection.js
+++ /dev/null
@@ -1,77 +0,0 @@
-import React from 'react'
-import CSSModules from 'browser/lib/CSSModules'
-import styles from './StorageSection.styl'
-import StorageItem from 'browser/components/StorageItem'
-
-class StorageSection extends React.Component {
- constructor (props) {
- super(props)
-
- this.state = {
- isOpen: true
- }
- }
-
- handleToggleButtonClick (e) {
- this.setState({
- isOpen: !this.state.isOpen
- })
- }
-
- handleHeaderClick (e) {
- const { storage } = this.props
- this.props.handleStorageButtonClick(e, storage.key)
- }
-
- handleFolderClick (e, folder) {
- const { storage } = this.props
- this.props.handleFolderButtonClick(e, storage.key, folder.key)
- }
-
- render () {
- const { storage, filter } = this.props
- const folderList = storage.folders
- .map(folder => (
- this.handleFolderClick(e, folder)}
- folderName={folder.name}
- folderColor={folder.color}
- isFolded={false}
- />
- ))
-
- return (
-
-
-
-
-
- {this.state.isOpen &&
-
- {folderList}
-
- }
-
- )
- }
-}
-
-StorageSection.propTypes = {
-}
-
-export default CSSModules(StorageSection, styles)
diff --git a/browser/finder/StorageSection.styl b/browser/finder/StorageSection.styl
deleted file mode 100644
index df5d792e..00000000
--- a/browser/finder/StorageSection.styl
+++ /dev/null
@@ -1,85 +0,0 @@
-.root
- position relative
-
-.header
- height 26px
-.header-toggleButton
- absolute top left
- width 25px
- height 26px
- navButtonColor()
- border none
- outline none
-.header-name
- display block
- height 26px
- navButtonColor()
- padding 0 10px 0 25px
- font-size 14px
- width 100%
- text-align left
- line-height 26px
- box-sizing border-box
- cursor pointer
- outline none
-
-.header-name--active
- @extend .header-name
- background-color $ui-button--active-backgroundColor
- color $ui-button--active-color
- &:hover
- background-color $ui-button--active-backgroundColor
-
-.folderList-item
- display block
- width 100%
- height 26px
- navButtonColor()
- padding 0 10px 0 25px
- font-size 14px
- width 100%
- text-align left
- line-height 26px
- box-sizing border-box
- cursor pointer
- outline none
- padding 0 10px
- margin 2px 0
- height 26px
- line-height 26px
- border-width 0 0 0 6px
- border-style solid
- border-color transparent
-
-.folderList-item--active
- @extend .folderList-item
- background-color $ui-button--active-backgroundColor
- color $ui-button--active-color
- &:hover
- background-color $ui-button--active-backgroundColor
-
-body[data-theme="dark"]
- .header-toggleButton
- navDarkButtonColor()
- .header-name
- navDarkButtonColor()
-
- .header-name--active
- @extend .header-name
- background-color $ui-button--active-backgroundColor
- color $ui-button--active-color
- &:hover
- background-color $ui-button--active-backgroundColor
-
- .folderList-item
- navDarkButtonColor()
- border-width 0 0 0 6px
- border-style solid
- border-color transparent
-
- .folderList-item--active
- @extend .folderList-item
- background-color $ui-button--active-backgroundColor
- color $ui-button--active-color
- &:hover
- background-color $ui-button--active-backgroundColor
diff --git a/browser/finder/index.js b/browser/finder/index.js
deleted file mode 100644
index ee418f94..00000000
--- a/browser/finder/index.js
+++ /dev/null
@@ -1,357 +0,0 @@
-import PropTypes from 'prop-types'
-import React from 'react'
-import ReactDOM from 'react-dom'
-import { connect, Provider } from 'react-redux'
-import _ from 'lodash'
-import store from './store'
-import CSSModules from 'browser/lib/CSSModules'
-import styles from './FinderMain.styl'
-import StorageSection from './StorageSection'
-import NoteList from './NoteList'
-import NoteDetail from './NoteDetail'
-import SideNavFilter from 'browser/components/SideNavFilter'
-import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
-require('!!style!css!stylus?sourceMap!../main/global.styl')
-require('../lib/customMeta')
-require('./ipcClient.js')
-
-const electron = require('electron')
-const { remote } = electron
-const { Menu } = remote
-
-function hideFinder () {
- const finderWindow = remote.getCurrentWindow()
- if (global.process.platform === 'win32') {
- finderWindow.blur()
- finderWindow.hide()
- }
- if (global.process.platform === 'darwin') {
- Menu.sendActionToFirstResponder('hide:')
- }
- remote.getCurrentWindow().hide()
-}
-
-require('!!style!css!stylus?sourceMap!../styles/finder/index.styl')
-
-class FinderMain extends React.Component {
- constructor (props) {
- super(props)
-
- this.state = {
- search: '',
- index: 0,
- filter: {
- includeSnippet: true,
- includeMarkdown: false,
- type: 'ALL',
- storage: null,
- folder: null
- }
- }
-
- this.focusHandler = (e) => this.handleWindowFocus(e)
- this.blurHandler = (e) => this.handleWindowBlur(e)
- }
-
- componentDidMount () {
- this.refs.search.focus()
- window.addEventListener('focus', this.focusHandler)
- window.addEventListener('blur', this.blurHandler)
- }
-
- componentWillUnmount () {
- window.removeEventListener('focus', this.focusHandler)
- window.removeEventListener('blur', this.blurHandler)
- }
-
- handleWindowFocus (e) {
- this.refs.search.focus()
- }
-
- handleWindowBlur (e) {
- this.setState({
- search: ''
- })
- }
-
- handleKeyDown (e) {
- this.refs.search.focus()
- if (e.keyCode === 9) {
- if (e.shiftKey) {
- this.refs.detail.selectPriorSnippet()
- } else {
- this.refs.detail.selectNextSnippet()
- }
- e.preventDefault()
- }
- if (e.keyCode === 38) {
- this.selectPrevious()
- e.preventDefault()
- }
-
- if (e.keyCode === 40) {
- this.selectNext()
- e.preventDefault()
- }
-
- if (e.keyCode === 13) {
- this.refs.detail.saveToClipboard()
- AwsMobileAnalyticsConfig.recordDynamicCustomEvent('COPY_FINDER')
- hideFinder()
- e.preventDefault()
- }
- if (e.keyCode === 27) {
- hideFinder()
- e.preventDefault()
- }
- if (e.keyCode === 91) {
- return
- }
- }
-
- handleSearchChange (e) {
- this.setState({
- search: e.target.value,
- index: 0
- })
- }
-
- selectArticle (article) {
- this.setState({currentArticle: article})
- }
-
- selectPrevious () {
- if (this.state.index > 0) {
- this.setState({
- index: this.state.index - 1
- })
- }
- }
-
- selectNext () {
- if (this.state.index < this.noteCount - 1) {
- this.setState({
- index: this.state.index + 1
- })
- }
- }
-
- handleOnlySnippetCheckboxChange (e) {
- const { filter } = this.state
- filter.includeSnippet = e.target.checked
- this.setState({
- filter: filter,
- index: 0
- }, () => {
- this.refs.search.focus()
- })
- }
-
- handleOnlyMarkdownCheckboxChange (e) {
- const { filter } = this.state
- filter.includeMarkdown = e.target.checked
- this.refs.list.resetScroll()
- this.setState({
- filter: filter,
- index: 0
- }, () => {
- this.refs.search.focus()
- })
- }
-
- handleAllNotesButtonClick (e) {
- const { filter } = this.state
- filter.type = 'ALL'
- this.refs.list.resetScroll()
- this.setState({
- filter,
- index: 0
- }, () => {
- this.refs.search.focus()
- })
- }
-
- handleStarredButtonClick (e) {
- const { filter } = this.state
- filter.type = 'STARRED'
- this.refs.list.resetScroll()
- this.setState({
- filter,
- index: 0
- }, () => {
- this.refs.search.focus()
- })
- }
-
- handleStorageButtonClick (e, storage) {
- const { filter } = this.state
- filter.type = 'STORAGE'
- filter.storage = storage
- this.refs.list.resetScroll()
- this.setState({
- filter,
- index: 0
- }, () => {
- this.refs.search.focus()
- })
- }
-
- handleFolderButtonClick (e, storage, folder) {
- const { filter } = this.state
- filter.type = 'FOLDER'
- filter.storage = storage
- filter.folder = folder
- this.refs.list.resetScroll()
- this.setState({
- filter,
- index: 0
- }, () => {
- this.refs.search.focus()
- })
- }
-
- handleNoteClick (e, index) {
- this.setState({
- index
- }, () => {
- this.refs.search.focus()
- })
- }
-
- render () {
- const { data, config } = this.props
- const { filter, search } = this.state
- const storageList = []
- for (const key in data.storageMap) {
- const storage = data.storageMap[key]
- const item = (
- this.handleStorageButtonClick(e, storage)}
- handleFolderButtonClick={(e, storage, folder) => this.handleFolderButtonClick(e, storage, folder)}
- />
- )
- storageList.push(item)
- }
- let notes = []
- let noteIds
-
- switch (filter.type) {
- case 'STORAGE':
- noteIds = data.storageNoteMap[filter.storage]
- break
- case 'FOLDER':
- noteIds = data.folderNoteMap[filter.storage + '-' + filter.folder]
- break
- case 'STARRED':
- noteIds = data.starredSet
- }
- if (noteIds != null) {
- noteIds.forEach((id) => {
- notes.push(data.noteMap[id])
- })
- } else {
- for (const key in data.noteMap) {
- notes.push(data.noteMap[key])
- }
- }
-
- if (!filter.includeSnippet && filter.includeMarkdown) {
- notes = notes.filter((note) => note.type === 'MARKDOWN_NOTE')
- } else if (filter.includeSnippet && !filter.includeMarkdown) {
- notes = notes.filter((note) => note.type === 'SNIPPET_NOTE')
- }
-
- if (search.trim().length > 0) {
- const needle = new RegExp(_.escapeRegExp(search.trim()), 'i')
- notes = notes.filter((note) => note.title.match(needle))
- }
- notes = notes
- .sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt))
-
- const activeNote = notes[this.state.index]
- this.noteCount = notes.length
-
- return (
- this.handleKeyDown(e)}
- >
-
- this.handleSearchChange(e)}
- />
-
-
-
-
-
this.handleAllNotesButtonClick(e)}
- isStarredActive={filter.type === 'STARRED'}
- handleStarredButtonClick={(e) => this.handleStarredButtonClick(e)}
- />
-
- {storageList}
-
-
-
this.handleNoteClick(e, _index)}
- />
-
-
-
-
-
- )
- }
-}
-
-FinderMain.propTypes = {
- dispatch: PropTypes.func
-}
-
-var Finder = connect((x) => x)(CSSModules(FinderMain, styles))
-
-function refreshData () {
- // let data = dataStore.getData(true)
-}
-
-ReactDOM.render((
-
-
-
-), document.getElementById('content'), function () {
- refreshData()
-})
diff --git a/browser/finder/ipcClient.js b/browser/finder/ipcClient.js
deleted file mode 100644
index 1be83c50..00000000
--- a/browser/finder/ipcClient.js
+++ /dev/null
@@ -1,126 +0,0 @@
-const nodeIpc = require('node-ipc')
-const { remote, ipcRenderer } = require('electron')
-const { app, Menu } = remote
-const path = require('path')
-const store = require('./store')
-const consts = require('browser/lib/consts')
-
-nodeIpc.config.id = 'finder'
-nodeIpc.config.retry = 1500
-nodeIpc.config.silent = true
-
-function killFinder () {
- const finderWindow = remote.getCurrentWindow()
- finderWindow.removeAllListeners()
- if (global.process.platform === 'darwin') {
- // Only OSX has another app process.
- nodeIpc.of.node.emit('quit-from-finder')
- } else {
- finderWindow.close()
- }
-}
-
-function toggleFinder () {
- const finderWindow = remote.getCurrentWindow()
- if (global.process.platform === 'darwin') {
- if (finderWindow.isVisible()) {
- finderWindow.hide()
- Menu.sendActionToFirstResponder('hide:')
- } else {
- nodeIpc.of.node.emit('request-data-from-finder')
- finderWindow.show()
- }
- } else {
- if (finderWindow.isVisible()) {
- finderWindow.blur()
- finderWindow.hide()
- } else {
- nodeIpc.of.node.emit('request-data-from-finder')
- finderWindow.show()
- finderWindow.focus()
- }
- }
-}
-
-nodeIpc.connectTo(
- 'node',
- path.join(app.getPath('userData'), 'boostnote.service'),
- function () {
- nodeIpc.of.node.on('error', function (err) {
- console.log(err)
- })
- nodeIpc.of.node.on('connect', function () {
- console.log('Conncted successfully')
- })
- nodeIpc.of.node.on('disconnect', function () {
- console.log('disconnected')
- })
-
- nodeIpc.of.node.on('open-finder', function () {
- toggleFinder()
- })
-
- ipcRenderer.on('open-finder-from-tray', function () {
- toggleFinder()
- })
- ipcRenderer.on('open-main-from-tray', function () {
- nodeIpc.of.node.emit('open-main-from-finder')
- })
-
- ipcRenderer.on('quit-from-tray', function () {
- nodeIpc.of.node.emit('quit-from-finder')
- killFinder()
- })
-
- nodeIpc.of.node.on('throttle-data', function (payload) {
- console.log('Received data from Main renderer')
- store.default.dispatch({
- type: 'THROTTLE_DATA',
- data: payload
- })
- })
-
- nodeIpc.of.node.on('config-renew', function (payload) {
- const { config } = payload
- if (config.ui.theme === 'dark') {
- document.body.setAttribute('data-theme', 'dark')
- } else if (config.ui.theme === 'white') {
- document.body.setAttribute('data-theme', 'white')
- } else if (config.ui.theme === 'solarized-dark') {
- document.body.setAttribute('data-theme', 'solarized-dark')
- } else {
- document.body.setAttribute('data-theme', 'default')
- }
-
- let editorTheme = document.getElementById('editorTheme')
- if (editorTheme == null) {
- editorTheme = document.createElement('link')
- editorTheme.setAttribute('id', 'editorTheme')
- editorTheme.setAttribute('rel', 'stylesheet')
- document.head.appendChild(editorTheme)
- }
-
- config.editor.theme = consts.THEMES.some((theme) => theme === config.editor.theme)
- ? config.editor.theme
- : 'default'
-
- if (config.editor.theme !== 'default') {
- editorTheme.setAttribute('href', '../node_modules/codemirror/theme/' + config.editor.theme + '.css')
- }
-
- store.default.dispatch({
- type: 'SET_CONFIG',
- config: config
- })
- })
-
- nodeIpc.of.node.on('quit-finder-app', function () {
- nodeIpc.of.node.emit('quit-finder-app-confirm')
- killFinder()
- })
- }
-)
-
-const ipc = {}
-
-module.exports = ipc
diff --git a/browser/finder/store.js b/browser/finder/store.js
deleted file mode 100644
index ca108e6b..00000000
--- a/browser/finder/store.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import { combineReducers, createStore } from 'redux'
-import { routerReducer } from 'react-router-redux'
-import { DEFAULT_CONFIG } from 'browser/main/lib/ConfigManager'
-
-const defaultData = {
- storageMap: {},
- noteMap: {},
- starredSet: [],
- storageNoteMap: {},
- folderNoteMap: {},
- tagNoteMap: {}
-}
-
-function data (state = defaultData, action) {
- switch (action.type) {
- case 'THROTTLE_DATA':
- console.log(action)
- state = action.data
- }
- return state
-}
-
-function config (state = DEFAULT_CONFIG, action) {
- switch (action.type) {
- case 'INIT_CONFIG':
- case 'SET_CONFIG':
- return Object.assign({}, state, action.config)
- case 'SET_IS_SIDENAV_FOLDED':
- state.isSideNavFolded = action.isFolded
- return Object.assign({}, state)
- case 'SET_ZOOM':
- state.zoom = action.zoom
- return Object.assign({}, state)
- case 'SET_LIST_WIDTH':
- state.listWidth = action.listWidth
- return Object.assign({}, state)
- case 'SET_UI':
- return Object.assign({}, state, action.config)
- }
- return state
-}
-
-const reducer = combineReducers({
- data,
- config,
- routing: routerReducer
-})
-
-const store = createStore(reducer)
-
-export default store
diff --git a/browser/lib/context.js b/browser/lib/context.js
index 417712b8..6c82e6a2 100644
--- a/browser/lib/context.js
+++ b/browser/lib/context.js
@@ -2,7 +2,7 @@ const { remote } = require('electron')
const { Menu, MenuItem } = remote
function popup (templates) {
- let menu = new Menu()
+ const menu = new Menu()
templates.forEach((item) => {
menu.append(new MenuItem(item))
})
diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js
index 44c36492..1269f2a6 100644
--- a/browser/main/Detail/SnippetNoteDetail.js
+++ b/browser/main/Detail/SnippetNoteDetail.js
@@ -564,6 +564,7 @@ class SnippetNoteDetail extends React.Component {
fontSize={editorFontSize}
indentType={config.editor.indentType}
indentSize={editorIndentSize}
+ displayLineNumbers={config.editor.displayLineNumbers}
keyMap={config.editor.keyMap}
scrollPastEnd={config.editor.scrollPastEnd}
fetchUrlTitle={config.editor.fetchUrlTitle}
diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js
index c164b35f..30317095 100644
--- a/browser/main/NoteList/index.js
+++ b/browser/main/NoteList/index.js
@@ -169,9 +169,8 @@ class NoteList extends React.Component {
if (this.notes == null || this.notes.length === 0) {
return
}
- let { router } = this.context
- let { location } = this.props
- let { selectedNoteKeys, shiftKeyDown } = this.state
+ let { selectedNoteKeys } = this.state
+ const { shiftKeyDown } = this.state
let targetIndex = this.getTargetIndex()
@@ -197,9 +196,8 @@ class NoteList extends React.Component {
if (this.notes == null || this.notes.length === 0) {
return
}
- let { router } = this.context
- let { location } = this.props
- let { selectedNoteKeys, shiftKeyDown } = this.state
+ let { selectedNoteKeys } = this.state
+ const { shiftKeyDown } = this.state
let targetIndex = this.getTargetIndex()
const isTargetLastNote = targetIndex === this.notes.length - 1
@@ -240,7 +238,6 @@ class NoteList extends React.Component {
}
handleNoteListKeyDown (e) {
- const { shiftKeyDown } = this.state
if (e.metaKey || e.ctrlKey) return true
if (e.keyCode === 65 && !e.shiftKey) {
@@ -282,7 +279,7 @@ class NoteList extends React.Component {
getNotes () {
const { data, params, location } = this.props
- if (location.pathname.match(/\/home/) || location.pathname.match(/\alltags/)) {
+ if (location.pathname.match(/\/home/) || location.pathname.match(/alltags/)) {
const allNotes = data.noteMap.map((note) => note)
this.contextNotes = allNotes
return allNotes
@@ -353,9 +350,10 @@ class NoteList extends React.Component {
}
handleNoteClick (e, uniqueKey) {
- let { router } = this.context
- let { location } = this.props
- let { shiftKeyDown, selectedNoteKeys } = this.state
+ const { router } = this.context
+ const { location } = this.props
+ let { selectedNoteKeys } = this.state
+ const { shiftKeyDown } = this.state
if (shiftKeyDown && selectedNoteKeys.includes(uniqueKey)) {
const newSelectedNoteKeys = selectedNoteKeys.filter((noteKey) => noteKey !== uniqueKey)
@@ -681,9 +679,10 @@ class NoteList extends React.Component {
}
render () {
- let { location, notes, config, dispatch } = this.props
- let { selectedNoteKeys } = this.state
- let sortFunc = config.sortBy === 'CREATED_AT'
+ const { location, config } = this.props
+ let { notes } = this.props
+ const { selectedNoteKeys } = this.state
+ const sortFunc = config.sortBy === 'CREATED_AT'
? sortByCreatedAt
: config.sortBy === 'ALPHABETICAL'
? sortByAlphabetical
@@ -728,7 +727,6 @@ class NoteList extends React.Component {
config.sortBy === 'CREATED_AT'
? note.createdAt : note.updatedAt
).fromNow('D')
- const key = `${note.storage}-${note.key}`
if (isDefault) {
return (
diff --git a/browser/main/SideNav/StorageItem.js b/browser/main/SideNav/StorageItem.js
index bbf87306..5d7e6005 100644
--- a/browser/main/SideNav/StorageItem.js
+++ b/browser/main/SideNav/StorageItem.js
@@ -8,12 +8,10 @@ import CreateFolderModal from 'browser/main/modals/CreateFolderModal'
import RenameFolderModal from 'browser/main/modals/RenameFolderModal'
import dataApi from 'browser/main/lib/dataApi'
import StorageItemChild from 'browser/components/StorageItem'
-import eventEmitter from 'browser/main/lib/eventEmitter'
import _ from 'lodash'
-import * as path from 'path'
const { remote } = require('electron')
-const { Menu, MenuItem, dialog } = remote
+const { Menu, dialog } = remote
class StorageItem extends React.Component {
constructor (props) {
diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js
index 4c0d410f..0c8d6ee9 100644
--- a/browser/main/lib/ConfigManager.js
+++ b/browser/main/lib/ConfigManager.js
@@ -18,7 +18,6 @@ export const DEFAULT_CONFIG = {
listStyle: 'DEFAULT', // 'DEFAULT', 'SMALL'
amaEnabled: true,
hotkey: {
- toggleFinder: OSX ? 'Cmd + Alt + S' : 'Super + Alt + S',
toggleMain: OSX ? 'Cmd + Alt + L' : 'Super + Alt + E'
},
ui: {
@@ -34,6 +33,7 @@ export const DEFAULT_CONFIG = {
fontFamily: win ? 'Segoe UI' : 'Monaco, Consolas',
indentType: 'space',
indentSize: '2',
+ displayLineNumbers: true,
switchPreview: 'BLUR', // Available value: RIGHTCLICK, BLUR
scrollPastEnd: false,
type: 'SPLIT',
diff --git a/browser/main/lib/ipcClient.js b/browser/main/lib/ipcClient.js
index 12acfed2..dc45c65d 100644
--- a/browser/main/lib/ipcClient.js
+++ b/browser/main/lib/ipcClient.js
@@ -24,20 +24,6 @@ nodeIpc.connectTo(
nodeIpc.of.node.on('disconnect', function () {
console.log('disconnected')
})
-
- nodeIpc.of.node.on('request-data-from-finder', function () {
- console.log('throttle')
- var { data } = store.getState()
- console.log(data.starredSet.toJS())
- nodeIpc.of.node.emit('throttle-data', {
- storageMap: data.storageMap.toJS(),
- noteMap: data.noteMap.toJS(),
- starredSet: data.starredSet.toJS(),
- storageNoteMap: data.storageNoteMap.toJS(),
- folderNoteMap: data.folderNoteMap.toJS(),
- tagNoteMap: data.tagNoteMap.toJS()
- })
- })
}
)
diff --git a/browser/main/modals/PreferencesModal/Crowdfunding.js b/browser/main/modals/PreferencesModal/Crowdfunding.js
index 3dccd27b..048520b0 100644
--- a/browser/main/modals/PreferencesModal/Crowdfunding.js
+++ b/browser/main/modals/PreferencesModal/Crowdfunding.js
@@ -22,18 +22,18 @@ class Crowdfunding extends React.Component {
return (
Crowdfunding
-
Dear all,
+
Dear everyone,
-
Thanks for your using!
-
Boostnote is used in about 200 countries and regions, it is a awesome developer community.
+
Thank you for using Boostnote!
+
Boostnote is used in about 200 different countries and regions by an awesome community of developers.
To continue supporting this growth, and to satisfy community expectations,
-
we would like to invest more time in this project.
+
we would like to invest more time and resources in this project.
-
If you like this project and see its potential, you can help!
+
If you like this project and see its potential, you can help by supporting us on OpenCollective!
Thanks,
-
Boostnote maintainers.
+
Boostnote maintainers