+class InfoPanel extends React.Component {
+ copyNoteLink () {
+ const {noteLink} = this.props
+ this.refs.noteLink.select()
+ copy(noteLink)
+ }
-
-
-
{wordCount}
-
Words
+ render () {
+ const {
+ storageName, folderName, noteLink, updatedAt, createdAt, exportAsMd, exportAsTxt, exportAsHtml, wordCount, letterCount, type, print
+ } = this.props
+ return (
+
+
+
{updatedAt}
+
MODIFICATION DATE
-
-
{letterCount}
-
Letters
+
+
+
+ {type === 'SNIPPET_NOTE'
+ ? ''
+ :
+
+
+
{letterCount}
+
Letters
+
+
+ }
+
+ {type === 'SNIPPET_NOTE'
+ ? ''
+ :
+ }
+
+
+
{storageName}
+
STORAGE
+
+
+
+
{folderName}
+
FOLDER
+
+
+
+
{createdAt}
+
CREATION DATE
+
+
+
+
{ e.target.select() }} />
+
+
NOTE LINK
+
+
+
+
+
+
+
+
+
+
+
+
- }
-
- {type === 'SNIPPET_NOTE'
- ? ''
- :
- }
-
-
-
{storageName}
-
STORAGE
-
-
-
-
{folderName}
-
FOLDER
-
-
-
-
{createdAt}
-
CREATION DATE
-
-
-
-
{ e.target.select() }} />
-
NOTE LINK
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-)
+ )
+ }
+}
InfoPanel.propTypes = {
storageName: PropTypes.string.isRequired,
diff --git a/browser/main/Detail/InfoPanel.styl b/browser/main/Detail/InfoPanel.styl
index 72b07c87..d90dea49 100644
--- a/browser/main/Detail/InfoPanel.styl
+++ b/browser/main/Detail/InfoPanel.styl
@@ -11,11 +11,10 @@
.control-infoButton-panel
z-index 200
margin-top 0px
- right 0
+ right 25px
position absolute
padding 20px 25px 0 25px
width 300px
- height 350px
overflow auto
background-color $ui-noteList-backgroundColor
box-shadow 2px 12px 15px 2px rgba(0, 0, 0, 0.1), 2px 1px 50px 2px rgba(0, 0, 0, 0.1)
@@ -70,15 +69,30 @@
color $ui-text-color
.infoPanel-sub
- font-size 14px
+ font-size 12px
+ font-weight 600
color $ui-inactive-text-color
padding-bottom 8px
.infoPanel-noteLink
padding-right 5px
- width 200px
+ width 210px
height 25px
- margin-bottom 6px
+ margin 6px 0
+
+.infoPanel-copyButton
+ outline none
+ font-size 16px
+ color #A0A0A0
+ background-color transparent
+ border none
+ margin 0 5px
+ border-radius 5px
+ cursor pointer
+ &:hover
+ transition 0.2s
+ background-color alpha($ui-button--hover-backgroundColor, 30%)
+ color $ui-inactive-text-color
.infoPanel-trash
color #EA4447
diff --git a/browser/main/Detail/MarkdownNoteDetail.js b/browser/main/Detail/MarkdownNoteDetail.js
index 15c584d4..2dac51a6 100755
--- a/browser/main/Detail/MarkdownNoteDetail.js
+++ b/browser/main/Detail/MarkdownNoteDetail.js
@@ -28,10 +28,6 @@ import { formatDate } from 'browser/lib/date-formatter'
import { getTodoPercentageOfCompleted } from 'browser/lib/getTodoStatus'
import striptags from 'striptags'
-const electron = require('electron')
-const { remote } = electron
-const { dialog } = remote
-
class MarkdownNoteDetail extends React.Component {
constructor (props) {
super(props)
@@ -187,38 +183,37 @@ class MarkdownNoteDetail extends React.Component {
handleTrashButtonClick (e) {
const { note } = this.state
const { isTrashed } = note
+ const { confirmDeletion } = this.props
if (isTrashed) {
- const dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), {
- type: 'warning',
- message: 'Confirm note deletion',
- detail: 'This will permanently remove this note.',
- buttons: ['Confirm', 'Cancel']
- })
- if (dialogueButtonIndex === 1) return
- const { note, dispatch } = this.props
- dataApi
- .deleteNote(note.storage, note.key)
- .then((data) => {
- const dispatchHandler = () => {
- dispatch({
- type: 'DELETE_NOTE',
- storageKey: data.storageKey,
- noteKey: data.noteKey
- })
- }
- ee.once('list:moved', dispatchHandler)
- })
+ if (confirmDeletion(true)) {
+ const {note, dispatch} = this.props
+ dataApi
+ .deleteNote(note.storage, note.key)
+ .then((data) => {
+ const dispatchHandler = () => {
+ dispatch({
+ type: 'DELETE_NOTE',
+ storageKey: data.storageKey,
+ noteKey: data.noteKey
+ })
+ }
+ ee.once('list:moved', dispatchHandler)
+ })
+ }
} else {
- note.isTrashed = true
+ if (confirmDeletion()) {
+ note.isTrashed = true
- this.setState({
- note
- }, () => {
- this.save()
- })
+ this.setState({
+ note
+ }, () => {
+ this.save()
+ })
+
+ ee.emit('list:next')
+ }
}
- ee.emit('list:next')
}
handleUndoButtonClick (e) {
@@ -372,10 +367,6 @@ class MarkdownNoteDetail extends React.Component {
-
this.handleInfoButtonClick(e)}
- />
-
this.handleStarButtonClick(e)}
isActive={note.isStarred}
@@ -389,6 +380,7 @@ class MarkdownNoteDetail extends React.Component {
onMouseDown={(e) => this.handleLockButtonMouseDown(e)}
>
+ {this.state.isLocked ? Unlock : Lock}
return (
@@ -400,6 +392,10 @@ class MarkdownNoteDetail extends React.Component {
this.handleTrashButtonClick(e)} />
+ this.handleInfoButtonClick(e)}
+ />
+
{
- const dispatchHandler = () => {
- dispatch({
- type: 'DELETE_NOTE',
- storageKey: data.storageKey,
- noteKey: data.noteKey
- })
- }
- ee.once('list:moved', dispatchHandler)
- })
+ if (confirmDeletion(true)) {
+ const {note, dispatch} = this.props
+ dataApi
+ .deleteNote(note.storage, note.key)
+ .then((data) => {
+ const dispatchHandler = () => {
+ dispatch({
+ type: 'DELETE_NOTE',
+ storageKey: data.storageKey,
+ noteKey: data.noteKey
+ })
+ }
+ ee.once('list:moved', dispatchHandler)
+ })
+ }
} else {
- note.isTrashed = true
+ if (confirmDeletion()) {
+ note.isTrashed = true
- this.setState({
- note
- }, () => {
- this.save()
- })
+ this.setState({
+ note
+ }, () => {
+ this.save()
+ })
+
+ ee.emit('list:next')
+ }
}
- ee.emit('list:next')
}
handleUndoButtonClick (e) {
@@ -565,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}
onChange={(e) => this.handleCodeChange(index)(e)}
@@ -627,10 +627,6 @@ class SnippetNoteDetail extends React.Component {
/>
-
this.handleInfoButtonClick(e)}
- />
-
this.handleStarButtonClick(e)}
isActive={note.isStarred}
@@ -638,10 +634,16 @@ class SnippetNoteDetail extends React.Component {
this.handleTrashButtonClick(e)} />
+
+ this.handleInfoButtonClick(e)}
+ />
+
(
onClick('SPLIT')}>
-

+
onClick('EDITOR_PREVIEW')}>
-

+
Toggle Mode
diff --git a/browser/main/Detail/ToggleModeButton.styl b/browser/main/Detail/ToggleModeButton.styl
index b9d3cc6c..c69401f8 100644
--- a/browser/main/Detail/ToggleModeButton.styl
+++ b/browser/main/Detail/ToggleModeButton.styl
@@ -1,24 +1,28 @@
.control-toggleModeButton
- border 1px solid #eee
- height 34px
+ height 25px
+ border-radius 50px
+ background-color #F4F4F4
+ width 52px
display flex
align-items center
+ position absolute
+ right 165px
+ .active
+ background-color #1EC38B
+ width 33px
+ height 24px
+ box-shadow 2px 0px 7px #eee
+ z-index 1
div
width 40px
height 100%
- background-color #f9f9f9
+ border-radius 50%
display flex
align-items center
justify-content center
cursor pointer
- &:first-child
- border-right 1px solid #eee
- .active
- background-color #fff
- box-shadow 2px 0px 7px #eee
- z-index 1
&:hover .tooltip
opacity 1
@@ -26,9 +30,10 @@
tooltip()
position absolute
pointer-events none
- top 47px
- right 11px
+ top 33px
+ left -10px
z-index 200
+ width 80px
padding 5px
line-height normal
border-radius 2px
@@ -40,22 +45,14 @@ body[data-theme="dark"]
topBarButtonDark()
.control-toggleModeButton
- border 1px solid #444444
- div
- background-color $ui-dark-noteDetail-backgroundColor
- &:first-child
- border-right 1px solid #444444
- .active
background-color #3A404C
+ .active
+ background-color #1EC38B
box-shadow 2px 0px 7px #444444
body[data-theme="solarized-dark"]
.control-toggleModeButton
- border 1px solid #586E75
- div
- background-color $ui-solarized-dark-noteDetail-backgroundColor
- &:first-child
- border-right 1px solid #586E75
- .active
background-color #002B36
+ .active
+ background-color #1EC38B
box-shadow 2px 0px 7px #222222
\ No newline at end of file
diff --git a/browser/main/Detail/TrashButton.styl b/browser/main/Detail/TrashButton.styl
index 455d36a6..7c7af878 100644
--- a/browser/main/Detail/TrashButton.styl
+++ b/browser/main/Detail/TrashButton.styl
@@ -8,8 +8,8 @@
tooltip()
position absolute
pointer-events none
- top 26px
- right 0
+ top 50px
+ right 50px
z-index 200
padding 5px
line-height normal
diff --git a/browser/main/Detail/index.js b/browser/main/Detail/index.js
index 70f37a41..a9a8e4f2 100644
--- a/browser/main/Detail/index.js
+++ b/browser/main/Detail/index.js
@@ -32,6 +32,26 @@ class Detail extends React.Component {
ee.off('detail:delete', this.deleteHandler)
}
+ confirmDeletion (permanent) {
+ if (this.props.config.ui.confirmDeletion || permanent) {
+ const electron = require('electron')
+ const { remote } = electron
+ const { dialog } = remote
+
+ const alertConfig = {
+ type: 'warning',
+ message: 'Confirm note deletion',
+ detail: 'This will permanently remove this note.',
+ buttons: ['Confirm', 'Cancel']
+ }
+
+ const dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), alertConfig)
+ return dialogueButtonIndex === 0
+ }
+
+ return true
+ }
+
render () {
const { location, data, config } = this.props
let note = null
@@ -64,6 +84,7 @@ class Detail extends React.Component {
this.confirmDeletion(permanent)}
ref='root'
{..._.pick(this.props, [
'dispatch',
@@ -80,6 +101,7 @@ class Detail extends React.Component {
this.confirmDeletion(permanent)}
ref='root'
{..._.pick(this.props, [
'dispatch',
diff --git a/browser/main/Main.js b/browser/main/Main.js
index 3fefdb45..f9be6085 100644
--- a/browser/main/Main.js
+++ b/browser/main/Main.js
@@ -10,10 +10,13 @@ import Detail from './Detail'
import dataApi from 'browser/main/lib/dataApi'
import _ from 'lodash'
import ConfigManager from 'browser/main/lib/ConfigManager'
-import modal from 'browser/main/lib/modal'
-import InitModal from 'browser/main/modals/InitModal'
import mobileAnalytics from 'browser/main/lib/AwsMobileAnalyticsConfig'
import eventEmitter from 'browser/main/lib/eventEmitter'
+import { hashHistory } from 'react-router'
+import store from 'browser/main/store'
+const path = require('path')
+const electron = require('electron')
+const { remote } = electron
class Main extends React.Component {
@@ -48,6 +51,91 @@ class Main extends React.Component {
}
}
+ init () {
+ dataApi
+ .addStorage({
+ name: 'My Storage',
+ path: path.join(remote.app.getPath('home'), 'Boostnote')
+ })
+ .then((data) => {
+ return data
+ })
+ .then((data) => {
+ if (data.storage.folders[0] != null) {
+ return data
+ } else {
+ return dataApi
+ .createFolder(data.storage.key, {
+ color: '#1278BD',
+ name: 'Default'
+ })
+ .then((_data) => {
+ return {
+ storage: _data.storage,
+ notes: data.notes
+ }
+ })
+ }
+ })
+ .then((data) => {
+ console.log(data)
+ store.dispatch({
+ type: 'ADD_STORAGE',
+ storage: data.storage,
+ notes: data.notes
+ })
+
+ const defaultSnippetNote = dataApi
+ .createNote(data.storage.key, {
+ type: 'SNIPPET_NOTE',
+ folder: data.storage.folders[0].key,
+ title: 'Snippet note example',
+ description: 'Snippet note example\nYou can store a series of snippets as a single note, like Gist.',
+ snippets: [
+ {
+ name: 'example.html',
+ mode: 'html',
+ content: '\n\nEnjoy Boostnote!
\n\n'
+ },
+ {
+ name: 'example.js',
+ mode: 'javascript',
+ content: 'var boostnote = document.getElementById(\'enjoy\').innerHTML\n\nconsole.log(boostnote)'
+ }
+ ]
+ })
+ .then((note) => {
+ store.dispatch({
+ type: 'UPDATE_NOTE',
+ note: note
+ })
+ })
+ const defaultMarkdownNote = dataApi
+ .createNote(data.storage.key, {
+ type: 'MARKDOWN_NOTE',
+ folder: data.storage.folders[0].key,
+ title: 'Welcome to Boostnote!',
+ content: '# Welcome to Boostnote!\n## Click here to edit markdown :wave:\n\n\n\n## Docs :memo:\n- [Boostnote | Boost your happiness, productivity and creativity.](https://hackernoon.com/boostnote-boost-your-happiness-productivity-and-creativity-315034efeebe)\n- [Cloud Syncing & Backups](https://github.com/BoostIO/Boostnote/wiki/Cloud-Syncing-and-Backup)\n- [How to sync your data across Desktop and Mobile apps](https://github.com/BoostIO/Boostnote/wiki/Sync-Data-Across-Desktop-and-Mobile-apps)\n- [Convert data from **Evernote** to Boostnote.](https://github.com/BoostIO/Boostnote/wiki/Evernote)\n- [Keyboard Shortcuts](https://github.com/BoostIO/Boostnote/wiki/Keyboard-Shortcuts)\n- [Keymaps in Editor mode](https://github.com/BoostIO/Boostnote/wiki/Keymaps-in-Editor-mode)\n- [How to set syntax highlight in Snippet note](https://github.com/BoostIO/Boostnote/wiki/Syntax-Highlighting)\n\n---\n\n## Article Archive :books:\n- [Reddit English](http://bit.ly/2mOJPu7)\n- [Reddit Spanish](https://www.reddit.com/r/boostnote_es/)\n- [Reddit Chinese](https://www.reddit.com/r/boostnote_cn/)\n- [Reddit Japanese](https://www.reddit.com/r/boostnote_jp/)\n\n---\n\n## Community :beers:\n- [GitHub](http://bit.ly/2AWWzkD)\n- [Twitter](http://bit.ly/2z8BUJZ)\n- [Facebook Group](http://bit.ly/2jcca8t)'
+ })
+ .then((note) => {
+ store.dispatch({
+ type: 'UPDATE_NOTE',
+ note: note
+ })
+ })
+
+ return Promise.resolve(defaultSnippetNote)
+ .then(defaultMarkdownNote)
+ .then(() => data.storage)
+ })
+ .then((storage) => {
+ hashHistory.push('/storages/' + storage.key)
+ })
+ .catch((err) => {
+ throw err
+ })
+ }
+
componentDidMount () {
const { dispatch, config } = this.props
@@ -71,7 +159,7 @@ class Main extends React.Component {
})
if (data.storages.length < 1) {
- modal.open(InitModal)
+ this.init()
}
})
diff --git a/browser/main/NewNoteButton/index.js b/browser/main/NewNoteButton/index.js
index 3adf3369..633433df 100644
--- a/browser/main/NewNoteButton/index.js
+++ b/browser/main/NewNoteButton/index.js
@@ -86,7 +86,7 @@ class NewNoteButton extends React.Component {
onClick={(e) => this.handleNewNoteButtonClick(e)}>
- Make a Note {OSX ? '⌘' : '^'} + n
+ Make a note {OSX ? '⌘' : 'Ctrl'} + N
diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js
index 083eb75f..30317095 100644
--- a/browser/main/NoteList/index.js
+++ b/browser/main/NoteList/index.js
@@ -11,10 +11,8 @@ import NoteItem from 'browser/components/NoteItem'
import NoteItemSimple from 'browser/components/NoteItemSimple'
import searchFromNotes from 'browser/lib/search'
import fs from 'fs'
+import path from 'path'
import { hashHistory } from 'react-router'
-import markdown from 'browser/lib/markdownTextHelper'
-import { findNoteTitle } from 'browser/lib/findNoteTitle'
-import store from 'browser/main/store'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
const { remote } = require('electron')
@@ -171,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()
@@ -199,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
@@ -242,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) {
@@ -284,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
@@ -355,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)
@@ -443,6 +439,7 @@ class NoteList extends React.Component {
const pinLabel = note.isPinned ? 'Remove pin' : 'Pin to Top'
const deleteLabel = 'Delete Note'
+ const cloneNote = 'Clone Note'
const menu = new Menu()
if (!location.pathname.match(/\/home|\/starred|\/trash/)) {
@@ -455,6 +452,10 @@ class NoteList extends React.Component {
label: deleteLabel,
click: this.deleteNote
}))
+ menu.append(new MenuItem({
+ label: cloneNote,
+ click: this.cloneNote.bind(this)
+ }))
menu.popup()
}
@@ -545,6 +546,42 @@ class NoteList extends React.Component {
this.setState({ selectedNoteKeys: [] })
}
+ cloneNote () {
+ const { selectedNoteKeys } = this.state
+ const { dispatch, location } = this.props
+ const { storage, folder } = this.resolveTargetFolder()
+ const notes = this.notes.map((note) => Object.assign({}, note))
+ const selectedNotes = findNotesByKeys(notes, selectedNoteKeys)
+ const firstNote = selectedNotes[0]
+ const eventName = firstNote.type === 'MARKDOWN_NOTE' ? 'ADD_MARKDOWN' : 'ADD_SNIPPET'
+
+ AwsMobileAnalyticsConfig.recordDynamicCustomEvent(eventName)
+ AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_ALLNOTE')
+ dataApi
+ .createNote(storage.key, {
+ type: firstNote.type,
+ folder: folder.key,
+ title: firstNote.title + ' copy',
+ content: firstNote.content
+ })
+ .then((note) => {
+ const uniqueKey = note.storage + '-' + note.key
+ dispatch({
+ type: 'UPDATE_NOTE',
+ note: note
+ })
+
+ this.setState({
+ selectedNoteKeys: [uniqueKey]
+ })
+
+ hashHistory.push({
+ pathname: location.pathname,
+ query: {key: uniqueKey}
+ })
+ })
+ }
+
importFromFile () {
const options = {
filters: [
@@ -582,7 +619,7 @@ class NoteList extends React.Component {
const newNote = {
content: content,
folder: folder.key,
- title: markdown.strip(findNoteTitle(content)),
+ title: path.basename(filepath, path.extname(filepath)),
type: 'MARKDOWN_NOTE',
createdAt: birthtime,
updatedAt: mtime
@@ -642,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
@@ -689,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/StatusBar/StatusBar.styl b/browser/main/StatusBar/StatusBar.styl
index 9f189fec..e055dc0d 100644
--- a/browser/main/StatusBar/StatusBar.styl
+++ b/browser/main/StatusBar/StatusBar.styl
@@ -21,19 +21,20 @@
color white
.zoom
- navButtonColor()
- color rgba(0,0,0,.54)
- height 20px
- display flex
- padding 0
- align-items center
- background-color transparent
- &:hover
- color $ui-active-color
- &:active
- color $ui-active-color
- span
- margin-left 5px
+ display none
+ // navButtonColor()
+ // color rgba(0,0,0,.54)
+ // height 20px
+ // display flex
+ // padding 0
+ // align-items center
+ // background-color transparent
+ // &:hover
+ // color $ui-active-color
+ // &:active
+ // color $ui-active-color
+ // span
+ // margin-left 5px
.update
navButtonColor()
diff --git a/browser/main/global.styl b/browser/main/global.styl
index 27d1ae73..1b40587c 100644
--- a/browser/main/global.styl
+++ b/browser/main/global.styl
@@ -97,7 +97,7 @@ body[data-theme="dark"]
.CodeMirror
font-family inherit !important
line-height 1.4em
- height 96%
+ height 100%
.CodeMirror > div > textarea
margin-bottom -1em
.CodeMirror-focused .CodeMirror-selected
diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js
index 3d70a7a3..fde7dafd 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'
@@ -46,7 +46,8 @@ export const DEFAULT_CONFIG = {
latexInlineOpen: '$',
latexInlineClose: '$',
latexBlockOpen: '$$',
- latexBlockClose: '$$'
+ latexBlockClose: '$$',
+ scrollPastEnd: false
}
}
diff --git a/browser/main/lib/dataApi/exportFolder.js b/browser/main/lib/dataApi/exportFolder.js
index 75dba959..bb3b2834 100644
--- a/browser/main/lib/dataApi/exportFolder.js
+++ b/browser/main/lib/dataApi/exportFolder.js
@@ -46,9 +46,7 @@ function exportFolder (storageKey, folderKey, fileType, exportDir) {
.filter(note => note.folder === folderKey && note.isTrashed === false && note.type === 'MARKDOWN_NOTE')
.forEach(snippet => {
const notePath = path.join(exportDir, `${snippet.title}.${fileType}`)
- fs.writeFileSync(notePath, snippet.content, (err) => {
- if (err) throw err
- })
+ fs.writeFileSync(notePath, snippet.content)
})
return {
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/CreateFolderModal.styl b/browser/main/modals/CreateFolderModal.styl
index 97fddec7..45f2e852 100644
--- a/browser/main/modals/CreateFolderModal.styl
+++ b/browser/main/modals/CreateFolderModal.styl
@@ -29,7 +29,7 @@
width 490px
padding 0 5px
margin 10px 0
- border 1px solid #C9C9C9 // TODO: use variable.
+ border 1px solid $ui-input--create-folder-modal
border-radius 2px
background-color transparent
outline none
@@ -68,7 +68,7 @@ body[data-theme="dark"]
color $ui-dark-text-color
.control-folder-input
- border 1px solid #C9C9C9 // TODO: use variable.
+ border 1px solid $ui-input--create-folder-modal
color white
.description
@@ -76,3 +76,29 @@ body[data-theme="dark"]
.control-confirmButton
colorDarkPrimaryButton()
+
+body[data-theme="solarized-dark"]
+ .root
+ modalSolarizedDark()
+ width 500px
+ height 270px
+ overflow hidden
+ position relative
+
+ .header
+ background-color transparent
+ border-color $ui-dark-borderColor
+ color $ui-solarized-dark-text-color
+
+ .control-folder-label
+ color $ui-solarized-dark-text-color
+
+ .control-folder-input
+ border 1px solid $ui-input--create-folder-modal
+ color white
+
+ .description
+ color $ui-inactive-text-color
+
+ .control-confirmButton
+ colorSolarizedDarkPrimaryButton()
diff --git a/browser/main/modals/InitModal.js b/browser/main/modals/InitModal.js
deleted file mode 100644
index 024c6f42..00000000
--- a/browser/main/modals/InitModal.js
+++ /dev/null
@@ -1,254 +0,0 @@
-import React from 'react'
-import CSSModules from 'browser/lib/CSSModules'
-import styles from './InitModal.styl'
-import dataApi from 'browser/main/lib/dataApi'
-import store from 'browser/main/store'
-import { hashHistory } from 'react-router'
-import _ from 'lodash'
-
-const CSON = require('@rokt33r/season')
-const path = require('path')
-const electron = require('electron')
-const { remote } = electron
-
-function browseFolder () {
- const dialog = remote.dialog
-
- const defaultPath = remote.app.getPath('home')
- return new Promise((resolve, reject) => {
- dialog.showOpenDialog({
- title: 'Select Directory',
- defaultPath,
- properties: ['openDirectory', 'createDirectory']
- }, function (targetPaths) {
- if (targetPaths == null) return resolve('')
- resolve(targetPaths[0])
- })
- })
-}
-
-class InitModal extends React.Component {
- constructor (props) {
- super(props)
-
- this.state = {
- path: path.join(remote.app.getPath('home'), 'Boostnote'),
- migrationRequested: true,
- isLoading: true,
- data: null,
- legacyStorageExists: false,
- isSending: false
- }
- }
-
- handlePathChange (e) {
- this.setState({
- path: e.target.value
- })
- }
-
- componentDidMount () {
- let data = null
- try {
- data = CSON.readFileSync(path.join(remote.app.getPath('userData'), 'local.json'))
- } catch (err) {
- console.error(err)
- }
- const newState = {
- isLoading: false
- }
- if (data != null) {
- newState.legacyStorageExists = true
- newState.data = data
- }
- this.setState(newState, () => {
- this.refs.createButton.focus()
- })
- }
-
- handlePathBrowseButtonClick (e) {
- browseFolder()
- .then((targetPath) => {
- if (targetPath.length > 0) {
- this.setState({
- path: targetPath
- })
- }
- })
- .catch((err) => {
- console.error('BrowseFAILED')
- console.error(err)
- })
- }
-
- handleSubmitButtonClick (e) {
- this.setState({
- isSending: true
- }, () => {
- dataApi
- .addStorage({
- name: 'My Storage',
- path: this.state.path
- })
- .then((data) => {
- if (this.state.migrationRequested && _.isObject(this.state.data) && _.isArray(this.state.data.folders) && _.isArray(this.state.data.articles)) {
- return dataApi.migrateFromV5Storage(data.storage.key, this.state.data)
- }
- return data
- })
- .then((data) => {
- if (data.storage.folders[0] != null) {
- return data
- } else {
- return dataApi
- .createFolder(data.storage.key, {
- color: '#1278BD',
- name: 'Default'
- })
- .then((_data) => {
- return {
- storage: _data.storage,
- notes: data.notes
- }
- })
- }
- })
- .then((data) => {
- console.log(data)
- store.dispatch({
- type: 'ADD_STORAGE',
- storage: data.storage,
- notes: data.notes
- })
-
- const defaultSnippetNote = dataApi
- .createNote(data.storage.key, {
- type: 'SNIPPET_NOTE',
- folder: data.storage.folders[0].key,
- title: 'Snippet note example',
- description: 'Snippet note example\nYou can store a series of snippets as a single note, like Gist.',
- snippets: [
- {
- name: 'example.html',
- mode: 'html',
- content: '\n\n
Enjoy Boostnote!
\n\n'
- },
- {
- name: 'example.js',
- mode: 'javascript',
- content: 'var boostnote = document.getElementById(\'enjoy\').innerHTML\n\nconsole.log(boostnote)'
- }
- ]
- })
- .then((note) => {
- store.dispatch({
- type: 'UPDATE_NOTE',
- note: note
- })
- })
- const defaultMarkdownNote = dataApi
- .createNote(data.storage.key, {
- type: 'MARKDOWN_NOTE',
- folder: data.storage.folders[0].key,
- title: 'Welcome to Boostnote!',
- content: '# Welcome to Boostnote!\n## Click here to edit markdown :wave:\n\n
\n\n## Docs :memo:\n- [Boostnote | Boost your happiness, productivity and creativity.](https://hackernoon.com/boostnote-boost-your-happiness-productivity-and-creativity-315034efeebe)\n- [Cloud Syncing & Backups](https://github.com/BoostIO/Boostnote/wiki/Cloud-Syncing-and-Backup)\n- [How to sync your data across Desktop and Mobile apps](https://github.com/BoostIO/Boostnote/wiki/Sync-Data-Across-Desktop-and-Mobile-apps)\n- [Convert data from **Evernote** to Boostnote.](https://github.com/BoostIO/Boostnote/wiki/Evernote)\n- [Keyboard Shortcuts](https://github.com/BoostIO/Boostnote/wiki/Keyboard-Shortcuts)\n- [Keymaps in Editor mode](https://github.com/BoostIO/Boostnote/wiki/Keymaps-in-Editor-mode)\n- [How to set syntax highlight in Snippet note](https://github.com/BoostIO/Boostnote/wiki/Syntax-Highlighting)\n\n---\n\n## Article Archive :books:\n- [Reddit English](http://bit.ly/2mOJPu7)\n- [Reddit Spanish](https://www.reddit.com/r/boostnote_es/)\n- [Reddit Chinese](https://www.reddit.com/r/boostnote_cn/)\n- [Reddit Japanese](https://www.reddit.com/r/boostnote_jp/)\n\n---\n\n## Community :beers:\n- [GitHub](http://bit.ly/2AWWzkD)\n- [Twitter](http://bit.ly/2z8BUJZ)\n- [Facebook Group](http://bit.ly/2jcca8t)'
- })
- .then((note) => {
- store.dispatch({
- type: 'UPDATE_NOTE',
- note: note
- })
- })
-
- return Promise.resolve(defaultSnippetNote)
- .then(defaultMarkdownNote)
- .then(() => data.storage)
- })
- .then((storage) => {
- hashHistory.push('/storages/' + storage.key)
- this.props.close()
- })
- .catch((err) => {
- this.setState({
- isSending: false
- })
- throw err
- })
- })
- }
-
- handleMigrationRequestedChange (e) {
- this.setState({
- migrationRequested: e.target.checked
- })
- }
-
- handleKeyDown (e) {
- if (e.keyCode === 27) {
- this.props.close()
- }
- }
-
- render () {
- if (this.state.isLoading) {
- return
-
-
Preparing initialization...
-
- }
- return (
-
this.handleKeyDown(e)}
- >
-
-
- Welcome to Boostnote!
-
-
- Please select a directory for data storage.
-
-
- this.handlePathChange(e)}
- />
-
-
-
- {this.state.legacyStorageExists &&
-
-
-
- }
-
-
-
-
-
-
-
- )
- }
-}
-
-InitModal.propTypes = {
-}
-
-export default CSSModules(InitModal, styles)
diff --git a/browser/main/modals/InitModal.styl b/browser/main/modals/InitModal.styl
deleted file mode 100644
index 62e02b68..00000000
--- a/browser/main/modals/InitModal.styl
+++ /dev/null
@@ -1,76 +0,0 @@
-.root
- modal()
- background-color #fff
- max-width 100vw
- max-height 100vh
- overflow hidden
- margin 0
- padding 150px 0
- position relative
-.root--loading
- @extend .root
- text-align center
-.spinner
- font-size 100px
- margin 35px auto
- color $ui-text-color
-.loadingMessage
- color $ui-text-color
- margin 15px auto 35px
-
-.body
- padding 30px
-
-.body-welcome
- text-align center
- margin-bottom 25px
- font-size 32px
- color $ui-text-color
-
-.body-description
- font-size 16px
- color $ui-text-color
- text-align center
- margin-bottom 25px
-
-.body-path
- margin 0 auto 25px
- width 330px
-
-.body-path-input
- height 40px
- vertical-align middle
- width 300px
- font-size 14px
- border-style solid
- border-width 1px 0 1px 1px
- border-color $border-color
- border-top-left-radius 2px
- border-bottom-left-radius 2px
- padding 0 5px
-
-.body-path-button
- height 42px
- width 30px
- font-size 16px
- font-weight 600
- border none
- border-top-right-radius 2px
- border-bottom-right-radius 2px
- colorPrimaryButton()
- vertical-align middle
-.body-migration
- margin 0 auto 25px
- text-align center
-
-.body-control
- text-align center
-
-.body-control-createButton
- colorPrimaryButton()
- font-size 14px
- font-weight 600
- border none
- border-radius 2px
- height 40px
- padding 0 25px
diff --git a/browser/main/modals/NewNoteModal.js b/browser/main/modals/NewNoteModal.js
index 346fe920..24b150cb 100644
--- a/browser/main/modals/NewNoteModal.js
+++ b/browser/main/modals/NewNoteModal.js
@@ -106,7 +106,7 @@ class NewNoteModal extends React.Component {
onKeyDown={(e) => this.handleKeyDown(e)}
>
-
Make a Note
+
Make a note
this.handleCloseButtonClick(e)} />
diff --git a/browser/main/modals/PreferencesModal/ConfigTab.styl b/browser/main/modals/PreferencesModal/ConfigTab.styl
index ea26af08..f6f7ace9 100644
--- a/browser/main/modals/PreferencesModal/ConfigTab.styl
+++ b/browser/main/modals/PreferencesModal/ConfigTab.styl
@@ -89,9 +89,9 @@
margin-right 10px
.group-control-rightButton
- position absolute
- top 10px
- right 20px
+ position fixed
+ top 80px
+ right 100px
colorPrimaryButton()
border none
border-radius 2px
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