mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
@@ -83,37 +83,7 @@ export default class CodeEditor extends React.Component {
|
||||
'Cmd-T': function (cm) {
|
||||
// Do nothing
|
||||
},
|
||||
Enter: (cm) => {
|
||||
const cursor = cm.getCursor()
|
||||
const line = cm.getLine(cursor.line)
|
||||
let bulletType
|
||||
if (line.trim().startsWith('- ')) {
|
||||
bulletType = 1 // dash
|
||||
} else if (line.trim().startsWith('* ')) {
|
||||
bulletType = 2 // star
|
||||
} else if (line.trim().startsWith('+ ')) {
|
||||
bulletType = 3 // plus
|
||||
} else {
|
||||
bulletType = 0 // not a bullet
|
||||
}
|
||||
const numberedListRegex = /^(\d+)\. .+/
|
||||
const match = line.trim().match(numberedListRegex)
|
||||
if (bulletType !== 0 || match) {
|
||||
cm.execCommand('newlineAndIndent')
|
||||
const range = {line: cursor.line + 1, ch: cm.getLine(cursor.line + 1).length}
|
||||
if (match) {
|
||||
cm.replaceRange((parseInt(match[1]) + 1) + '. ', range)
|
||||
} else if (bulletType === 1) {
|
||||
cm.replaceRange('- ', range)
|
||||
} else if (bulletType === 2) {
|
||||
cm.replaceRange('* ', range)
|
||||
} else if (bulletType === 3) {
|
||||
cm.replaceRange('+ ', range)
|
||||
}
|
||||
} else {
|
||||
cm.execCommand('newlineAndIndent')
|
||||
}
|
||||
}
|
||||
Enter: 'newlineAndIndentContinueMarkdownList'
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class MarkdownEditor extends React.Component {
|
||||
|
||||
this.escapeFromEditor = ['Control', 'w']
|
||||
|
||||
this.supportMdWordBold = ['Control', ':']
|
||||
this.supportMdSelectionBold = ['Control', ':']
|
||||
|
||||
this.state = {
|
||||
status: 'PREVIEW',
|
||||
@@ -169,12 +169,15 @@ class MarkdownEditor extends React.Component {
|
||||
if (!this.state.isLocked && this.state.status === 'CODE' && this.escapeFromEditor.every(isNoteHandlerKey)) {
|
||||
document.activeElement.blur()
|
||||
}
|
||||
if (this.supportMdWordBold.every(isNoteHandlerKey)) {
|
||||
this.addMdBetweenWord('**')
|
||||
if (this.supportMdSelectionBold.every(isNoteHandlerKey)) {
|
||||
this.addMdAroundWord('**')
|
||||
}
|
||||
}
|
||||
|
||||
addMdBetweenWord (mdElement) {
|
||||
addMdAroundWord (mdElement) {
|
||||
if (this.refs.code.editor.getSelection()) {
|
||||
return this.addMdAroundSelection(mdElement)
|
||||
}
|
||||
const currentCaret = this.refs.code.editor.getCursor()
|
||||
const word = this.refs.code.editor.findWordAt(currentCaret)
|
||||
const cmDoc = this.refs.code.editor.getDoc()
|
||||
@@ -182,6 +185,10 @@ class MarkdownEditor extends React.Component {
|
||||
cmDoc.replaceRange(mdElement, { line: word.head.line, ch: word.head.ch + mdElement.length })
|
||||
}
|
||||
|
||||
addMdAroundSelection (mdElement) {
|
||||
this.refs.code.editor.replaceSelection(`${mdElement}${this.refs.code.editor.getSelection()}${mdElement}`)
|
||||
}
|
||||
|
||||
handleKeyUp (e) {
|
||||
const keyPressed = Object.assign(this.state.keyPressed, {
|
||||
[e.key]: false
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
color #e74c3c
|
||||
.menu-button-label
|
||||
color $ui-text-color
|
||||
&:active, &:active:hover
|
||||
background-color $ui-button--active-backgroundColor
|
||||
color #e74c3c
|
||||
.menu-button-label
|
||||
color $ui-text-color
|
||||
|
||||
.menu-button-star--active
|
||||
@extend .menu-button
|
||||
@@ -33,6 +38,11 @@
|
||||
color #F9BF3B
|
||||
.menu-button-label
|
||||
color $ui-text-color
|
||||
&:active, &:active:hover
|
||||
background-color $ui-button--active-backgroundColor
|
||||
color #F9BF3B
|
||||
.menu-button-label
|
||||
color $ui-text-color
|
||||
|
||||
.menu-button-label
|
||||
margin-left 5px
|
||||
|
||||
@@ -96,6 +96,7 @@ class SnippetTab extends React.Component {
|
||||
{!this.state.isRenaming
|
||||
? <button styleName='button'
|
||||
onClick={(e) => this.handleClick(e)}
|
||||
onDoubleClick={(e) => this.handleRenameClick(e)}
|
||||
onContextMenu={(e) => this.handleContextMenu(e)}
|
||||
>
|
||||
{snippet.name.trim().length > 0
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
padding 0 15px
|
||||
height 26px
|
||||
line-height 26px
|
||||
border-width 0 0 0 1px
|
||||
border-width 0 0 0 2px
|
||||
border-style solid
|
||||
border-color transparent
|
||||
overflow hidden
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
background-color $ui-button--active-backgroundColor
|
||||
color $ui-button--active-color
|
||||
.search-optionList-item-name
|
||||
border-left solid 4px transparent
|
||||
border-left solid 2px transparent
|
||||
padding 2px 5px
|
||||
.search-optionList-item-name-surfix
|
||||
font-size 10px
|
||||
|
||||
@@ -41,10 +41,6 @@ class InitModal extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleCloseButtonClick (e) {
|
||||
this.props.close()
|
||||
}
|
||||
|
||||
handlePathChange (e) {
|
||||
this.setState({
|
||||
path: e.target.value
|
||||
@@ -187,12 +183,6 @@ class InitModal extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
handleKeyDown (e) {
|
||||
if (e.keyCode === 27) {
|
||||
this.props.close()
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
if (this.state.isLoading) {
|
||||
return <div styleName='root--loading'>
|
||||
@@ -209,9 +199,6 @@ class InitModal extends React.Component {
|
||||
<div styleName='header'>
|
||||
<div styleName='header-title'>Initialize Storage</div>
|
||||
</div>
|
||||
<button styleName='closeButton'
|
||||
onClick={(e) => this.handleCloseButtonClick(e)}
|
||||
>Close</button>
|
||||
<div styleName='body'>
|
||||
<div styleName='body-welcome'>
|
||||
Welcome!
|
||||
|
||||
@@ -104,10 +104,17 @@
|
||||
margin-left: 10px
|
||||
font-size: 12px
|
||||
|
||||
.code-mirror
|
||||
width 400px
|
||||
height 120px
|
||||
margin 5px 0
|
||||
font-size 12px
|
||||
|
||||
colorDarkControl()
|
||||
border-color $ui-dark-borderColor
|
||||
background-color $ui-dark-backgroundColor
|
||||
color $ui-dark-text-color
|
||||
|
||||
body[data-theme="dark"]
|
||||
.root
|
||||
color $ui-dark-text-color
|
||||
|
||||
@@ -139,6 +139,7 @@ class HotkeyTab extends React.Component {
|
||||
<li><code>VolumeUp</code>, <code>VolumeDown</code> and <code>VolumeMute</code></li>
|
||||
<li><code>MediaNextTrack</code>, <code>MediaPreviousTrack</code>, <code>MediaStop</code> and <code>MediaPlayPause</code></li>
|
||||
<li><code>Control</code> (or <code>Ctrl</code> for short)</li>
|
||||
<li><code>Shift</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
background-color darken(white, 3%)
|
||||
.folderList-item-left
|
||||
height 30px
|
||||
border-left solid 1px transparent
|
||||
border-left solid 2px transparent
|
||||
padding 0 10px
|
||||
line-height 30px
|
||||
float left
|
||||
|
||||
@@ -4,44 +4,66 @@ import styles from './ConfigTab.styl'
|
||||
import ConfigManager from 'browser/main/lib/ConfigManager'
|
||||
import store from 'browser/main/store'
|
||||
import consts from 'browser/lib/consts'
|
||||
import ReactCodeMirror from 'react-codemirror'
|
||||
import CodeMirror from 'codemirror'
|
||||
|
||||
const OSX = global.process.platform === 'darwin'
|
||||
|
||||
class UiTab extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
config: props.config
|
||||
config: props.config,
|
||||
codemirrorTheme: props.config.editor.theme
|
||||
}
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
CodeMirror.autoLoadMode(ReactCodeMirror, 'javascript')
|
||||
}
|
||||
|
||||
handleUIChange (e) {
|
||||
let { config } = this.state
|
||||
const { codemirrorTheme } = this.state
|
||||
let checkHighLight = document.getElementById('checkHighLight')
|
||||
|
||||
config.ui = {
|
||||
theme: this.refs.uiTheme.value,
|
||||
disableDirectWrite: this.refs.uiD2w != null
|
||||
? this.refs.uiD2w.checked
|
||||
: false
|
||||
}
|
||||
config.editor = {
|
||||
theme: this.refs.editorTheme.value,
|
||||
fontSize: this.refs.editorFontSize.value,
|
||||
fontFamily: this.refs.editorFontFamily.value,
|
||||
indentType: this.refs.editorIndentType.value,
|
||||
indentSize: this.refs.editorIndentSize.value,
|
||||
switchPreview: this.refs.editorSwitchPreview.value,
|
||||
keyMap: this.refs.editorKeyMap.value
|
||||
}
|
||||
config.preview = {
|
||||
fontSize: this.refs.previewFontSize.value,
|
||||
fontFamily: this.refs.previewFontFamily.value,
|
||||
codeBlockTheme: this.refs.previewCodeBlockTheme.value,
|
||||
lineNumber: this.refs.previewLineNumber.checked
|
||||
if (checkHighLight === null) {
|
||||
checkHighLight = document.createElement('link')
|
||||
checkHighLight.setAttribute('id', 'checkHighLight')
|
||||
checkHighLight.setAttribute('rel', 'stylesheet')
|
||||
document.head.appendChild(checkHighLight)
|
||||
}
|
||||
|
||||
this.setState({ config })
|
||||
const newConfig = {
|
||||
ui: {
|
||||
theme: this.refs.uiTheme.value,
|
||||
disableDirectWrite: this.refs.uiD2w != null
|
||||
? this.refs.uiD2w.checked
|
||||
: false
|
||||
},
|
||||
editor: {
|
||||
theme: this.refs.editorTheme.value,
|
||||
fontSize: this.refs.editorFontSize.value,
|
||||
fontFamily: this.refs.editorFontFamily.value,
|
||||
indentType: this.refs.editorIndentType.value,
|
||||
indentSize: this.refs.editorIndentSize.value,
|
||||
switchPreview: this.refs.editorSwitchPreview.value,
|
||||
keyMap: this.refs.editorKeyMap.value
|
||||
},
|
||||
preview: {
|
||||
fontSize: this.refs.previewFontSize.value,
|
||||
fontFamily: this.refs.previewFontFamily.value,
|
||||
codeBlockTheme: this.refs.previewCodeBlockTheme.value,
|
||||
lineNumber: this.refs.previewLineNumber.checked
|
||||
}
|
||||
}
|
||||
|
||||
const newCodemirrorTheme = this.refs.editorTheme.value
|
||||
|
||||
if (newCodemirrorTheme !== codemirrorTheme) {
|
||||
checkHighLight.setAttribute('href', `../node_modules/codemirror/theme/${newCodemirrorTheme}.css`)
|
||||
}
|
||||
|
||||
this.setState({ config: newConfig, codemirrorTheme: newCodemirrorTheme })
|
||||
}
|
||||
|
||||
handleSaveUIClick (e) {
|
||||
@@ -61,8 +83,8 @@ class UiTab extends React.Component {
|
||||
|
||||
render () {
|
||||
const themes = consts.THEMES
|
||||
const { config } = this.state
|
||||
|
||||
const { config, codemirrorTheme } = this.state
|
||||
const codemirrorSampleCode = 'function iamHappy (happy) {\n\tif (happy) {\n\t console.log("I am Happy!")\n\t} else {\n\t console.log("I am not Happy!")\n\t}\n};'
|
||||
return (
|
||||
<div styleName='root'>
|
||||
<div styleName='group'>
|
||||
@@ -113,6 +135,9 @@ class UiTab extends React.Component {
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<div styleName='code-mirror'>
|
||||
<ReactCodeMirror value={codemirrorSampleCode} options={{ lineNumbers: true, readOnly: true, mode: 'javascript', theme: codemirrorTheme }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='group-section'>
|
||||
|
||||
@@ -3,11 +3,11 @@ const BrowserWindow = electron.BrowserWindow
|
||||
const shell = electron.shell
|
||||
const mainWindow = require('./main-window')
|
||||
|
||||
const OSX = process.platform === 'darwin'
|
||||
const macOS = process.platform === 'darwin'
|
||||
// const WIN = process.platform === 'win32'
|
||||
const LINUX = process.platform === 'linux'
|
||||
|
||||
var boost = OSX
|
||||
const boost = macOS
|
||||
? {
|
||||
label: 'Boostnote',
|
||||
submenu: [
|
||||
@@ -36,6 +36,7 @@ var boost = OSX
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit Boostnote',
|
||||
role: 'quit'
|
||||
}
|
||||
]
|
||||
@@ -49,13 +50,13 @@ var boost = OSX
|
||||
]
|
||||
}
|
||||
|
||||
var file = {
|
||||
const file = {
|
||||
label: 'File',
|
||||
submenu: [
|
||||
{
|
||||
label: 'New Note',
|
||||
accelerator: 'CommandOrControl+N',
|
||||
click: function () {
|
||||
click () {
|
||||
mainWindow.webContents.send('top:new-note')
|
||||
}
|
||||
},
|
||||
@@ -93,8 +94,8 @@ var file = {
|
||||
},
|
||||
{
|
||||
label: 'Delete Note',
|
||||
accelerator: OSX ? 'Control+Backspace' : 'Control+Delete',
|
||||
click: function () {
|
||||
accelerator: macOS ? 'Control+Backspace' : 'Control+Delete',
|
||||
click () {
|
||||
mainWindow.webContents.send('detail:delete')
|
||||
}
|
||||
}
|
||||
@@ -104,13 +105,12 @@ var file = {
|
||||
if (LINUX) {
|
||||
file.submenu.push({
|
||||
type: 'separator'
|
||||
})
|
||||
file.submenu.push({
|
||||
}, {
|
||||
role: 'quit'
|
||||
})
|
||||
}
|
||||
|
||||
var edit = {
|
||||
const edit = {
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
@@ -149,20 +149,20 @@ var edit = {
|
||||
]
|
||||
}
|
||||
|
||||
var view = {
|
||||
const view = {
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'CommandOrControl+R',
|
||||
click: function () {
|
||||
click () {
|
||||
BrowserWindow.getFocusedWindow().reload()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: OSX ? 'Command+Alt+I' : 'Control+Shift+I',
|
||||
click: function () {
|
||||
accelerator: macOS ? 'Command+Alt+I' : 'Control+Shift+I',
|
||||
click () {
|
||||
BrowserWindow.getFocusedWindow().toggleDevTools()
|
||||
}
|
||||
},
|
||||
@@ -203,7 +203,7 @@ var view = {
|
||||
]
|
||||
}
|
||||
|
||||
var window = {
|
||||
const window = {
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{
|
||||
@@ -226,21 +226,21 @@ var window = {
|
||||
]
|
||||
}
|
||||
|
||||
var help = {
|
||||
const help = {
|
||||
label: 'Help',
|
||||
role: 'help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Boostnote official site',
|
||||
click: function () { shell.openExternal('https://boostnote.io/') }
|
||||
click () { shell.openExternal('https://boostnote.io/') }
|
||||
},
|
||||
{
|
||||
label: 'Issue Tracker',
|
||||
click: function () { shell.openExternal('https://github.com/BoostIO/Boostnote/issues') }
|
||||
click () { shell.openExternal('https://github.com/BoostIO/Boostnote/issues') }
|
||||
},
|
||||
{
|
||||
label: 'Changelog',
|
||||
click: function () { shell.openExternal('https://github.com/BoostIO/boost-releases') }
|
||||
click () { shell.openExternal('https://github.com/BoostIO/boost-releases') }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "boost",
|
||||
"version": "0.8.7",
|
||||
"version": "0.8.8",
|
||||
"description": "Boostnote",
|
||||
"main": "index.js",
|
||||
"license": "GPL-3.0",
|
||||
@@ -68,6 +68,7 @@
|
||||
"node-ipc": "^8.1.0",
|
||||
"raphael": "^2.2.7",
|
||||
"react": "^15.0.2",
|
||||
"react-codemirror": "^0.3.0",
|
||||
"react-dom": "^15.0.2",
|
||||
"react-redux": "^4.4.5",
|
||||
"redux": "^3.5.2",
|
||||
|
||||
19
yarn.lock
19
yarn.lock
@@ -1,5 +1,7 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@rokt33r/markdown-it-math@^4.0.1":
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@rokt33r/markdown-it-math/-/markdown-it-math-4.0.2.tgz#87c7172f459833b05e406cfc846e0c0b7ebc24ef"
|
||||
@@ -1371,6 +1373,10 @@ clap@^1.0.9:
|
||||
dependencies:
|
||||
chalk "^1.1.3"
|
||||
|
||||
classnames@^2.2.5:
|
||||
version "2.2.5"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
|
||||
|
||||
clean-yaml-object@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz#63fb110dc2ce1a84dc21f6d9334876d010ae8b68"
|
||||
@@ -1440,7 +1446,7 @@ code-point-at@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
|
||||
codemirror@^5.19.0:
|
||||
codemirror@^5.18.2, codemirror@^5.19.0:
|
||||
version "5.25.0"
|
||||
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.25.0.tgz#78e06939c7bb41f65707b8aa9c5328111948b756"
|
||||
|
||||
@@ -3813,7 +3819,7 @@ lodash.clonedeep@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
||||
|
||||
lodash.debounce@^4.0.3:
|
||||
lodash.debounce@^4.0.3, lodash.debounce@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
|
||||
@@ -5123,6 +5129,14 @@ rcedit@^0.5.0:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/rcedit/-/rcedit-0.5.1.tgz#d0bdcf5d280a9d1c29da6f118ccce2ce153cef1d"
|
||||
|
||||
react-codemirror@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-codemirror/-/react-codemirror-0.3.0.tgz#cd6bd6ef458ec1e035cfd8b3fe7b30c8c7883c6c"
|
||||
dependencies:
|
||||
classnames "^2.2.5"
|
||||
codemirror "^5.18.2"
|
||||
lodash.debounce "^4.0.8"
|
||||
|
||||
react-color@^2.2.2:
|
||||
version "2.11.4"
|
||||
resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.11.4.tgz#43f64630e5d47a243f6bd35300224c9c69c73921"
|
||||
@@ -6670,4 +6684,3 @@ yauzl@2.4.1:
|
||||
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005"
|
||||
dependencies:
|
||||
fd-slicer "~1.0.1"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user