Compare commits
234 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87f9589be3 | ||
|
|
96413b9851 | ||
|
|
9699ef6319 | ||
|
|
dd8f4d60f0 | ||
|
|
372f2e7319 | ||
|
|
1957d87dd7 | ||
|
|
a148d17ba1 | ||
|
|
297553c240 | ||
|
|
f0fcaa6be7 | ||
|
|
cfa40f3ec1 | ||
|
|
832c43de88 | ||
|
|
1665e18edb | ||
|
|
fd1717046b | ||
|
|
7fe7c555bc | ||
|
|
411a7a8e80 | ||
|
|
196f5a7bf7 | ||
|
|
3fa326121a | ||
|
|
cce69bea3a | ||
|
|
f70cf7845d | ||
|
|
bd0a326128 | ||
|
|
897d99e043 | ||
|
|
b0f288e103 | ||
|
|
7d26d46c7b | ||
|
|
5c7804fc40 | ||
|
|
836f3af1ab | ||
|
|
67b89d4fe7 | ||
|
|
bc2d9d0fe2 | ||
|
|
79f33b9405 | ||
|
|
ed9ddee5f1 | ||
|
|
0d004b2f0a | ||
|
|
f41ff77d76 | ||
|
|
ae97a76d2e | ||
|
|
3ca18c04c6 | ||
|
|
2b03e6e956 | ||
|
|
010793a478 | ||
|
|
b136512ece | ||
|
|
9179c199fe | ||
|
|
cfa4dfa817 | ||
|
|
6a73a3af97 | ||
|
|
923c24fa6c | ||
|
|
4b1c8a3238 | ||
|
|
76508fbc3b | ||
|
|
2bfda95ed8 | ||
|
|
6e5082a470 | ||
|
|
a6cec44fc4 | ||
|
|
600fab4f23 | ||
|
|
12377b8caf | ||
|
|
250c6e488d | ||
|
|
3a9b57adae | ||
|
|
74415956ac | ||
|
|
33d7ed25a5 | ||
|
|
df2de5c081 | ||
|
|
7f4c58a84a | ||
|
|
7437b26e3c | ||
|
|
ee6d41859f | ||
|
|
b368c3b5d8 | ||
|
|
b1ae2b0b6f | ||
|
|
27a6d53c7f | ||
|
|
4caf3a81be | ||
|
|
ab578f768f | ||
|
|
e4212e796a | ||
|
|
95b1ff9b41 | ||
|
|
684d2c411e | ||
|
|
42710cfee5 | ||
|
|
277004fd9b | ||
|
|
14f79c4c21 | ||
|
|
f88cd80dca | ||
|
|
19ada1dbf6 | ||
|
|
7754ab1a2e | ||
|
|
de0a8837eb | ||
|
|
042d059d53 | ||
|
|
cba743c895 | ||
|
|
24ee71ac06 | ||
|
|
0ec4ef3363 | ||
|
|
98120a5e40 | ||
|
|
3cb2a6bf92 | ||
|
|
4b7262cb72 | ||
|
|
eac8b13d7b | ||
|
|
4458c58066 | ||
|
|
245d603ae8 | ||
|
|
e3d959522b | ||
|
|
124544452b | ||
|
|
4534625084 | ||
|
|
3e4342eec4 | ||
|
|
0ed2d26129 | ||
|
|
1b538993db | ||
|
|
d67e4009e7 | ||
|
|
7f066c4443 | ||
|
|
2594ca984a | ||
|
|
0e089fadfb | ||
|
|
e56518e13d | ||
|
|
c9bc0c89ff | ||
|
|
b18b1171e7 | ||
|
|
d65464401c | ||
|
|
e9a9e10c81 | ||
|
|
825cd6a93b | ||
|
|
276471979a | ||
|
|
d6903edac7 | ||
|
|
4e1b4bdd6a | ||
|
|
52f0a5639d | ||
|
|
58181d02b2 | ||
|
|
1fea39f1b7 | ||
|
|
ae97ff0f98 | ||
|
|
b2d7fa9e97 | ||
|
|
93e9235bb2 | ||
|
|
094bce20e2 | ||
|
|
2f9d4c447a | ||
|
|
84eb790d93 | ||
|
|
ebd07694db | ||
|
|
2bbac8a6f4 | ||
|
|
e74f5e835f | ||
|
|
69e753cc71 | ||
|
|
b0978c772e | ||
|
|
fb4dfbadf3 | ||
|
|
d19ff3ff17 | ||
|
|
d0990be856 | ||
|
|
268d66b51d | ||
|
|
c1df311e86 | ||
|
|
cc3bd41df2 | ||
|
|
856979b455 | ||
|
|
47925489fd | ||
|
|
8aefb21123 | ||
|
|
e27751c18c | ||
|
|
a3f3fdcc71 | ||
|
|
a757576920 | ||
|
|
c4eb28d241 | ||
|
|
aba6c2eb4f | ||
|
|
ecb91b3155 | ||
|
|
7374b1cc70 | ||
|
|
e8f2972659 | ||
|
|
5bef19a306 | ||
|
|
54d9e02a42 | ||
|
|
4f479a8baf | ||
|
|
e7e6194cac | ||
|
|
113abbb94d | ||
|
|
d9d0651352 | ||
|
|
e27af9f6c1 | ||
|
|
11d820356d | ||
|
|
0945aab232 | ||
|
|
e4744221ee | ||
|
|
5f71b24f8d | ||
|
|
095a29972a | ||
|
|
76bdb708fa | ||
|
|
7c3c08fd96 | ||
|
|
a4a2e09429 | ||
|
|
4ed0ae5e2d | ||
|
|
4cb5e43357 | ||
|
|
b0fecc6b51 | ||
|
|
dd4236ca89 | ||
|
|
5da908c759 | ||
|
|
fcce1d406d | ||
|
|
5a01f39dc7 | ||
|
|
ea1d76f853 | ||
|
|
2356d8a64f | ||
|
|
969f82b903 | ||
|
|
fb90907abf | ||
|
|
cbd4cd940c | ||
|
|
6b18c6182e | ||
|
|
09164aa0c9 | ||
|
|
b83dadddb7 | ||
|
|
b3263b41ff | ||
|
|
1118149b9e | ||
|
|
b6fc24c6e7 | ||
|
|
441edf4667 | ||
|
|
74068eaa3d | ||
|
|
c11bd9e7eb | ||
|
|
b21a82ea6b | ||
|
|
cf455a13d5 | ||
|
|
c492f3529e | ||
|
|
40d7ba4bcc | ||
|
|
686bc49230 | ||
|
|
6550af698a | ||
|
|
aac5cbf53e | ||
|
|
00636db87c | ||
|
|
6231b8ad57 | ||
|
|
f2a41aa049 | ||
|
|
bb87b80a92 | ||
|
|
ebfbe29217 | ||
|
|
fad837e148 | ||
|
|
7dc84c0d6d | ||
|
|
74807fe251 | ||
|
|
bf9773be20 | ||
|
|
18961ff555 | ||
|
|
1f6e0342d6 | ||
|
|
7d2bc58ba2 | ||
|
|
556b53181f | ||
|
|
ca904d69e5 | ||
|
|
f461d459d2 | ||
|
|
6e535c11fd | ||
|
|
49d3262380 | ||
|
|
1ee3dec0cc | ||
|
|
15637642bb | ||
|
|
3c950c2b9e | ||
|
|
7811039651 | ||
|
|
ec5f7b38d0 | ||
|
|
2bb361dc19 | ||
|
|
3445e484ae | ||
|
|
efd6bf2afe | ||
|
|
cd2e6e1b24 | ||
|
|
99b8d24db3 | ||
|
|
8116b569c1 | ||
|
|
da791c5fed | ||
|
|
fbd9c59bfd | ||
|
|
3a1b3d19c5 | ||
|
|
238076f534 | ||
|
|
214d74ae11 | ||
|
|
30324f6113 | ||
|
|
68f0a25873 | ||
|
|
cd5bc4e930 | ||
|
|
1d8f729c95 | ||
|
|
f0d2fb53d4 | ||
|
|
0445c680ba | ||
|
|
12453942c8 | ||
|
|
b18a5be940 | ||
|
|
c2234747e8 | ||
|
|
d6c9ab43ec | ||
|
|
db16a87f74 | ||
|
|
5b0d2ec97b | ||
|
|
b906db3b24 | ||
|
|
df0af2a11f | ||
|
|
706dd3e616 | ||
|
|
bbec58e049 | ||
|
|
381b7d85f4 | ||
|
|
c17c056af3 | ||
|
|
a26a85cd1f | ||
|
|
9b68b1d327 | ||
|
|
6a6631052e | ||
|
|
d4ad3a953a | ||
|
|
7bb63a78c5 | ||
|
|
26c859f14c | ||
|
|
dd5c9bf3f6 | ||
|
|
3db40fea31 | ||
|
|
8f1c198406 | ||
|
|
44d754c59d |
3
.eslintignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules/
|
||||||
|
compiled/
|
||||||
|
dist/
|
||||||
6
.eslintrc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": ["standard", "standard-jsx"],
|
||||||
|
"rules": {
|
||||||
|
"no-useless-escape": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
6
.travis.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- 'stable'
|
||||||
|
- 'lts/*'
|
||||||
|
|
||||||
|
script: npm run lint && npm run test
|
||||||
@@ -37,6 +37,9 @@ export default class CodeEditor extends React.Component {
|
|||||||
}
|
}
|
||||||
this.props.onBlur != null && this.props.onBlur(e)
|
this.props.onBlur != null && this.props.onBlur(e)
|
||||||
}
|
}
|
||||||
|
this.loadStyleHandler = (e) => {
|
||||||
|
this.editor.refresh()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
@@ -49,8 +52,8 @@ export default class CodeEditor extends React.Component {
|
|||||||
indentUnit: this.props.indentSize,
|
indentUnit: this.props.indentSize,
|
||||||
tabSize: this.props.indentSize,
|
tabSize: this.props.indentSize,
|
||||||
indentWithTabs: this.props.indentType !== 'space',
|
indentWithTabs: this.props.indentType !== 'space',
|
||||||
keyMap: 'sublime',
|
keyMap: this.props.keyMap,
|
||||||
inputStyle: 'contenteditable',
|
inputStyle: 'textarea',
|
||||||
extraKeys: {
|
extraKeys: {
|
||||||
Tab: function (cm) {
|
Tab: function (cm) {
|
||||||
if (cm.somethingSelected()) cm.indentSelection('add')
|
if (cm.somethingSelected()) cm.indentSelection('add')
|
||||||
@@ -72,11 +75,16 @@ export default class CodeEditor extends React.Component {
|
|||||||
|
|
||||||
this.editor.on('blur', this.blurHandler)
|
this.editor.on('blur', this.blurHandler)
|
||||||
this.editor.on('change', this.changeHandler)
|
this.editor.on('change', this.changeHandler)
|
||||||
|
|
||||||
|
let editorTheme = document.getElementById('editorTheme')
|
||||||
|
editorTheme.addEventListener('load', this.loadStyleHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
this.editor.off('blur', this.blurHandler)
|
this.editor.off('blur', this.blurHandler)
|
||||||
this.editor.off('change', this.changeHandler)
|
this.editor.off('change', this.changeHandler)
|
||||||
|
let editorTheme = document.getElementById('editorTheme')
|
||||||
|
editorTheme.removeEventListener('load', this.loadStyleHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate (prevProps, prevState) {
|
componentDidUpdate (prevProps, prevState) {
|
||||||
@@ -86,7 +94,7 @@ export default class CodeEditor extends React.Component {
|
|||||||
}
|
}
|
||||||
if (prevProps.theme !== this.props.theme) {
|
if (prevProps.theme !== this.props.theme) {
|
||||||
this.editor.setOption('theme', this.props.theme)
|
this.editor.setOption('theme', this.props.theme)
|
||||||
needRefresh = true
|
// editor should be refreshed after css loaded
|
||||||
}
|
}
|
||||||
if (prevProps.fontSize !== this.props.fontSize) {
|
if (prevProps.fontSize !== this.props.fontSize) {
|
||||||
needRefresh = true
|
needRefresh = true
|
||||||
@@ -94,6 +102,9 @@ export default class CodeEditor extends React.Component {
|
|||||||
if (prevProps.fontFamily !== this.props.fontFamily) {
|
if (prevProps.fontFamily !== this.props.fontFamily) {
|
||||||
needRefresh = true
|
needRefresh = true
|
||||||
}
|
}
|
||||||
|
if (prevProps.keyMap !== this.props.keyMap) {
|
||||||
|
needRefresh = true
|
||||||
|
}
|
||||||
|
|
||||||
if (prevProps.indentSize !== this.props.indentSize) {
|
if (prevProps.indentSize !== this.props.indentSize) {
|
||||||
this.editor.setOption('indentUnit', this.props.indentSize)
|
this.editor.setOption('indentUnit', this.props.indentSize)
|
||||||
@@ -186,6 +197,7 @@ CodeEditor.propTypes = {
|
|||||||
CodeEditor.defaultProps = {
|
CodeEditor.defaultProps = {
|
||||||
readOnly: false,
|
readOnly: false,
|
||||||
theme: 'xcode',
|
theme: 'xcode',
|
||||||
|
keyMap: 'sublime',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontFamily: 'Monaco, Consolas',
|
fontFamily: 'Monaco, Consolas',
|
||||||
indentSize: 4,
|
indentSize: 4,
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ class MarkdownEditor extends React.Component {
|
|||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
status: 'PREVIEW'
|
status: 'PREVIEW',
|
||||||
|
renderValue: props.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,6 +22,33 @@ class MarkdownEditor extends React.Component {
|
|||||||
this.value = this.refs.code.value
|
this.value = this.refs.code.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps (props) {
|
||||||
|
if (props.value !== this.props.value) {
|
||||||
|
this.queueRendering(props.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
this.cancelQueue()
|
||||||
|
}
|
||||||
|
|
||||||
|
queueRendering (value) {
|
||||||
|
clearTimeout(this.renderTimer)
|
||||||
|
this.renderTimer = setTimeout(() => {
|
||||||
|
this.renderPreview(value)
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelQueue () {
|
||||||
|
clearTimeout(this.renderTimer)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderPreview (value) {
|
||||||
|
this.setState({
|
||||||
|
renderValue: value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
handleChange (e) {
|
handleChange (e) {
|
||||||
this.value = this.refs.code.value
|
this.value = this.refs.code.value
|
||||||
this.props.onChange(e)
|
this.props.onChange(e)
|
||||||
@@ -110,10 +138,13 @@ class MarkdownEditor extends React.Component {
|
|||||||
|
|
||||||
reload () {
|
reload () {
|
||||||
this.refs.code.reload()
|
this.refs.code.reload()
|
||||||
|
this.cancelQueue()
|
||||||
|
this.renderPreview(this.props.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
let { className, value, config } = this.props
|
let { className, value, config } = this.props
|
||||||
|
|
||||||
let editorFontSize = parseInt(config.editor.fontSize, 10)
|
let editorFontSize = parseInt(config.editor.fontSize, 10)
|
||||||
if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
|
if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
|
||||||
let editorIndentSize = parseInt(config.editor.indentSize, 10)
|
let editorIndentSize = parseInt(config.editor.indentSize, 10)
|
||||||
@@ -135,6 +166,7 @@ class MarkdownEditor extends React.Component {
|
|||||||
mode='GitHub Flavored Markdown'
|
mode='GitHub Flavored Markdown'
|
||||||
value={value}
|
value={value}
|
||||||
theme={config.editor.theme}
|
theme={config.editor.theme}
|
||||||
|
keyMap={config.editor.keyMap}
|
||||||
fontFamily={config.editor.fontFamily}
|
fontFamily={config.editor.fontFamily}
|
||||||
fontSize={editorFontSize}
|
fontSize={editorFontSize}
|
||||||
indentType={config.editor.indentType}
|
indentType={config.editor.indentType}
|
||||||
@@ -148,15 +180,17 @@ class MarkdownEditor extends React.Component {
|
|||||||
}
|
}
|
||||||
style={previewStyle}
|
style={previewStyle}
|
||||||
theme={config.ui.theme}
|
theme={config.ui.theme}
|
||||||
|
keyMap={config.editor.keyMap}
|
||||||
fontSize={config.preview.fontSize}
|
fontSize={config.preview.fontSize}
|
||||||
fontFamily={config.preview.fontFamily}
|
fontFamily={config.preview.fontFamily}
|
||||||
codeBlockTheme={config.preview.codeBlockTheme}
|
codeBlockTheme={config.preview.codeBlockTheme}
|
||||||
codeBlockFontFamily={config.editor.fontFamily}
|
codeBlockFontFamily={config.editor.fontFamily}
|
||||||
lineNumber={config.preview.lineNumber}
|
lineNumber={config.preview.lineNumber}
|
||||||
|
indentSize={editorIndentSize}
|
||||||
ref='preview'
|
ref='preview'
|
||||||
onContextMenu={(e) => this.handleContextMenu(e)}
|
onContextMenu={(e) => this.handleContextMenu(e)}
|
||||||
tabIndex='0'
|
tabIndex='0'
|
||||||
value={value}
|
value={this.state.renderValue}
|
||||||
onMouseUp={(e) => this.handlePreviewMouseUp(e)}
|
onMouseUp={(e) => this.handlePreviewMouseUp(e)}
|
||||||
onMouseDown={(e) => this.handlePreviewMouseDown(e)}
|
onMouseDown={(e) => this.handlePreviewMouseDown(e)}
|
||||||
onCheckboxClick={(e) => this.handleCheckboxClick(e)}
|
onCheckboxClick={(e) => this.handleCheckboxClick(e)}
|
||||||
|
|||||||
@@ -1,11 +1,77 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from 'react'
|
||||||
import markdown from 'browser/lib/markdown'
|
import markdown from 'browser/lib/markdown'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import hljsTheme from 'browser/lib/hljsThemes'
|
import CodeMirror from 'codemirror'
|
||||||
|
import consts from 'browser/lib/consts'
|
||||||
|
import Raphael from 'raphael'
|
||||||
|
import flowchart from 'flowchart'
|
||||||
|
import SequenceDiagram from 'js-sequence-diagrams'
|
||||||
|
|
||||||
|
function decodeHTMLEntities (text) {
|
||||||
|
var entities = [
|
||||||
|
['apos', '\''],
|
||||||
|
['amp', '&'],
|
||||||
|
['lt', '<'],
|
||||||
|
['gt', '>']
|
||||||
|
]
|
||||||
|
|
||||||
|
for (var i = 0, max = entities.length; i < max; ++i) {
|
||||||
|
text = text.replace(new RegExp('&' + entities[i][0] + ';', 'g'), entities[i][1])
|
||||||
|
}
|
||||||
|
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
const { remote } = require('electron')
|
||||||
|
const { app } = remote
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
const markdownStyle = require('!!css!stylus?sourceMap!./markdown.styl')[0][1]
|
const markdownStyle = require('!!css!stylus?sourceMap!./markdown.styl')[0][1]
|
||||||
const { shell } = require('electron')
|
const appPath = 'file://' + (process.env.NODE_ENV === 'production'
|
||||||
|
? app.getAppPath()
|
||||||
|
: path.resolve())
|
||||||
|
|
||||||
|
function buildStyle (fontFamily, fontSize, codeBlockFontFamily, lineNumber) {
|
||||||
|
return `
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Lato';
|
||||||
|
src: url('${appPath}/resources/fonts/Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
|
||||||
|
url('${appPath}/resources/fonts/Lato-Regular.woff') format('woff'), /* Modern Browsers */
|
||||||
|
url('${appPath}/resources/fonts/Lato-Regular.ttf') format('truetype');
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
}
|
||||||
|
${markdownStyle}
|
||||||
|
body {
|
||||||
|
font-family: ${fontFamily.join(', ')};
|
||||||
|
font-size: ${fontSize}px;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
font-family: ${codeBlockFontFamily.join(', ')};
|
||||||
|
}
|
||||||
|
.lineNumber {
|
||||||
|
${lineNumber && 'display: block !important;'}
|
||||||
|
font-family: ${codeBlockFontFamily.join(', ')};
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2 {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
padding-bottom: 4px;
|
||||||
|
margin: 1em 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
padding-bottom: 0.2em;
|
||||||
|
margin: 1em 0 0.37em;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
const { shell } = require('electron')
|
||||||
const OSX = global.process.platform === 'darwin'
|
const OSX = global.process.platform === 'darwin'
|
||||||
|
|
||||||
const defaultFontFamily = ['helvetica', 'arial', 'sans-serif']
|
const defaultFontFamily = ['helvetica', 'arial', 'sans-serif']
|
||||||
@@ -30,14 +96,15 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
|
||||||
let href = e.target.getAttribute('href')
|
let anchor = e.target.closest('a')
|
||||||
|
let href = anchor.getAttribute('href')
|
||||||
if (_.isString(href) && href.match(/^#/)) {
|
if (_.isString(href) && href.match(/^#/)) {
|
||||||
let targetElement = this.refs.root.contentWindow.document.getElementById(href.substring(1, href.length))
|
let targetElement = this.refs.root.contentWindow.document.getElementById(href.substring(1, href.length))
|
||||||
if (targetElement != null) {
|
if (targetElement != null) {
|
||||||
this.getWindow().scrollTo(0, targetElement.offsetTop)
|
this.getWindow().scrollTo(0, targetElement.offsetTop)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
shell.openExternal(e.target.href)
|
shell.openExternal(href)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,9 +135,17 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.refs.root.setAttribute('sandbox', 'allow-same-origin')
|
this.refs.root.setAttribute('sandbox', 'allow-scripts')
|
||||||
this.refs.root.contentWindow.document.body.addEventListener('contextmenu', this.contextMenuHandler)
|
this.refs.root.contentWindow.document.body.addEventListener('contextmenu', this.contextMenuHandler)
|
||||||
|
|
||||||
|
this.refs.root.contentWindow.document.head.innerHTML = `
|
||||||
|
<style id='style'></style>
|
||||||
|
<link rel="stylesheet" href="${appPath}/node_modules/katex/dist/katex.min.css">
|
||||||
|
<link rel="stylesheet" href="${appPath}/node_modules/codemirror/lib/codemirror.css">
|
||||||
|
<link rel="stylesheet" id="codeTheme">
|
||||||
|
`
|
||||||
this.rewriteIframe()
|
this.rewriteIframe()
|
||||||
|
this.applyStyle()
|
||||||
|
|
||||||
this.refs.root.contentWindow.document.addEventListener('mousedown', this.mouseDownHandler)
|
this.refs.root.contentWindow.document.addEventListener('mousedown', this.mouseDownHandler)
|
||||||
this.refs.root.contentWindow.document.addEventListener('mouseup', this.mouseUpHandler)
|
this.refs.root.contentWindow.document.addEventListener('mouseup', this.mouseUpHandler)
|
||||||
@@ -83,71 +158,113 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate (prevProps) {
|
componentDidUpdate (prevProps) {
|
||||||
if (prevProps.value !== this.props.value ||
|
if (prevProps.value !== this.props.value) this.rewriteIframe()
|
||||||
prevProps.fontFamily !== this.props.fontFamily ||
|
if (prevProps.fontFamily !== this.props.fontFamily ||
|
||||||
prevProps.fontSize !== this.props.fontSize ||
|
prevProps.fontSize !== this.props.fontSize ||
|
||||||
prevProps.codeBlockFontFamily !== this.props.codeBlockFontFamily ||
|
prevProps.codeBlockFontFamily !== this.props.codeBlockFontFamily ||
|
||||||
prevProps.codeBlockTheme !== this.props.codeBlockTheme ||
|
prevProps.codeBlockTheme !== this.props.codeBlockTheme ||
|
||||||
prevProps.lineNumber !== this.props.lineNumber ||
|
prevProps.lineNumber !== this.props.lineNumber ||
|
||||||
prevProps.theme !== this.props.theme
|
prevProps.theme !== this.props.theme) {
|
||||||
) this.rewriteIframe()
|
this.applyStyle()
|
||||||
|
this.rewriteIframe()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rewriteIframe () {
|
applyStyle () {
|
||||||
Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
|
let { fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme } = this.props
|
||||||
el.removeEventListener('click', this.anchorClickHandler)
|
|
||||||
})
|
|
||||||
Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('input[type="checkbox"]'), (el) => {
|
|
||||||
el.removeEventListener('click', this.checkboxClickHandler)
|
|
||||||
})
|
|
||||||
|
|
||||||
let { value, fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme, theme } = this.props
|
|
||||||
fontFamily = _.isString(fontFamily) && fontFamily.trim().length > 0
|
fontFamily = _.isString(fontFamily) && fontFamily.trim().length > 0
|
||||||
? [fontFamily].concat(defaultFontFamily)
|
? [fontFamily].concat(defaultFontFamily)
|
||||||
: defaultFontFamily
|
: defaultFontFamily
|
||||||
codeBlockFontFamily = _.isString(codeBlockFontFamily) && codeBlockFontFamily.trim().length > 0
|
codeBlockFontFamily = _.isString(codeBlockFontFamily) && codeBlockFontFamily.trim().length > 0
|
||||||
? [codeBlockFontFamily].concat(defaultCodeBlockFontFamily)
|
? [codeBlockFontFamily].concat(defaultCodeBlockFontFamily)
|
||||||
: defaultCodeBlockFontFamily
|
: defaultCodeBlockFontFamily
|
||||||
codeBlockTheme = hljsTheme().some((theme) => theme.name === codeBlockTheme) ? codeBlockTheme : 'xcode'
|
|
||||||
|
|
||||||
this.refs.root.contentWindow.document.head.innerHTML = `
|
this.setCodeTheme(codeBlockTheme)
|
||||||
<style>
|
this.getWindow().document.getElementById('style').innerHTML = buildStyle(fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme, lineNumber)
|
||||||
@font-face {
|
}
|
||||||
font-family: 'Lato';
|
|
||||||
src: url('../resources/fonts/Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
|
setCodeTheme (theme) {
|
||||||
url('../resources/fonts/Lato-Regular.woff') format('woff'), /* Modern Browsers */
|
theme = consts.THEMES.some((_theme) => _theme === theme) && theme !== 'default'
|
||||||
url('../resources/fonts/Lato-Regular.ttf') format('truetype');
|
? theme
|
||||||
font-style: normal;
|
: 'elegant'
|
||||||
font-weight: normal;
|
this.getWindow().document.getElementById('codeTheme').href = `${appPath}/node_modules/codemirror/theme/${theme}.css`
|
||||||
text-rendering: optimizeLegibility;
|
}
|
||||||
}
|
|
||||||
${markdownStyle}
|
rewriteIframe () {
|
||||||
body {
|
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
|
||||||
font-family: ${fontFamily.join(', ')};
|
el.removeEventListener('click', this.anchorClickHandler)
|
||||||
font-size: ${fontSize}px;
|
})
|
||||||
}
|
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('input[type="checkbox"]'), (el) => {
|
||||||
code {
|
el.removeEventListener('click', this.checkboxClickHandler)
|
||||||
font-family: ${codeBlockFontFamily.join(', ')};
|
})
|
||||||
}
|
|
||||||
.lineNumber {
|
let { value, theme, indentSize, codeBlockTheme } = this.props
|
||||||
${lineNumber && 'display: block !important;'}
|
|
||||||
font-family: ${codeBlockFontFamily.join(', ')};
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<link rel="stylesheet" href="../node_modules/highlight.js/styles/${codeBlockTheme}.css">
|
|
||||||
<link rel="stylesheet" href="../compiled/katex-style.css">
|
|
||||||
`
|
|
||||||
|
|
||||||
this.refs.root.contentWindow.document.body.setAttribute('data-theme', theme)
|
this.refs.root.contentWindow.document.body.setAttribute('data-theme', theme)
|
||||||
this.refs.root.contentWindow.document.body.innerHTML = markdown.render(value)
|
this.refs.root.contentWindow.document.body.innerHTML = markdown.render(value)
|
||||||
|
|
||||||
Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
|
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
|
||||||
el.addEventListener('click', this.anchorClickHandler)
|
el.addEventListener('click', this.anchorClickHandler)
|
||||||
})
|
})
|
||||||
Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('input[type="checkbox"]'), (el) => {
|
|
||||||
|
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('input[type="checkbox"]'), (el) => {
|
||||||
el.addEventListener('click', this.checkboxClickHandler)
|
el.addEventListener('click', this.checkboxClickHandler)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
codeBlockTheme = consts.THEMES.some((_theme) => _theme === codeBlockTheme)
|
||||||
|
? codeBlockTheme
|
||||||
|
: 'default'
|
||||||
|
|
||||||
|
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.code code'), (el) => {
|
||||||
|
let syntax = CodeMirror.findModeByName(el.className)
|
||||||
|
if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text')
|
||||||
|
CodeMirror.requireMode(syntax.mode, () => {
|
||||||
|
let content = el.innerHTML
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.parentNode.className += ` cm-s-${codeBlockTheme} CodeMirror`
|
||||||
|
CodeMirror.runMode(content, syntax.mime, el, {
|
||||||
|
tabSize: indentSize
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
let opts = {}
|
||||||
|
// if (this.props.theme === 'dark') {
|
||||||
|
// opts['font-color'] = '#DDD'
|
||||||
|
// opts['line-color'] = '#DDD'
|
||||||
|
// opts['element-color'] = '#DDD'
|
||||||
|
// opts['fill'] = '#3A404C'
|
||||||
|
// }
|
||||||
|
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.flowchart'), (el) => {
|
||||||
|
Raphael.setWindow(this.getWindow())
|
||||||
|
try {
|
||||||
|
let diagram = flowchart.parse(decodeHTMLEntities(el.innerHTML))
|
||||||
|
el.innerHTML = ''
|
||||||
|
diagram.drawSVG(el, opts)
|
||||||
|
_.forEach(el.querySelectorAll('a'), (el) => {
|
||||||
|
el.addEventListener('click', this.anchorClickHandler)
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
el.className = 'flowchart-error'
|
||||||
|
el.innerHTML = 'Flowchart parse error: ' + e.message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.sequence'), (el) => {
|
||||||
|
Raphael.setWindow(this.getWindow())
|
||||||
|
try {
|
||||||
|
let diagram = SequenceDiagram.parse(decodeHTMLEntities(el.innerHTML))
|
||||||
|
el.innerHTML = ''
|
||||||
|
diagram.drawSVG(el, {theme: 'simple'})
|
||||||
|
_.forEach(el.querySelectorAll('a'), (el) => {
|
||||||
|
el.addEventListener('click', this.anchorClickHandler)
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
el.className = 'sequence-error'
|
||||||
|
el.innerHTML = 'Sequence diagram parse error: ' + e.message
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
focus () {
|
focus () {
|
||||||
|
|||||||
100
browser/components/NoteItem.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview Note item component.
|
||||||
|
*/
|
||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import { isArray } from 'lodash'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './NoteItem.styl'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Tag element component.
|
||||||
|
* @param {string} tagName
|
||||||
|
* @return {React.Component}
|
||||||
|
*/
|
||||||
|
const TagElement = ({ tagName }) => (
|
||||||
|
<span styleName='item-bottom-tagList-item' key={tagName}>
|
||||||
|
{tagName}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Tag element list component.
|
||||||
|
* @param {Array|null} tags
|
||||||
|
* @return {React.Component}
|
||||||
|
*/
|
||||||
|
const TagElementList = (tags) => {
|
||||||
|
if (!isArray(tags)) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const tagElements = tags.map(tag => (
|
||||||
|
TagElement({tagName: tag})
|
||||||
|
))
|
||||||
|
|
||||||
|
return tagElements
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Note item component when using normal display mode.
|
||||||
|
* @param {boolean} isActive
|
||||||
|
* @param {Object} note
|
||||||
|
* @param {Function} handleNoteClick
|
||||||
|
* @param {Function} handleNoteContextMenu
|
||||||
|
* @param {string} dateDisplay
|
||||||
|
*/
|
||||||
|
const NoteItem = ({ isActive, note, dateDisplay, handleNoteClick, handleNoteContextMenu }) => (
|
||||||
|
<div styleName={isActive
|
||||||
|
? 'item--active'
|
||||||
|
: 'item'
|
||||||
|
}
|
||||||
|
key={`${note.storage}-${note.key}`}
|
||||||
|
onClick={e => handleNoteClick(e, `${note.storage}-${note.key}`)}
|
||||||
|
onContextMenu={e => handleNoteContextMenu(e, `${note.storage}-${note.key}`)}
|
||||||
|
>
|
||||||
|
<div styleName='item-wrapper'>
|
||||||
|
<div styleName='item-bottom-time'>{dateDisplay}</div>
|
||||||
|
|
||||||
|
<div styleName='item-title'>
|
||||||
|
{note.title.trim().length > 0
|
||||||
|
? note.title
|
||||||
|
: <span styleName='item-title-empty'>Empty</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div styleName='item-bottom'>
|
||||||
|
<div styleName='item-bottom-tagList'>
|
||||||
|
{note.tags.length > 0
|
||||||
|
? TagElementList(note.tags)
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{note.type === 'SNIPPET_NOTE'
|
||||||
|
? <i styleName='item-title-icon' className='fa fa-fw fa-code' />
|
||||||
|
: <i styleName='item-title-icon' className='fa fa-fw fa-file-text-o' />
|
||||||
|
}
|
||||||
|
|
||||||
|
{note.isStarred
|
||||||
|
? <i styleName='item-star' className='fa fa-star' /> : ''
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
NoteItem.propTypes = {
|
||||||
|
isActive: PropTypes.bool.isRequired,
|
||||||
|
dateDisplay: PropTypes.string.isRequired,
|
||||||
|
note: PropTypes.shape({
|
||||||
|
storage: PropTypes.string.isRequired,
|
||||||
|
key: PropTypes.string.isRequired,
|
||||||
|
type: PropTypes.string.isRequired,
|
||||||
|
title: PropTypes.string.isrequired,
|
||||||
|
tags: PropTypes.array,
|
||||||
|
isStarred: PropTypes.bool.isRequired
|
||||||
|
}),
|
||||||
|
handleNoteClick: PropTypes.func.isRequired,
|
||||||
|
handleNoteContextMenu: PropTypes.func.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(NoteItem, styles)
|
||||||
168
browser/components/NoteItem.styl
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
$control-height = 30px
|
||||||
|
|
||||||
|
.root
|
||||||
|
absolute left bottom
|
||||||
|
top $topBar-height - 1
|
||||||
|
background-color $ui-noteList-backgroundColor
|
||||||
|
|
||||||
|
.item
|
||||||
|
position relative
|
||||||
|
padding 0 25px
|
||||||
|
user-select none
|
||||||
|
cursor pointer
|
||||||
|
background-color $ui-noteList-backgroundColor
|
||||||
|
transition background-color 0.15s
|
||||||
|
&:hover
|
||||||
|
background-color alpha($ui-active-color, 20%)
|
||||||
|
&:active
|
||||||
|
background-color $ui-active-color
|
||||||
|
color white
|
||||||
|
.item-title
|
||||||
|
.item-title-empty
|
||||||
|
.item-bottom-tagList-empty
|
||||||
|
.item-bottom-time
|
||||||
|
.item-title-icon
|
||||||
|
color white
|
||||||
|
.item-bottom-tagList-item
|
||||||
|
background-color transparent
|
||||||
|
color white
|
||||||
|
|
||||||
|
.item-wrapper
|
||||||
|
padding 20px 0
|
||||||
|
border-bottom $ui-border
|
||||||
|
|
||||||
|
.item--active
|
||||||
|
@extend .item
|
||||||
|
background-color $ui-active-color
|
||||||
|
color white
|
||||||
|
.item-title
|
||||||
|
.item-title-empty
|
||||||
|
.item-bottom-tagList-empty
|
||||||
|
.item-bottom-time
|
||||||
|
.item-title-icon
|
||||||
|
color white
|
||||||
|
.item-bottom-tagList-item
|
||||||
|
background-color transparent
|
||||||
|
color white
|
||||||
|
.item-wrapper
|
||||||
|
border-color transparent
|
||||||
|
&:hover
|
||||||
|
background-color $ui-active-color
|
||||||
|
|
||||||
|
.item-title
|
||||||
|
font-size 14px
|
||||||
|
height 40px
|
||||||
|
box-sizing border-box
|
||||||
|
line-height 24px
|
||||||
|
padding-top 5px
|
||||||
|
padding-bottom 20px
|
||||||
|
overflow ellipsis
|
||||||
|
color $ui-text-color
|
||||||
|
|
||||||
|
.item-title-icon
|
||||||
|
position absolute
|
||||||
|
top 20px
|
||||||
|
right 25px
|
||||||
|
font-size 14px
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
|
||||||
|
.item-title-empty
|
||||||
|
font-weight normal
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
|
||||||
|
.item-bottom
|
||||||
|
position relative
|
||||||
|
bottom 0px
|
||||||
|
margin-top 2px
|
||||||
|
height 20px
|
||||||
|
font-size 12px
|
||||||
|
line-height 20px
|
||||||
|
overflow ellipsis
|
||||||
|
display flex
|
||||||
|
|
||||||
|
.item-bottom-tagList
|
||||||
|
flex 1
|
||||||
|
overflow ellipsis
|
||||||
|
line-height 20px
|
||||||
|
color #FFFFFF
|
||||||
|
|
||||||
|
.item-bottom-tagList-item
|
||||||
|
font-size 12px
|
||||||
|
margin-right 8px
|
||||||
|
padding 0 10px
|
||||||
|
height 20px
|
||||||
|
box-sizing border-box
|
||||||
|
border-radius 20px
|
||||||
|
vertical-align middle
|
||||||
|
background-color $ui-tag-backgroundColor
|
||||||
|
color #FFFFFF
|
||||||
|
|
||||||
|
.item-bottom-tagList-empty
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
vertical-align middle
|
||||||
|
font-size 10px
|
||||||
|
margin-left 5px
|
||||||
|
|
||||||
|
.item-bottom-time
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
font-size 12px
|
||||||
|
|
||||||
|
.item-star
|
||||||
|
position absolute
|
||||||
|
top 20px
|
||||||
|
right 29px
|
||||||
|
width 34px
|
||||||
|
height 34px
|
||||||
|
color $ui-favorite-star-button-color
|
||||||
|
font-size 14px
|
||||||
|
padding 0
|
||||||
|
border-radius 17px
|
||||||
|
|
||||||
|
body[data-theme="dark"]
|
||||||
|
.root
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
|
|
||||||
|
.item
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
|
&:active
|
||||||
|
background-color $ui-active-color
|
||||||
|
&:hover
|
||||||
|
background-color alpha($ui-active-color, 20%)
|
||||||
|
|
||||||
|
.item-wrapper
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
|
||||||
|
.item--active
|
||||||
|
@extend .item
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-active-color
|
||||||
|
.item-wrapper
|
||||||
|
border-color transparent
|
||||||
|
.item-title
|
||||||
|
color white
|
||||||
|
.item-bottom-tagList-item
|
||||||
|
background-color transparent
|
||||||
|
color white
|
||||||
|
.item-bottom-tagList-empty
|
||||||
|
color white
|
||||||
|
&:hover
|
||||||
|
background-color $ui-active-color
|
||||||
|
|
||||||
|
.item-title
|
||||||
|
color $ui-dark-text-color
|
||||||
|
|
||||||
|
.item-title-icon
|
||||||
|
color $ui-darkinactive-text-color
|
||||||
|
|
||||||
|
.item-title-empty
|
||||||
|
color $ui-dark-inactive-text-color
|
||||||
|
|
||||||
|
.item-bottom-tagList-item
|
||||||
|
background-color $ui-dark-tag-backgroundColor
|
||||||
|
color $ui-dark-text-color
|
||||||
|
|
||||||
|
.item-bottom-tagList-empty
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
vertical-align middle
|
||||||
49
browser/components/NoteItemSimple.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview Note item component with simple display mode.
|
||||||
|
*/
|
||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './NoteItemSimple.styl'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Note item component when using simple display mode.
|
||||||
|
* @param {boolean} isActive
|
||||||
|
* @param {Object} note
|
||||||
|
* @param {Function} handleNoteClick
|
||||||
|
* @param {Function} handleNoteContextMenu
|
||||||
|
*/
|
||||||
|
const NoteItemSimple = ({ isActive, note, handleNoteClick, handleNoteContextMenu }) => (
|
||||||
|
<div styleName={isActive
|
||||||
|
? 'item-simple--active'
|
||||||
|
: 'item-simple'
|
||||||
|
}
|
||||||
|
key={`${note.storage}-${note.key}`}
|
||||||
|
onClick={e => handleNoteClick(e, `${note.storage}-${note.key}`)}
|
||||||
|
onContextMenu={e => handleNoteContextMenu(e, `${note.storage}-${note.key}`)}
|
||||||
|
>
|
||||||
|
<div styleName='item-simple-title'>
|
||||||
|
{note.type === 'SNIPPET_NOTE'
|
||||||
|
? <i styleName='item-simple-title-icon' className='fa fa-fw fa-code' />
|
||||||
|
: <i styleName='item-simple-title-icon' className='fa fa-fw fa-file-text-o' />
|
||||||
|
}
|
||||||
|
{note.title.trim().length > 0
|
||||||
|
? note.title
|
||||||
|
: <span styleName='item-simple-title-empty'>Empty</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
NoteItemSimple.propTypes = {
|
||||||
|
isActive: PropTypes.bool.isRequired,
|
||||||
|
note: PropTypes.shape({
|
||||||
|
storage: PropTypes.string.isRequired,
|
||||||
|
key: PropTypes.string.isRequired,
|
||||||
|
type: PropTypes.string.isRequired,
|
||||||
|
title: PropTypes.string.isrequired
|
||||||
|
}),
|
||||||
|
handleNoteClick: PropTypes.func.isRequired,
|
||||||
|
handleNoteContextMenu: PropTypes.func.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(NoteItemSimple, styles)
|
||||||
89
browser/components/NoteItemSimple.styl
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
$control-height = 30px
|
||||||
|
|
||||||
|
.root
|
||||||
|
absolute left bottom
|
||||||
|
top $topBar-height - 1
|
||||||
|
background-color $ui-noteList-backgroundColor
|
||||||
|
|
||||||
|
.item-simple
|
||||||
|
position relative
|
||||||
|
padding 0 25px
|
||||||
|
user-select none
|
||||||
|
cursor pointer
|
||||||
|
background-color $ui-noteList-backgroundColor
|
||||||
|
transition background-color 0.15s
|
||||||
|
&:hover
|
||||||
|
background-color alpha($ui-active-color, 20%)
|
||||||
|
&:active
|
||||||
|
background-color $ui-active-color
|
||||||
|
color white
|
||||||
|
.item-simple-title
|
||||||
|
.item-simple-title-empty
|
||||||
|
.item-simple-title-icon
|
||||||
|
color white
|
||||||
|
|
||||||
|
.item-simple--active
|
||||||
|
@extend .item-simple
|
||||||
|
background-color $ui-active-color
|
||||||
|
color white
|
||||||
|
.item-simple-title
|
||||||
|
.item-simple-title-empty
|
||||||
|
border-color transparent
|
||||||
|
color white
|
||||||
|
.item-simple-title-icon
|
||||||
|
color white
|
||||||
|
&:hover
|
||||||
|
background-color $ui-active-color
|
||||||
|
|
||||||
|
.item-simple-title
|
||||||
|
font-size 14px
|
||||||
|
height 40px
|
||||||
|
box-sizing border-box
|
||||||
|
line-height 24px
|
||||||
|
padding-top 8px
|
||||||
|
overflow ellipsis
|
||||||
|
color $ui-text-color
|
||||||
|
border-bottom $ui-border
|
||||||
|
|
||||||
|
.item-simple-title-icon
|
||||||
|
font-size 12px
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
padding-right 6px
|
||||||
|
|
||||||
|
.item-simple-title-empty
|
||||||
|
font-weight normal
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
|
||||||
|
body[data-theme="dark"]
|
||||||
|
.root
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
|
|
||||||
|
.item-simple
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
|
&:active
|
||||||
|
background-color $ui-active-color
|
||||||
|
&:hover
|
||||||
|
background-color alpha($ui-active-color, 20%)
|
||||||
|
|
||||||
|
.item-simple--active
|
||||||
|
@extend .item-simple
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-active-color
|
||||||
|
.item-simple-title
|
||||||
|
.item-simple-title-empty
|
||||||
|
color white
|
||||||
|
border-color transparent
|
||||||
|
&:hover
|
||||||
|
background-color $ui-active-color
|
||||||
|
|
||||||
|
.item-simple-title
|
||||||
|
color $ui-dark-text-color
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
|
||||||
|
.item-simple-title-icon
|
||||||
|
color $ui-darkinactive-text-color
|
||||||
|
|
||||||
|
.item-simple-title-empty
|
||||||
|
color $ui-dark-inactive-text-color
|
||||||
@@ -12,7 +12,7 @@ export default class ProfileImage extends React.Component {
|
|||||||
className={className}
|
className={className}
|
||||||
width={this.props.size}
|
width={this.props.size}
|
||||||
height={this.props.size}
|
height={this.props.size}
|
||||||
src={src}/>
|
src={src} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
browser/components/SideNavFilter.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview Filter for all notes.
|
||||||
|
*/
|
||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './SideNavFilter.styl'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} isFolded
|
||||||
|
* @param {boolean} isHomeActive
|
||||||
|
* @param {Function} handleAllNotesButtonClick
|
||||||
|
* @param {boolean} isStarredActive
|
||||||
|
* @param {Function} handleStarredButtonClick
|
||||||
|
* @return {React.Component}
|
||||||
|
*/
|
||||||
|
const SideNavFilter = ({
|
||||||
|
isFolded, isHomeActive, handleAllNotesButtonClick,
|
||||||
|
isStarredActive, handleStarredButtonClick
|
||||||
|
}) => (
|
||||||
|
<div styleName={isFolded ? 'menu--folded' : 'menu'}>
|
||||||
|
<button styleName={isHomeActive ? 'menu-button--active' : 'menu-button'}
|
||||||
|
onClick={handleAllNotesButtonClick}
|
||||||
|
>
|
||||||
|
<i className='fa fa-book fa-fw' />
|
||||||
|
<span styleName='menu-button-label'>All Notes</span>
|
||||||
|
</button>
|
||||||
|
<button styleName={isStarredActive ? 'menu-button--active' : 'menu-button'}
|
||||||
|
onClick={handleStarredButtonClick}
|
||||||
|
>
|
||||||
|
<i className='fa fa-star fa-fw' />
|
||||||
|
<span styleName='menu-button-label'>Starred</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
SideNavFilter.propTypes = {
|
||||||
|
isFolded: PropTypes.bool,
|
||||||
|
isHomeActive: PropTypes.bool.isRequired,
|
||||||
|
handleAllNotesButtonClick: PropTypes.func.isRequired,
|
||||||
|
isStarredActive: PropTypes.bool.isRequired,
|
||||||
|
handleStarredButtonClick: PropTypes.func.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(SideNavFilter, styles)
|
||||||
58
browser/components/SideNavFilter.styl
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
.menu
|
||||||
|
margin-bottom 30px
|
||||||
|
|
||||||
|
.menu-button
|
||||||
|
navButtonColor()
|
||||||
|
height 32px
|
||||||
|
padding 0 15px
|
||||||
|
font-size 14px
|
||||||
|
width 100%
|
||||||
|
text-align left
|
||||||
|
overflow ellipsis
|
||||||
|
|
||||||
|
.menu-button--active
|
||||||
|
@extend .menu-button
|
||||||
|
background-color $ui-button--active-backgroundColor
|
||||||
|
color $ui-button--active-color
|
||||||
|
&:hover
|
||||||
|
background-color $ui-button--active-backgroundColor
|
||||||
|
|
||||||
|
.menu-button-label
|
||||||
|
margin-left 5px
|
||||||
|
|
||||||
|
.menu--folded
|
||||||
|
@extend .menu
|
||||||
|
.menu-button, .menu-button--active
|
||||||
|
text-align center
|
||||||
|
&:hover .menu-button-label
|
||||||
|
transition opacity 0.15s
|
||||||
|
opacity 1
|
||||||
|
.menu-button-label
|
||||||
|
position fixed
|
||||||
|
display inline-block
|
||||||
|
height 32px
|
||||||
|
left 44px
|
||||||
|
padding 0 10px
|
||||||
|
margin-top -8px
|
||||||
|
margin-left 0
|
||||||
|
overflow ellipsis
|
||||||
|
background-color $ui-tooltip-backgroundColor
|
||||||
|
z-index 10
|
||||||
|
color white
|
||||||
|
line-height 32px
|
||||||
|
border-top-right-radius 2px
|
||||||
|
border-bottom-right-radius 2px
|
||||||
|
pointer-events none
|
||||||
|
opacity 0
|
||||||
|
font-size 12px
|
||||||
|
|
||||||
|
body[data-theme="dark"]
|
||||||
|
.menu-button
|
||||||
|
navDarkButtonColor()
|
||||||
|
|
||||||
|
.menu-button--active
|
||||||
|
@extend .menu-button
|
||||||
|
background-color $ui-dark-button--active-backgroundColor
|
||||||
|
color $ui-dark-button--active-color
|
||||||
|
&:hover
|
||||||
|
background-color $ui-dark-button--active-backgroundColor
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './SnippetTab.styl'
|
import styles from './SnippetTab.styl'
|
||||||
import context from 'browser/lib/context'
|
import context from 'browser/lib/context'
|
||||||
@@ -117,7 +117,7 @@ class SnippetTab extends React.Component {
|
|||||||
<button styleName='deleteButton'
|
<button styleName='deleteButton'
|
||||||
onClick={(e) => this.handleDeleteButtonClick(e)}
|
onClick={(e) => this.handleDeleteButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-times'/>
|
<i className='fa fa-times' />
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -2,9 +2,6 @@
|
|||||||
position relative
|
position relative
|
||||||
flex 1
|
flex 1
|
||||||
overflow hidden
|
overflow hidden
|
||||||
border-right $ui-border
|
|
||||||
&:last-child
|
|
||||||
border-right none
|
|
||||||
&:hover
|
&:hover
|
||||||
.deleteButton
|
.deleteButton
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
@@ -13,11 +10,11 @@
|
|||||||
&:active
|
&:active
|
||||||
color white
|
color white
|
||||||
background-color $ui-active-color
|
background-color $ui-active-color
|
||||||
|
|
||||||
.root--active
|
.root--active
|
||||||
@extend .root
|
@extend .root
|
||||||
min-width 100px
|
min-width 100px
|
||||||
.button
|
border-bottom $ui-border
|
||||||
border-color $brand-color
|
|
||||||
|
|
||||||
.button
|
.button
|
||||||
width 100%
|
width 100%
|
||||||
@@ -31,8 +28,6 @@
|
|||||||
border-left 4px solid transparent
|
border-left 4px solid transparent
|
||||||
&:hover
|
&:hover
|
||||||
background-color $ui-button--hover-backgroundColor
|
background-color $ui-button--hover-backgroundColor
|
||||||
&:active, &:active:hover
|
|
||||||
border-color $brand-color
|
|
||||||
|
|
||||||
.deleteButton
|
.deleteButton
|
||||||
position absolute
|
position absolute
|
||||||
@@ -71,8 +66,6 @@ body[data-theme="dark"]
|
|||||||
.root--active
|
.root--active
|
||||||
color $ui-dark-text-color
|
color $ui-dark-text-color
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
.button
|
|
||||||
border-color $brand-color
|
|
||||||
&:hover
|
&:hover
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color $ui-dark-button--hover-backgroundColor
|
||||||
.deleteButton
|
.deleteButton
|
||||||
@@ -92,10 +85,6 @@ body[data-theme="dark"]
|
|||||||
&:hover
|
&:hover
|
||||||
color white
|
color white
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color $ui-dark-button--hover-backgroundColor
|
||||||
&:active
|
|
||||||
color $ui-dark-button--active-color
|
|
||||||
&:active, &:active:hover
|
|
||||||
color $ui-dark-button--active-color
|
|
||||||
|
|
||||||
.input
|
.input
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color $ui-dark-button--hover-backgroundColor
|
||||||
58
browser/components/StorageItem.js
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview Micro component for showing storage.
|
||||||
|
*/
|
||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import styles from './StorageItem.styl'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import { isNumber } from 'lodash'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} isActive
|
||||||
|
* @param {Function} handleButtonClick
|
||||||
|
* @param {Function} handleContextMenu
|
||||||
|
* @param {string} folderName
|
||||||
|
* @param {string} folderColor
|
||||||
|
* @param {boolean} isFolded
|
||||||
|
* @param {number} noteCount
|
||||||
|
* @return {React.Component}
|
||||||
|
*/
|
||||||
|
const StorageItem = ({
|
||||||
|
isActive, handleButtonClick, handleContextMenu, folderName,
|
||||||
|
folderColor, isFolded, noteCount
|
||||||
|
}) => (
|
||||||
|
<button styleName={isActive
|
||||||
|
? 'folderList-item--active'
|
||||||
|
: 'folderList-item'
|
||||||
|
}
|
||||||
|
onClick={handleButtonClick}
|
||||||
|
onContextMenu={handleContextMenu}
|
||||||
|
>
|
||||||
|
<span styleName={isFolded
|
||||||
|
? 'folderList-item-name--folded' : 'folderList-item-name'
|
||||||
|
}
|
||||||
|
style={{borderColor: folderColor}}
|
||||||
|
>
|
||||||
|
{isFolded ? folderName.substring(0, 1) : folderName}
|
||||||
|
</span>
|
||||||
|
{(!isFolded && isNumber(noteCount)) &&
|
||||||
|
<span styleName='folderList-item-noteCount'>{noteCount}</span>
|
||||||
|
}
|
||||||
|
{isFolded &&
|
||||||
|
<span styleName='folderList-item-tooltip'>
|
||||||
|
{folderName}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
|
||||||
|
StorageItem.propTypes = {
|
||||||
|
isActive: PropTypes.bool.isRequired,
|
||||||
|
handleButtonClick: PropTypes.func,
|
||||||
|
handleContextMenu: PropTypes.func,
|
||||||
|
folderName: PropTypes.string.isRequired,
|
||||||
|
folderColor: PropTypes.string,
|
||||||
|
isFolded: PropTypes.bool.isRequired,
|
||||||
|
noteCount: PropTypes.number
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(StorageItem, styles)
|
||||||
70
browser/components/StorageItem.styl
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
.root
|
||||||
|
width 100%
|
||||||
|
user-select none
|
||||||
|
|
||||||
|
.folderList-item
|
||||||
|
display flex
|
||||||
|
width 100%
|
||||||
|
height 26px
|
||||||
|
background-color transparent
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
padding 0
|
||||||
|
margin-bottom 5px
|
||||||
|
text-align left
|
||||||
|
border none
|
||||||
|
overflow ellipsis
|
||||||
|
font-size 14px
|
||||||
|
&:first-child
|
||||||
|
margin-top 0
|
||||||
|
&:hover
|
||||||
|
background-color $ui-button--hover-backgroundColor
|
||||||
|
&:active
|
||||||
|
color $ui-button--active-color
|
||||||
|
background-color $ui-button--active-backgroundColor
|
||||||
|
|
||||||
|
.folderList-item--active
|
||||||
|
@extend .folderList-item
|
||||||
|
color $ui-button--active-color
|
||||||
|
background-color $ui-button--active-backgroundColor
|
||||||
|
&:hover
|
||||||
|
color $ui-button--active-color
|
||||||
|
background-color $ui-button--active-backgroundColor
|
||||||
|
|
||||||
|
.folderList-item-name
|
||||||
|
display block
|
||||||
|
flex 1
|
||||||
|
padding 0 30px
|
||||||
|
height 26px
|
||||||
|
line-height 26px
|
||||||
|
border-width 0 0 0 3px
|
||||||
|
border-style solid
|
||||||
|
border-color transparent
|
||||||
|
overflow hidden
|
||||||
|
text-overflow ellipsis
|
||||||
|
|
||||||
|
.folderList-item-noteCount
|
||||||
|
float right
|
||||||
|
line-height 26px
|
||||||
|
padding-right 15px
|
||||||
|
font-size 12px
|
||||||
|
|
||||||
|
.folderList-item-tooltip
|
||||||
|
tooltip()
|
||||||
|
position fixed
|
||||||
|
padding 0 10px
|
||||||
|
left 44px
|
||||||
|
z-index 10
|
||||||
|
pointer-events none
|
||||||
|
opacity 0
|
||||||
|
border-top-right-radius 2px
|
||||||
|
border-bottom-right-radius 2px
|
||||||
|
height 26px
|
||||||
|
line-height 26px
|
||||||
|
|
||||||
|
.folderList-item:hover, .folderList-item--active:hover
|
||||||
|
.folderList-item-tooltip
|
||||||
|
opacity 1
|
||||||
|
|
||||||
|
.folderList-item-name--folded
|
||||||
|
@extend .folderList-item-name
|
||||||
|
padding-left 14px
|
||||||
@@ -55,6 +55,7 @@ body
|
|||||||
line-height 1.6
|
line-height 1.6
|
||||||
overflow-x hidden
|
overflow-x hidden
|
||||||
user-select all
|
user-select all
|
||||||
|
background-color $ui-noteDetail-backgroundColor
|
||||||
.katex
|
.katex
|
||||||
font 400 1.2em 'KaTeX_Main'
|
font 400 1.2em 'KaTeX_Main'
|
||||||
line-height 1.2em
|
line-height 1.2em
|
||||||
@@ -68,6 +69,12 @@ body
|
|||||||
padding 5px
|
padding 5px
|
||||||
margin -5px
|
margin -5px
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
|
.flowchart-error, .sequence-error
|
||||||
|
background-color errorBackgroundColor
|
||||||
|
color errorTextColor
|
||||||
|
padding 5px
|
||||||
|
border-radius 5px
|
||||||
|
justify-content left
|
||||||
li
|
li
|
||||||
label.taskListItem
|
label.taskListItem
|
||||||
margin-left -2em
|
margin-left -2em
|
||||||
@@ -191,7 +198,7 @@ code
|
|||||||
padding 0.2em 0.4em
|
padding 0.2em 0.4em
|
||||||
background-color #f7f7f7
|
background-color #f7f7f7
|
||||||
border-radius 3px
|
border-radius 3px
|
||||||
font-size 0.85em
|
font-size 1em
|
||||||
text-decoration none
|
text-decoration none
|
||||||
margin-right 2px
|
margin-right 2px
|
||||||
pre
|
pre
|
||||||
@@ -200,26 +207,40 @@ pre
|
|||||||
border-radius 5px
|
border-radius 5px
|
||||||
overflow-x auto
|
overflow-x auto
|
||||||
margin 0 0 1em
|
margin 0 0 1em
|
||||||
line-height 1.35
|
display flex
|
||||||
|
line-height 1.4em
|
||||||
|
&.flowchart, &.sequence
|
||||||
|
display flex
|
||||||
|
justify-content center
|
||||||
|
background-color white
|
||||||
|
&.CodeMirror
|
||||||
|
height initial
|
||||||
|
&>code
|
||||||
|
flex 1
|
||||||
|
overflow-x auto
|
||||||
code
|
code
|
||||||
margin 0
|
|
||||||
background-color inherit
|
background-color inherit
|
||||||
|
margin 0
|
||||||
padding 0
|
padding 0
|
||||||
border none
|
border none
|
||||||
border-radius 0
|
border-radius 0
|
||||||
pre
|
|
||||||
border none
|
|
||||||
margin -5px
|
|
||||||
&>span.lineNumber
|
&>span.lineNumber
|
||||||
display none
|
display none
|
||||||
float left
|
font-size 1em
|
||||||
font-size 0.85em
|
padding 0.5em 0
|
||||||
margin 0 0.5em 0 -0.5em
|
margin -0.5em 0.5em -0.5em -0.5em
|
||||||
border-right 1px solid
|
border-right 1px solid
|
||||||
text-align right
|
text-align right
|
||||||
|
border-top-left-radius 4px
|
||||||
|
border-bottom-left-radius 4px
|
||||||
|
&.CodeMirror-gutters
|
||||||
|
position initial
|
||||||
|
top initial
|
||||||
|
left initial
|
||||||
|
min-height 0 !important
|
||||||
&>span
|
&>span
|
||||||
display block
|
display block
|
||||||
padding 0 .5em 0 1em
|
padding 0 .5em 0
|
||||||
table
|
table
|
||||||
display block
|
display block
|
||||||
width 100%
|
width 100%
|
||||||
@@ -253,13 +274,14 @@ table
|
|||||||
themeDarkBackground = darken(#21252B, 10%)
|
themeDarkBackground = darken(#21252B, 10%)
|
||||||
themeDarkText = #DDDDDD
|
themeDarkText = #DDDDDD
|
||||||
themeDarkBorder = lighten(themeDarkBackground, 20%)
|
themeDarkBorder = lighten(themeDarkBackground, 20%)
|
||||||
themeDarkPreview = #282C34
|
themeDarkPreview = $ui-dark-noteDetail-backgroundColor
|
||||||
themeDarkTableOdd = themeDarkPreview
|
themeDarkTableOdd = themeDarkPreview
|
||||||
themeDarkTableEven = darken(themeDarkPreview, 10%)
|
themeDarkTableEven = darken(themeDarkPreview, 10%)
|
||||||
themeDarkTableHead = themeDarkTableEven
|
themeDarkTableHead = themeDarkTableEven
|
||||||
themeDarkTableBorder = themeDarkBorder
|
themeDarkTableBorder = themeDarkBorder
|
||||||
themeDarkModalButtonDefault = themeDarkPreview
|
themeDarkModalButtonDefault = themeDarkPreview
|
||||||
themeDarkModalButtonDanger = #BF360C
|
themeDarkModalButtonDanger = #BF360C
|
||||||
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
color themeDarkText
|
color themeDarkText
|
||||||
border-color themeDarkBorder
|
border-color themeDarkBorder
|
||||||
@@ -269,7 +291,7 @@ body[data-theme="dark"]
|
|||||||
|
|
||||||
code
|
code
|
||||||
border-color darken(themeDarkBorder, 10%)
|
border-color darken(themeDarkBorder, 10%)
|
||||||
background-color lighten(themeDarkPreview, 5%)
|
background-color lighten(themeDarkPreview, 10%)
|
||||||
|
|
||||||
pre
|
pre
|
||||||
border-color lighten(#21252B, 20%)
|
border-color lighten(#21252B, 20%)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ $list-width = 250px
|
|||||||
outline none
|
outline none
|
||||||
text-align center
|
text-align center
|
||||||
background-color transparent
|
background-color transparent
|
||||||
|
|
||||||
.result
|
.result
|
||||||
absolute left right bottom
|
absolute left right bottom
|
||||||
top $search-height
|
top $search-height
|
||||||
@@ -32,7 +33,7 @@ $list-width = 250px
|
|||||||
background-color $ui-backgroundColor
|
background-color $ui-backgroundColor
|
||||||
|
|
||||||
.result-nav-filter
|
.result-nav-filter
|
||||||
margin-bottom 5px
|
margin-bottom 10px
|
||||||
|
|
||||||
.result-nav-filter-option
|
.result-nav-filter-option
|
||||||
height 25px
|
height 25px
|
||||||
@@ -62,7 +63,7 @@ $list-width = 250px
|
|||||||
|
|
||||||
.result-nav-storageList
|
.result-nav-storageList
|
||||||
absolute bottom left right
|
absolute bottom left right
|
||||||
top 80px + 32px + 10px
|
top 80px + 32px + 10px + 10px
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
|
|
||||||
.result-list
|
.result-list
|
||||||
@@ -70,15 +71,15 @@ $list-width = 250px
|
|||||||
absolute top bottom
|
absolute top bottom
|
||||||
left $nav-width
|
left $nav-width
|
||||||
width $list-width
|
width $list-width
|
||||||
border-width 0 1px
|
|
||||||
border-style solid
|
|
||||||
border-color $ui-borderColor
|
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
|
box-shadow 2px 0 15px -8px #b1b1b1
|
||||||
|
z-index 1
|
||||||
|
|
||||||
.result-detail
|
.result-detail
|
||||||
absolute top bottom right
|
absolute top bottom right
|
||||||
left $nav-width + $list-width
|
left $nav-width + $list-width
|
||||||
|
background-color $ui-noteDetail-backgroundColor
|
||||||
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.root
|
.root
|
||||||
@@ -104,7 +105,10 @@ body[data-theme="dark"]
|
|||||||
|
|
||||||
.result-list
|
.result-list
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
|
box-shadow none
|
||||||
|
top 0
|
||||||
|
|
||||||
.result-detail
|
.result-detail
|
||||||
absolute top bottom right
|
absolute top bottom right
|
||||||
left $nav-width + $list-width
|
left $nav-width + $list-width
|
||||||
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './NoteDetail.styl'
|
import styles from './NoteDetail.styl'
|
||||||
import MarkdownPreview from 'browser/components/MarkdownPreview'
|
import MarkdownPreview from 'browser/components/MarkdownPreview'
|
||||||
@@ -97,9 +97,7 @@ class NoteDetail extends React.Component {
|
|||||||
let { note, config } = this.props
|
let { note, config } = this.props
|
||||||
if (note == null) {
|
if (note == null) {
|
||||||
return (
|
return (
|
||||||
<div styleName='root'>
|
<div styleName='root' />
|
||||||
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +152,7 @@ class NoteDetail extends React.Component {
|
|||||||
fontSize={editorFontSize}
|
fontSize={editorFontSize}
|
||||||
indentType={config.editor.indentType}
|
indentType={config.editor.indentType}
|
||||||
indentSize={editorIndentSize}
|
indentSize={editorIndentSize}
|
||||||
|
keyMap={config.editor.keyMap}
|
||||||
readOnly
|
readOnly
|
||||||
ref={'code-' + index}
|
ref={'code-' + index}
|
||||||
/>
|
/>
|
||||||
@@ -185,11 +184,13 @@ class NoteDetail extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<MarkdownPreview styleName='root'
|
<MarkdownPreview styleName='root'
|
||||||
|
theme={config.ui.theme}
|
||||||
fontSize={config.preview.fontSize}
|
fontSize={config.preview.fontSize}
|
||||||
fontFamily={config.preview.fontFamily}
|
fontFamily={config.preview.fontFamily}
|
||||||
codeBlockTheme={config.preview.codeBlockTheme}
|
codeBlockTheme={config.preview.codeBlockTheme}
|
||||||
codeBlockFontFamily={config.editor.fontFamily}
|
codeBlockFontFamily={config.editor.fontFamily}
|
||||||
lineNumber={config.preview.lineNumber}
|
lineNumber={config.preview.lineNumber}
|
||||||
|
indentSize={editorIndentSize}
|
||||||
value={note.content}
|
value={note.content}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
|
@import('../main/Detail/DetailVars.styl')
|
||||||
|
|
||||||
.root
|
.root
|
||||||
absolute top bottom left right
|
absolute top bottom left right
|
||||||
width 100%
|
left $note-detail-left-margin
|
||||||
|
right $note-detail-right-margin
|
||||||
height 100%
|
height 100%
|
||||||
|
width 365px
|
||||||
|
background-color $ui-noteDetail-backgroundColor
|
||||||
|
|
||||||
.description
|
.description
|
||||||
absolute top left right
|
absolute top left right
|
||||||
height 80px
|
height 80px
|
||||||
border-bottom $ui-border
|
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
|
|
||||||
.description-textarea
|
.description-textarea
|
||||||
@@ -18,52 +22,43 @@
|
|||||||
padding 10px
|
padding 10px
|
||||||
line-height 1.6
|
line-height 1.6
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
|
background-color $ui-noteDetail-backgroundColor
|
||||||
|
|
||||||
.tabList
|
.tabList
|
||||||
absolute left right
|
absolute left right
|
||||||
top 80px
|
top 80px
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
height 30px
|
height 30px
|
||||||
border-bottom $ui-border
|
|
||||||
display flex
|
display flex
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-noteDetail-backgroundColor
|
||||||
|
|
||||||
.tabList-item
|
.tabList-item
|
||||||
position relative
|
position relative
|
||||||
flex 1
|
flex 1
|
||||||
border-right $ui-border
|
overflow hidden
|
||||||
|
&:hover
|
||||||
|
background-color $ui-button--hover-backgroundColorg
|
||||||
|
|
||||||
.tabList-item--active
|
.tabList-item--active
|
||||||
@extend .tabList-item
|
@extend .tabList-item
|
||||||
.tabList-item-button
|
border-bottom $ui-border
|
||||||
border-color $brand-color
|
|
||||||
|
|
||||||
.tabList-item-button
|
.tabList-item-button
|
||||||
width 100%
|
width 100%
|
||||||
height 29px
|
height 29px
|
||||||
navButtonColor()
|
overflow ellipsis
|
||||||
outline none
|
text-align left
|
||||||
border-left 4px solid transparent
|
padding-right 30px
|
||||||
|
padding-left 10px
|
||||||
.tabList-item-deleteButton
|
|
||||||
position absolute
|
|
||||||
top 5px
|
|
||||||
height 20px
|
|
||||||
right 5px
|
|
||||||
width 20px
|
|
||||||
text-align center
|
|
||||||
border none
|
border none
|
||||||
padding 0
|
|
||||||
color transparent
|
|
||||||
background-color transparent
|
background-color transparent
|
||||||
border-radius 2px
|
transition 0.15s
|
||||||
.tabList-plusButton
|
&:hover
|
||||||
navButtonColor()
|
background-color $ui-button--hover-backgroundColor
|
||||||
width 30px
|
|
||||||
|
|
||||||
.tabView
|
.tabView
|
||||||
absolute left right bottom
|
absolute left right bottom
|
||||||
top 110px
|
top 130px
|
||||||
|
|
||||||
.tabView-content
|
.tabView-content
|
||||||
absolute top left right bottom
|
absolute top left right bottom
|
||||||
@@ -72,38 +67,31 @@
|
|||||||
width 100%
|
width 100%
|
||||||
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
|
.root
|
||||||
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
|
|
||||||
.description
|
.description
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
|
|
||||||
.description-textarea
|
.description-textarea
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
color white
|
color white
|
||||||
|
|
||||||
.tabList
|
.tabList
|
||||||
background-color $ui-button--active-backgroundColor
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
border-bottom-color $ui-dark-borderColor
|
|
||||||
background-color $ui-dark-backgroundColor
|
|
||||||
.tabList-item
|
.tabList-item
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
&:hover
|
&:hover
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color $ui-dark-button--hover-backgroundColor
|
||||||
.tabList-item--active
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
.tabList-item-button
|
|
||||||
border-color $brand-color
|
|
||||||
.tabList-item-button
|
|
||||||
navDarkButtonColor()
|
|
||||||
border-left 4px solid transparent
|
|
||||||
.tabList-plusButton
|
|
||||||
navDarkButtonColor()
|
|
||||||
|
|
||||||
.tabView-top
|
.tabList-item-button
|
||||||
border-color $ui-dark-borderColor
|
border none
|
||||||
.tabView-top-name
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
color $ui-dark-text-color
|
color $ui-dark-text-color
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color transparent
|
||||||
.tabView-top-mode
|
transition color background-color 0.15s
|
||||||
border-color $ui-dark-borderColor
|
border-left 4px solid transparent
|
||||||
background-color $dark-default-button-background
|
&:hover
|
||||||
color $ui-dark-inactive-text-color
|
color white
|
||||||
|
background-color $ui-dark-button--hover-backgroundColor
|
||||||
|
|||||||
@@ -1,85 +0,0 @@
|
|||||||
import React, { PropTypes } from 'react'
|
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
|
||||||
import styles from './NoteItem.styl'
|
|
||||||
import moment from 'moment'
|
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
class NoteItem extends React.Component {
|
|
||||||
constructor (props) {
|
|
||||||
super(props)
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleClick (e) {
|
|
||||||
this.props.onClick(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
let { note, folder, storage, isActive } = this.props
|
|
||||||
|
|
||||||
let tagList = _.isArray(note.tags)
|
|
||||||
? note.tags.map((tag) => {
|
|
||||||
return (
|
|
||||||
<span styleName='bottom-tagList-item'
|
|
||||||
key={tag}>
|
|
||||||
{tag}
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
: []
|
|
||||||
return (
|
|
||||||
<div styleName={isActive
|
|
||||||
? 'root--active'
|
|
||||||
: 'root'
|
|
||||||
}
|
|
||||||
key={note.storage + '-' + note.key}
|
|
||||||
onClick={(e) => this.handleClick(e)}
|
|
||||||
>
|
|
||||||
<div styleName='info'>
|
|
||||||
<div styleName='info-left'>
|
|
||||||
<span styleName='info-left-folder'
|
|
||||||
style={{borderColor: folder.color}}
|
|
||||||
>
|
|
||||||
{folder.name}
|
|
||||||
<span styleName='info-left-folder-surfix'>in {storage.name}</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div styleName='title'>
|
|
||||||
{note.type === 'SNIPPET_NOTE'
|
|
||||||
? <i styleName='title-icon' className='fa fa-fw fa-code'/>
|
|
||||||
: <i styleName='title-icon' className='fa fa-fw fa-file-text-o'/>
|
|
||||||
}
|
|
||||||
{note.title.trim().length > 0
|
|
||||||
? note.title
|
|
||||||
: <span styleName='title-empty'>Empty</span>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div styleName='bottom'>
|
|
||||||
<i styleName='bottom-tagIcon'
|
|
||||||
className='fa fa-tags fa-fw'
|
|
||||||
/>
|
|
||||||
<div styleName='bottom-tagList'>
|
|
||||||
{tagList.length > 0
|
|
||||||
? tagList
|
|
||||||
: <span styleName='bottom-tagList-empty'>Not tagged yet</span>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div styleName='bottom-time'>
|
|
||||||
{moment(note.updatedAt).fromNow()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NoteItem.propTypes = {
|
|
||||||
}
|
|
||||||
|
|
||||||
export default CSSModules(NoteItem, styles)
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
.root
|
|
||||||
position relative
|
|
||||||
border-bottom $ui-border
|
|
||||||
padding 2px 5px
|
|
||||||
user-select none
|
|
||||||
cursor pointer
|
|
||||||
transition background-color 0.15s
|
|
||||||
&:hover
|
|
||||||
background-color alpha($ui-active-color, 20%)
|
|
||||||
|
|
||||||
.root--active
|
|
||||||
@extend .root
|
|
||||||
background-color $ui-active-color
|
|
||||||
&:hover
|
|
||||||
background-color $ui-active-color
|
|
||||||
color white
|
|
||||||
.info-left-folder
|
|
||||||
.info-left-folder-surfix
|
|
||||||
.title
|
|
||||||
.title-icon
|
|
||||||
.title-empty
|
|
||||||
.bottom-tagIcon
|
|
||||||
.bottom-tagList-item
|
|
||||||
.bottom-tagList-empty
|
|
||||||
.bottom-time
|
|
||||||
color white
|
|
||||||
.bottom-tagList-item
|
|
||||||
color white
|
|
||||||
background-color transparent
|
|
||||||
|
|
||||||
.border
|
|
||||||
absolute top bottom left right
|
|
||||||
border-style solid
|
|
||||||
border-width 2px
|
|
||||||
border-color transparent
|
|
||||||
transition 0.15s
|
|
||||||
|
|
||||||
.info
|
|
||||||
height 20px
|
|
||||||
clearfix()
|
|
||||||
font-size 12px
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
line-height 20px
|
|
||||||
overflow-y hidden
|
|
||||||
|
|
||||||
.info-left
|
|
||||||
float left
|
|
||||||
overflow ellipsis
|
|
||||||
|
|
||||||
.info-left-folder
|
|
||||||
border-left 4px solid transparent
|
|
||||||
padding 2px 5px
|
|
||||||
color $ui-text-color
|
|
||||||
.info-left-folder-surfix
|
|
||||||
font-size 10px
|
|
||||||
margin-left 5px
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
.info-right
|
|
||||||
float right
|
|
||||||
|
|
||||||
.title
|
|
||||||
height 24px
|
|
||||||
box-sizing border-box
|
|
||||||
line-height 24px
|
|
||||||
height 20px
|
|
||||||
line-height 20px
|
|
||||||
padding 0 5px 0 0
|
|
||||||
overflow ellipsis
|
|
||||||
color $ui-text-color
|
|
||||||
|
|
||||||
.title-icon
|
|
||||||
font-size 12px
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
padding-right 3px
|
|
||||||
|
|
||||||
.title-empty
|
|
||||||
font-weight normal
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
|
|
||||||
.bottom
|
|
||||||
margin-top 2px
|
|
||||||
height 20px
|
|
||||||
font-size 12px
|
|
||||||
line-height 20px
|
|
||||||
overflow ellipsis
|
|
||||||
display flex
|
|
||||||
|
|
||||||
.bottom-tagIcon
|
|
||||||
vertical-align middle
|
|
||||||
color $ui-button-color
|
|
||||||
height 20px
|
|
||||||
line-height 20px
|
|
||||||
|
|
||||||
.bottom-tagList
|
|
||||||
flex 1
|
|
||||||
overflow ellipsis
|
|
||||||
line-height 20px
|
|
||||||
|
|
||||||
.bottom-tagList-item
|
|
||||||
margin 0 4px
|
|
||||||
padding 0 4px
|
|
||||||
height 20px
|
|
||||||
box-sizing border-box
|
|
||||||
border-radius 3px
|
|
||||||
vertical-align middle
|
|
||||||
border-style solid
|
|
||||||
border-color $ui-button--focus-borderColor
|
|
||||||
border-width 0 0 0 3px
|
|
||||||
background-color $ui-backgroundColor
|
|
||||||
color $ui-text-color
|
|
||||||
transition 0.15s
|
|
||||||
|
|
||||||
.bottom-tagList-empty
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
vertical-align middle
|
|
||||||
font-size 10px
|
|
||||||
margin-left 5px
|
|
||||||
|
|
||||||
.bottom-time
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
margin-left 5px
|
|
||||||
font-size 10px
|
|
||||||
|
|
||||||
body[data-theme="dark"]
|
|
||||||
.root
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
|
|
||||||
.root--active
|
|
||||||
@extend .root
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
&:hover
|
|
||||||
background-color $ui-active-color
|
|
||||||
.info-left-folder
|
|
||||||
.info-left-folder-surfix
|
|
||||||
.title
|
|
||||||
.title-icon
|
|
||||||
.title-empty
|
|
||||||
.bottom-tagIcon
|
|
||||||
.bottom-tagList-item
|
|
||||||
.bottom-tagList-empty
|
|
||||||
.bottom-time
|
|
||||||
color white
|
|
||||||
.bottom-tagList-item
|
|
||||||
color white
|
|
||||||
background-color transparent
|
|
||||||
|
|
||||||
.info
|
|
||||||
color $ui-dark-inactive-text-color
|
|
||||||
|
|
||||||
.info-left-folder
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.info-left-folder-surfix
|
|
||||||
color $ui-dark-inactive-text-color
|
|
||||||
|
|
||||||
.title
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.title-icon
|
|
||||||
color $ui-dark-inactive-text-color
|
|
||||||
|
|
||||||
.title-empty
|
|
||||||
color $ui-dark-inactive-text-color
|
|
||||||
|
|
||||||
.tagList-empty
|
|
||||||
color $ui-dark-inactive-text-color
|
|
||||||
|
|
||||||
.bottom-tagIcon
|
|
||||||
color $ui-dark-button-color
|
|
||||||
|
|
||||||
.bottom-tagList-item
|
|
||||||
color $ui-dark-text-color
|
|
||||||
background-color $ui-dark-backgroundColor
|
|
||||||
|
|
||||||
.bottom-tagList-empty
|
|
||||||
color $ui-dark-inactive-text-color
|
|
||||||
|
|
||||||
.bottom-time
|
|
||||||
color $ui-dark-inactive-text-color
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React from 'react'
|
||||||
import NoteItem from './NoteItem'
|
import NoteItem from 'browser/components/NoteItem'
|
||||||
import _ from 'lodash'
|
import moment from 'moment'
|
||||||
|
|
||||||
class NoteList extends React.Component {
|
class NoteList extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -54,21 +54,23 @@ class NoteList extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
let { storageMap, notes, index } = this.props
|
let { notes, index } = this.props
|
||||||
|
|
||||||
let notesList = notes
|
let notesList = notes
|
||||||
.slice(0, 10 + 10 * this.state.range)
|
.slice(0, 10 + 10 * this.state.range)
|
||||||
.map((note, _index) => {
|
.map((note, _index) => {
|
||||||
let storage = storageMap[note.storage]
|
const isActive = (index === _index)
|
||||||
let folder = _.find(storage.folders, {key: note.folder})
|
const key = `${note.storage}-${note.key}`
|
||||||
|
const dateDisplay = moment(note.updatedAt).fromNow()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NoteItem
|
<NoteItem
|
||||||
|
isActive={isActive}
|
||||||
note={note}
|
note={note}
|
||||||
key={`${note.storage}-${note.key}`}
|
dateDisplay={dateDisplay}
|
||||||
storage={storage}
|
key={key}
|
||||||
folder={folder}
|
handleNoteClick={(e) => this.props.handleNoteClick(e, _index)}
|
||||||
isActive={index === _index}
|
handleNoteContextMenu={() => ''}
|
||||||
onClick={(e) => this.props.handleNoteClick(e, _index)}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './StorageSection.styl'
|
import styles from './StorageSection.styl'
|
||||||
|
import StorageItem from 'browser/components/StorageItem'
|
||||||
|
|
||||||
class StorageSection extends React.Component {
|
class StorageSection extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -30,20 +31,17 @@ class StorageSection extends React.Component {
|
|||||||
render () {
|
render () {
|
||||||
let { storage, filter } = this.props
|
let { storage, filter } = this.props
|
||||||
let folderList = storage.folders
|
let folderList = storage.folders
|
||||||
.map((folder) => {
|
.map(folder => (
|
||||||
return (
|
<StorageItem
|
||||||
<button styleName={filter.type === 'FOLDER' && filter.folder === folder.key && filter.storage === storage.key
|
key={folder.key}
|
||||||
? 'folderList-item--active'
|
isActive={filter.type === 'FOLDER' && filter.folder === folder.key && filter.storage === storage.key}
|
||||||
: 'folderList-item'
|
handleButtonClick={(e) => this.handleFolderClick(e, folder)}
|
||||||
}
|
folderName={folder.name}
|
||||||
style={{borderColor: folder.color}}
|
folderColor={folder.color}
|
||||||
key={folder.key}
|
isFolded={false}
|
||||||
onClick={(e) => this.handleFolderClick(e, folder)}
|
/>
|
||||||
>
|
))
|
||||||
{folder.name}
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
return (
|
return (
|
||||||
<div styleName='root'>
|
<div styleName='root'>
|
||||||
<div styleName='header'>
|
<div styleName='header'>
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import React, { PropTypes } from 'react'
|
|||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import { connect, Provider } from 'react-redux'
|
import { connect, Provider } from 'react-redux'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import ipc from './ipcClient'
|
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './FinderMain.styl'
|
import styles from './FinderMain.styl'
|
||||||
import StorageSection from './StorageSection'
|
import StorageSection from './StorageSection'
|
||||||
import NoteList from './NoteList'
|
import NoteList from './NoteList'
|
||||||
import NoteDetail from './NoteDetail'
|
import NoteDetail from './NoteDetail'
|
||||||
|
import SideNavFilter from 'browser/components/SideNavFilter'
|
||||||
require('!!style!css!stylus?sourceMap!../main/global.styl')
|
require('!!style!css!stylus?sourceMap!../main/global.styl')
|
||||||
require('../lib/customMeta')
|
require('../lib/customMeta')
|
||||||
|
|
||||||
@@ -307,18 +307,12 @@ class FinderMain extends React.Component {
|
|||||||
/> Only Markdown</label>
|
/> Only Markdown</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button styleName={filter.type === 'ALL'
|
<SideNavFilter
|
||||||
? 'result-nav-menu--active'
|
isHomeActive={filter.type === 'ALL'}
|
||||||
: 'result-nav-menu'
|
handleAllNotesButtonClick={(e) => this.handleAllNotesButtonClick(e)}
|
||||||
}
|
isStarredActive={filter.type === 'STARRED'}
|
||||||
onClick={(e) => this.handleAllNotesButtonClick(e)}
|
handleStarredButtonClick={(e) => this.handleStarredButtonClick(e)}
|
||||||
><i className='fa fa-files-o fa-fw'/> All Notes</button>
|
/>
|
||||||
<button styleName={filter.type === 'STARRED'
|
|
||||||
? 'result-nav-menu--active'
|
|
||||||
: 'result-nav-menu'
|
|
||||||
}
|
|
||||||
onClick={(e) => this.handleStarredButtonClick(e)}
|
|
||||||
><i className='fa fa-star fa-fw'/> Starred</button>
|
|
||||||
<div styleName='result-nav-storageList'>
|
<div styleName='result-nav-storageList'>
|
||||||
{storageList}
|
{storageList}
|
||||||
</div>
|
</div>
|
||||||
@@ -356,7 +350,7 @@ function refreshData () {
|
|||||||
|
|
||||||
ReactDOM.render((
|
ReactDOM.render((
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<Finder/>
|
<Finder />
|
||||||
</Provider>
|
</Provider>
|
||||||
), document.getElementById('content'), function () {
|
), document.getElementById('content'), function () {
|
||||||
refreshData()
|
refreshData()
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
import superagent from 'superagent'
|
|
||||||
import superagentPromise from 'superagent-promise'
|
|
||||||
|
|
||||||
export const SERVER_URL = 'https://b00st.io/'
|
|
||||||
// export const SERVER_URL = 'http://localhost:3333/'
|
|
||||||
|
|
||||||
export const request = superagentPromise(superagent, Promise)
|
|
||||||
|
|
||||||
export function shareViaPublicURL (input) {
|
|
||||||
return request
|
|
||||||
.post(SERVER_URL + 'apis/share')
|
|
||||||
// .set({
|
|
||||||
// Authorization: 'Bearer ' + auth.token()
|
|
||||||
// })
|
|
||||||
.send(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
SERVER_URL,
|
|
||||||
shareViaPublicURL
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import CodeMirror from 'codemirror'
|
import CodeMirror from 'codemirror'
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
CodeMirror.modeInfo.push({name: 'Stylus', mime: 'text/x-styl', mode: 'stylus', ext: ['styl']})
|
CodeMirror.modeInfo.push({name: 'Stylus', mime: 'text/x-styl', mode: 'stylus', ext: ['styl'], alias: ['styl']})
|
||||||
|
|||||||
18
browser/lib/date-formatter.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview Formatting date string.
|
||||||
|
*/
|
||||||
|
import moment from 'moment'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Return date string. For example, 'Sep.9, 2016 12:00'.
|
||||||
|
* @param {mixed}
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
export function getLastUpdated (date) {
|
||||||
|
const m = moment(date)
|
||||||
|
if (!m.isValid()) {
|
||||||
|
throw Error('Invalid argument.')
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.format('MMM D, gggg H:mm')
|
||||||
|
}
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
const hljsThemeList = [
|
|
||||||
{caption: 'Default', name: 'default'},
|
|
||||||
{caption: 'Agate', name: 'agate'},
|
|
||||||
{caption: 'Androidstudio', name: 'androidstudio'},
|
|
||||||
{caption: 'Arduino Light', name: 'arduino-light'},
|
|
||||||
{caption: 'Arta', name: 'arta'},
|
|
||||||
{caption: 'Ascetic', name: 'ascetic'},
|
|
||||||
{caption: 'Atelier Cave Dark', name: 'atelier-cave-dark'},
|
|
||||||
{caption: 'Atelier Cave Light', name: 'atelier-cave-light'},
|
|
||||||
{caption: 'Atelier Dune Dark', name: 'atelier-dune-dark'},
|
|
||||||
{caption: 'Atelier Dune Light', name: 'atelier-dune-light'},
|
|
||||||
{caption: 'Atelier Estuary Dark', name: 'atelier-estuary-dark'},
|
|
||||||
{caption: 'Atelier Estuary Light', name: 'atelier-estuary-light'},
|
|
||||||
{caption: 'Atelier Forest Dark', name: 'atelier-forest-dark'},
|
|
||||||
{caption: 'Atelier Forest Light', name: 'atelier-forest-light'},
|
|
||||||
{caption: 'Atelier Heath Dark', name: 'atelier-heath-dark'},
|
|
||||||
{caption: 'Atelier Heath Light', name: 'atelier-heath-light'},
|
|
||||||
{caption: 'Atelier Lakeside Dark', name: 'atelier-lakeside-dark'},
|
|
||||||
{caption: 'Atelier Lakeside Light', name: 'atelier-lakeside-light'},
|
|
||||||
{caption: 'Atelier Plateau Dark', name: 'atelier-plateau-dark'},
|
|
||||||
{caption: 'Atelier Plateau Light', name: 'atelier-plateau-light'},
|
|
||||||
{caption: 'Atelier Savanna Dark', name: 'atelier-savanna-dark'},
|
|
||||||
{caption: 'Atelier Savanna Light', name: 'atelier-savanna-light'},
|
|
||||||
{caption: 'Atelier Seaside Dark', name: 'atelier-seaside-dark'},
|
|
||||||
{caption: 'Atelier Seaside Light', name: 'atelier-seaside-light'},
|
|
||||||
{caption: 'Atelier Sulphurpool Dark', name: 'atelier-sulphurpool-dark'},
|
|
||||||
{caption: 'Atelier Sulphurpool Light', name: 'atelier-sulphurpool-light'},
|
|
||||||
{caption: 'Brown Paper', name: 'brown-paper'},
|
|
||||||
{caption: 'Codepen Embed', name: 'codepen-embed'},
|
|
||||||
{caption: 'Color Brewer', name: 'color-brewer'},
|
|
||||||
{caption: 'Dark', name: 'dark'},
|
|
||||||
{caption: 'Darkula', name: 'darkula'},
|
|
||||||
{caption: 'Docco', name: 'docco'},
|
|
||||||
{caption: 'Dracula', name: 'dracula'},
|
|
||||||
{caption: 'Far', name: 'far'},
|
|
||||||
{caption: 'Foundation', name: 'foundation'},
|
|
||||||
{caption: 'Github Gist', name: 'github-gist'},
|
|
||||||
{caption: 'Github', name: 'github'},
|
|
||||||
{caption: 'Googlecode', name: 'googlecode'},
|
|
||||||
{caption: 'Grayscale', name: 'grayscale'},
|
|
||||||
{caption: 'Gruvbox Dark', name: 'gruvbox.dark'},
|
|
||||||
{caption: 'Gruvbox Light', name: 'gruvbox.light'},
|
|
||||||
{caption: 'Hopscotch', name: 'hopscotch'},
|
|
||||||
{caption: 'Hybrid', name: 'hybrid'},
|
|
||||||
{caption: 'Idea', name: 'idea'},
|
|
||||||
{caption: 'Ir Black', name: 'ir-black'},
|
|
||||||
{caption: 'Kimbie Dark', name: 'kimbie.dark'},
|
|
||||||
{caption: 'Kimbie Light', name: 'kimbie.light'},
|
|
||||||
{caption: 'Magula', name: 'magula'},
|
|
||||||
{caption: 'Mono Blue', name: 'mono-blue'},
|
|
||||||
{caption: 'Monokai Sublime', name: 'monokai-sublime'},
|
|
||||||
{caption: 'Monokai', name: 'monokai'},
|
|
||||||
{caption: 'Obsidian', name: 'obsidian'},
|
|
||||||
{caption: 'Paraiso Dark', name: 'paraiso-dark'},
|
|
||||||
{caption: 'Paraiso Light', name: 'paraiso-light'},
|
|
||||||
{caption: 'Pojoaque', name: 'pojoaque'},
|
|
||||||
{caption: 'Qtcreator Dark', name: 'qtcreator_dark'},
|
|
||||||
{caption: 'Qtcreator Light', name: 'qtcreator_light'},
|
|
||||||
{caption: 'Railscasts', name: 'railscasts'},
|
|
||||||
{caption: 'Rainbow', name: 'rainbow'},
|
|
||||||
{caption: 'School Book', name: 'school-book'},
|
|
||||||
{caption: 'Solarized Dark', name: 'solarized-dark'},
|
|
||||||
{caption: 'Solarized Light', name: 'solarized-light'},
|
|
||||||
{caption: 'Sunburst', name: 'sunburst'},
|
|
||||||
{caption: 'Tomorrow Night Blue', name: 'tomorrow-night-blue'},
|
|
||||||
{caption: 'Tomorrow Night Bright', name: 'tomorrow-night-bright'},
|
|
||||||
{caption: 'Tomorrow Night Eighties', name: 'tomorrow-night-eighties'},
|
|
||||||
{caption: 'Tomorrow Night', name: 'tomorrow-night'},
|
|
||||||
{caption: 'Tomorrow', name: 'tomorrow'},
|
|
||||||
{caption: 'Vs', name: 'vs'},
|
|
||||||
{caption: 'Xcode', name: 'xcode'},
|
|
||||||
{caption: 'Xt 256', name: 'xt256'},
|
|
||||||
{caption: 'Zenburn', name: 'zenburn'}
|
|
||||||
]
|
|
||||||
|
|
||||||
export default function hljsTheme () {
|
|
||||||
return hljsThemeList
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import markdownit from 'markdown-it'
|
import markdownit from 'markdown-it'
|
||||||
import emoji from 'markdown-it-emoji'
|
import emoji from 'markdown-it-emoji'
|
||||||
import math from '@rokt33r/markdown-it-math'
|
import math from '@rokt33r/markdown-it-math'
|
||||||
import hljs from 'highlight.js'
|
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
const katex = window.katex
|
const katex = window.katex
|
||||||
@@ -10,9 +9,9 @@ function createGutter (str) {
|
|||||||
let lc = (str.match(/\n/g) || []).length
|
let lc = (str.match(/\n/g) || []).length
|
||||||
let lines = []
|
let lines = []
|
||||||
for (let i = 1; i <= lc; i++) {
|
for (let i = 1; i <= lc; i++) {
|
||||||
lines.push('<span>' + i + '</span>')
|
lines.push('<span class="CodeMirror-linenumber">' + i + '</span>')
|
||||||
}
|
}
|
||||||
return '<span class="lineNumber">' + lines.join('') + '</span>'
|
return '<span class="lineNumber CodeMirror-gutters">' + lines.join('') + '</span>'
|
||||||
}
|
}
|
||||||
|
|
||||||
var md = markdownit({
|
var md = markdownit({
|
||||||
@@ -21,19 +20,16 @@ var md = markdownit({
|
|||||||
html: true,
|
html: true,
|
||||||
xhtmlOut: true,
|
xhtmlOut: true,
|
||||||
highlight: function (str, lang) {
|
highlight: function (str, lang) {
|
||||||
if (lang && hljs.getLanguage(lang)) {
|
if (lang === 'flowchart') {
|
||||||
try {
|
return `<pre class="flowchart">${str}</pre>`
|
||||||
return '<pre class="hljs">' +
|
|
||||||
createGutter(str) +
|
|
||||||
'<code>' +
|
|
||||||
hljs.highlight(lang, str).value +
|
|
||||||
'</code></pre>'
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
}
|
||||||
return '<pre class="hljs">' +
|
if (lang === 'sequence') {
|
||||||
|
return `<pre class="sequence">${str}</pre>`
|
||||||
|
}
|
||||||
|
return '<pre class="code">' +
|
||||||
createGutter(str) +
|
createGutter(str) +
|
||||||
'<code>' +
|
'<code class="' + lang + '">' +
|
||||||
str.replace(/\&/g, '&').replace(/\</g, '<').replace(/\>/g, '>').replace(/\"/g, '"') +
|
str +
|
||||||
'</code></pre>'
|
'</code></pre>'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -62,7 +58,7 @@ md.use(math, {
|
|||||||
})
|
})
|
||||||
md.use(require('markdown-it-footnote'))
|
md.use(require('markdown-it-footnote'))
|
||||||
// Override task item
|
// Override task item
|
||||||
md.block.ruler.at('paragraph', function (state, startLine/*, endLine*/) {
|
md.block.ruler.at('paragraph', function (state, startLine/*, endLine */) {
|
||||||
let content, terminate, i, l, token
|
let content, terminate, i, l, token
|
||||||
let nextLine = startLine + 1
|
let nextLine = startLine + 1
|
||||||
let terminatorRules = state.md.block.ruler.getRules('paragraph')
|
let terminatorRules = state.md.block.ruler.getRules('paragraph')
|
||||||
@@ -139,13 +135,13 @@ function strip (input) {
|
|||||||
.replace(/`{3}.*\n/g, '')
|
.replace(/`{3}.*\n/g, '')
|
||||||
.replace(/<(.*?)>/g, '$1')
|
.replace(/<(.*?)>/g, '$1')
|
||||||
.replace(/^[=\-]{2,}\s*$/g, '')
|
.replace(/^[=\-]{2,}\s*$/g, '')
|
||||||
.replace(/\[\^.+?\](\: .*?$)?/g, '')
|
.replace(/\[\^.+?\](: .*?$)?/g, '')
|
||||||
.replace(/\s{0,2}\[.*?\]: .*?$/g, '')
|
.replace(/\s{0,2}\[.*?\]: .*?$/g, '')
|
||||||
.replace(/\!\[.*?\][\[\(].*?[\]\)]/g, '')
|
.replace(/!\[.*?\][\[\(].*?[\]\)]/g, '')
|
||||||
.replace(/\[(.*?)\][\[\(].*?[\]\)]/g, '$1')
|
.replace(/\[(.*?)\][\[\(].*?[\]\)]/g, '$1')
|
||||||
.replace(/>/g, '')
|
.replace(/>/g, '')
|
||||||
.replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g, '')
|
.replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g, '')
|
||||||
.replace(/^\#{1,6}\s*([^#]*)\s*(\#{1,6})?/gm, '$1')
|
.replace(/^#{1,6}\s*([^#]*)\s*(#{1,6})?/gm, '$1')
|
||||||
.replace(/([\*_]{1,3})(\S.*?\S)\1/g, '$2')
|
.replace(/([\*_]{1,3})(\S.*?\S)\1/g, '$2')
|
||||||
.replace(/(`{3,})(.*?)\1/gm, '$2')
|
.replace(/(`{3,})(.*?)\1/gm, '$2')
|
||||||
.replace(/^-{3,}\s*$/g, '')
|
.replace(/^-{3,}\s*$/g, '')
|
||||||
|
|||||||
9
browser/main/Detail/DetailVars.styl
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Varibales for note detail space.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Margin on the left side and the right side for NoteDetail component.
|
||||||
|
$note-detail-left-margin = 25px
|
||||||
|
$note-detail-right-margin = 25px
|
||||||
|
|
||||||
|
$note-detail-box-shadow = 2px 0 15px -8px #b1b1b1 inset
|
||||||
@@ -128,8 +128,8 @@ class FolderSelect extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nextOption () {
|
nextOption () {
|
||||||
let { storages } = this.props
|
|
||||||
let { optionIndex } = this.state
|
let { optionIndex } = this.state
|
||||||
|
let { folders } = this.props
|
||||||
|
|
||||||
optionIndex++
|
optionIndex++
|
||||||
if (optionIndex >= folders.length) optionIndex = 0
|
if (optionIndex >= folders.length) optionIndex = 0
|
||||||
@@ -262,13 +262,11 @@ class FolderSelect extends React.Component {
|
|||||||
: <div styleName='idle'>
|
: <div styleName='idle'>
|
||||||
<div styleName='idle-label'>
|
<div styleName='idle-label'>
|
||||||
<span styleName='idle-label-name'
|
<span styleName='idle-label-name'
|
||||||
style={{borderColor: currentOption.folder.color}}
|
style={{color: currentOption.folder.color}}
|
||||||
>
|
>
|
||||||
{currentOption.folder.name}
|
{currentOption.folder.name} /
|
||||||
<span styleName='idle-label-name-surfix'>in {currentOption.storage.name}</span>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<i styleName='idle-caret' className='fa fa-fw fa-caret-down'/>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,29 +7,28 @@
|
|||||||
transition 0.15s
|
transition 0.15s
|
||||||
user-select none
|
user-select none
|
||||||
&:hover
|
&:hover
|
||||||
background-color white
|
background-color $ui-button--hover-backgroundColor
|
||||||
border-color $ui-borderColor
|
|
||||||
|
|
||||||
.root--search, .root--focus
|
.root--search, .root--focus
|
||||||
@extend .root
|
@extend .root
|
||||||
background-color white
|
background-color $ui-noteDetail-backgroundColor = #F4F4F4
|
||||||
border-color $ui-input--focus-borderColor
|
border-color $ui-input--focus-borderColor
|
||||||
|
width 100px
|
||||||
&:hover
|
&:hover
|
||||||
background-color white
|
|
||||||
border-color $ui-input--focus-borderColor
|
border-color $ui-input--focus-borderColor
|
||||||
|
|
||||||
.idle
|
.idle
|
||||||
position relative
|
position relative
|
||||||
cursor pointer
|
cursor pointer
|
||||||
|
|
||||||
.idle-label
|
.idle-label
|
||||||
absolute left top
|
|
||||||
padding 0 0 0 5px
|
|
||||||
right 20px
|
right 20px
|
||||||
overflow ellipsis
|
overflow ellipsis
|
||||||
|
|
||||||
.idle-label-name
|
.idle-label-name
|
||||||
border-left solid 4px transparent
|
font-size 16px
|
||||||
padding 2px 5px
|
padding 2px
|
||||||
|
|
||||||
.idle-label-name-surfix
|
.idle-label-name-surfix
|
||||||
font-size 10px
|
font-size 10px
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
@@ -60,9 +59,9 @@
|
|||||||
max-height 450px
|
max-height 450px
|
||||||
overflow auto
|
overflow auto
|
||||||
z-index 200
|
z-index 200
|
||||||
|
border $ui-border
|
||||||
background-color white
|
background-color white
|
||||||
border-radius 2px
|
border-radius 2px
|
||||||
box-shadow 2px 2px 10px gray
|
|
||||||
|
|
||||||
.search-optionList-item
|
.search-optionList-item
|
||||||
height 34px
|
height 34px
|
||||||
@@ -115,8 +114,8 @@ body[data-theme="dark"]
|
|||||||
|
|
||||||
.search-optionList
|
.search-optionList
|
||||||
color white
|
color white
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color $ui-dark-button--hover-backgroundColor
|
||||||
box-shadow 2px 2px 10px black
|
|
||||||
|
|
||||||
.search-optionList-item
|
.search-optionList-item
|
||||||
&:hover
|
&:hover
|
||||||
|
|||||||
27
browser/main/Detail/LastUpdatedString.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview Component for show updated date of the detail.
|
||||||
|
*/
|
||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import { getLastUpdated } from 'browser/lib/date-formatter'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './LastUpdatedString.styl'
|
||||||
|
|
||||||
|
const LastUpdatedString = ({ date }) => {
|
||||||
|
let text = ''
|
||||||
|
|
||||||
|
try {
|
||||||
|
text = `Last updated at ${getLastUpdated(date)}`
|
||||||
|
} catch (e) {
|
||||||
|
text = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<p styleName='info-right-date'>{text}</p>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
LastUpdatedString.propTypes = {
|
||||||
|
date: PropTypes.string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(LastUpdatedString, styles)
|
||||||
10
browser/main/Detail/LastUpdatedString.styl
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
.info-right-date
|
||||||
|
display inline
|
||||||
|
line-height 24px
|
||||||
|
padding-right 25px
|
||||||
|
font-size 11px
|
||||||
|
color $ui-button-color
|
||||||
|
|
||||||
|
body[data-theme="dark"]
|
||||||
|
.info-right-date
|
||||||
|
color $ui-dark-button-color
|
||||||
@@ -166,20 +166,6 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleShareButtonClick (e) {
|
|
||||||
let menu = new Menu()
|
|
||||||
menu.append(new MenuItem({
|
|
||||||
label: 'Export as a File',
|
|
||||||
click: (e) => this.handlePreferencesButtonClick(e)
|
|
||||||
}))
|
|
||||||
menu.append(new MenuItem({
|
|
||||||
label: 'Export to Web',
|
|
||||||
disabled: true,
|
|
||||||
click: (e) => this.handlePreferencesButtonClick(e)
|
|
||||||
}))
|
|
||||||
menu.popup(remote.getCurrentWindow())
|
|
||||||
}
|
|
||||||
|
|
||||||
handleContextButtonClick (e) {
|
handleContextButtonClick (e) {
|
||||||
let menu = new Menu()
|
let menu = new Menu()
|
||||||
menu.append(new MenuItem({
|
menu.append(new MenuItem({
|
||||||
@@ -229,6 +215,10 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
>
|
>
|
||||||
<div styleName='info'>
|
<div styleName='info'>
|
||||||
<div styleName='info-left'>
|
<div styleName='info-left'>
|
||||||
|
<StarButton styleName='info-left-button'
|
||||||
|
onClick={(e) => this.handleStarButtonClick(e)}
|
||||||
|
isActive={note.isStarred}
|
||||||
|
/>
|
||||||
<div styleName='info-left-top'>
|
<div styleName='info-left-top'>
|
||||||
<FolderSelect styleName='info-left-top-folderSelect'
|
<FolderSelect styleName='info-left-top-folderSelect'
|
||||||
value={this.state.note.storage + '-' + this.state.note.folder}
|
value={this.state.note.storage + '-' + this.state.note.folder}
|
||||||
@@ -237,36 +227,18 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
onChange={(e) => this.handleFolderChange(e)}
|
onChange={(e) => this.handleFolderChange(e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='info-left-bottom'>
|
|
||||||
<TagSelect
|
<TagSelect
|
||||||
styleName='info-left-bottom-tagSelect'
|
ref='tags'
|
||||||
ref='tags'
|
value={this.state.note.tags}
|
||||||
value={this.state.note.tags}
|
onChange={(e) => this.handleChange(e)}
|
||||||
onChange={(e) => this.handleChange(e)}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div styleName='info-right'>
|
<div styleName='info-right'>
|
||||||
<StarButton styleName='info-right-button'
|
|
||||||
onClick={(e) => this.handleStarButtonClick(e)}
|
|
||||||
isActive={note.isStarred}
|
|
||||||
/>
|
|
||||||
<button styleName='info-right-button'
|
|
||||||
onClick={(e) => this.handleShareButtonClick(e)}
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
<i className='fa fa-share-alt fa-fw' />
|
|
||||||
<span styleName='info-right-button-tooltip'
|
|
||||||
style={{right: 20}}
|
|
||||||
>Share Note</span>
|
|
||||||
</button>
|
|
||||||
<button styleName='info-right-button'
|
<button styleName='info-right-button'
|
||||||
onClick={(e) => this.handleContextButtonClick(e)}
|
onClick={(e) => this.handleContextButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-ellipsis-v' />
|
<i className='fa fa-ellipsis-v' />
|
||||||
<span styleName='info-right-button-tooltip'
|
|
||||||
style={{right: 5}}
|
|
||||||
>More Options</span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -284,6 +256,7 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
|
|
||||||
<StatusBar
|
<StatusBar
|
||||||
{..._.pick(this.props, ['config', 'location', 'dispatch'])}
|
{..._.pick(this.props, ['config', 'location', 'dispatch'])}
|
||||||
|
date={note.updatedAt}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,68 +1,19 @@
|
|||||||
$info-height = 75px
|
@import('NoteDetailInfo')
|
||||||
|
@import('DetailVars')
|
||||||
|
|
||||||
.root
|
.root
|
||||||
absolute top right bottom
|
absolute top right bottom
|
||||||
border-width 0 0 1px
|
border-width 0 0 1px
|
||||||
border-style solid
|
border-style solid
|
||||||
border-color $ui-borderColor
|
border-color $ui-borderColor
|
||||||
|
background-color $ui-noteDetail-backgroundColor
|
||||||
.info
|
box-shadow $note-detail-box-shadow
|
||||||
absolute top left right
|
|
||||||
height $info-height
|
|
||||||
border-bottom $ui-border
|
|
||||||
background-color $ui-backgroundColor
|
|
||||||
|
|
||||||
.info-left
|
|
||||||
float left
|
|
||||||
padding 0 5px
|
|
||||||
|
|
||||||
.info-left-top
|
|
||||||
height 40px
|
|
||||||
line-height 40px
|
|
||||||
|
|
||||||
.info-left-top-folderSelect
|
|
||||||
display inline-block
|
|
||||||
height 34px
|
|
||||||
width 200px
|
|
||||||
vertical-align middle
|
|
||||||
|
|
||||||
.info-left-bottom
|
|
||||||
height 30px
|
|
||||||
|
|
||||||
.info-left-bottom-tagSelect
|
|
||||||
height 30px
|
|
||||||
line-height 30px
|
|
||||||
|
|
||||||
.info-right
|
|
||||||
float right
|
|
||||||
|
|
||||||
.info-right-button
|
|
||||||
width 34px
|
|
||||||
height 34px
|
|
||||||
border-radius 17px
|
|
||||||
navButtonColor()
|
|
||||||
border $ui-border
|
|
||||||
font-size 14px
|
|
||||||
margin 8px 2px
|
|
||||||
padding 0
|
|
||||||
&:active
|
|
||||||
border-color $ui-button--focus-borderColor
|
|
||||||
&:hover .info-right-button-tooltip
|
|
||||||
opacity 1
|
|
||||||
&:focus
|
|
||||||
border-color $ui-button--focus-borderColor
|
|
||||||
|
|
||||||
.info-right-button-tooltip
|
|
||||||
tooltip()
|
|
||||||
position fixed
|
|
||||||
top 45px
|
|
||||||
padding 5px
|
|
||||||
opacity 0
|
|
||||||
border-radius 2px
|
|
||||||
|
|
||||||
.body
|
.body
|
||||||
absolute left right
|
absolute left right
|
||||||
top $info-height
|
left $note-detail-left-margin
|
||||||
|
right $note-detail-right-margin
|
||||||
|
top $info-height + $info-margin-under-border
|
||||||
bottom $statusBar-height
|
bottom $statusBar-height
|
||||||
|
|
||||||
.body-noteEditor
|
.body-noteEditor
|
||||||
@@ -71,32 +22,5 @@ $info-height = 75px
|
|||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.root
|
.root
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
.info
|
box-shadow none
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
background-color $ui-dark-backgroundColor
|
|
||||||
|
|
||||||
.info-delete
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.info-delete-confirmButton
|
|
||||||
colorDarkDangerButton()
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.info-delete-cancelButton
|
|
||||||
colorDarkDefaultButton()
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.info-right-button
|
|
||||||
navDarkButtonColor()
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
&:active
|
|
||||||
border-color $ui-dark-button--focus-borderColor
|
|
||||||
&:hover .info-right-button-tooltip
|
|
||||||
opacity 1
|
|
||||||
&:focus
|
|
||||||
border-color $ui-button--focus-borderColor
|
|
||||||
|
|
||||||
.info-right-button-tooltip
|
|
||||||
darkTooltip()
|
|
||||||
|
|||||||
98
browser/main/Detail/NoteDetailInfo.styl
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
@import('DetailVars')
|
||||||
|
|
||||||
|
$info-height = 60px
|
||||||
|
$info-margin-under-border = 27px
|
||||||
|
|
||||||
|
.info
|
||||||
|
absolute top left right
|
||||||
|
left $note-detail-left-margin
|
||||||
|
right $note-detail-right-margin
|
||||||
|
height $info-height
|
||||||
|
border-bottom $ui-border
|
||||||
|
background-color $ui-noteDetail-backgroundColor
|
||||||
|
|
||||||
|
.info-left
|
||||||
|
float left
|
||||||
|
padding 0 5px
|
||||||
|
margin 0px 2px
|
||||||
|
|
||||||
|
.info-left-top
|
||||||
|
display inline-block
|
||||||
|
height $info-height
|
||||||
|
line-height $info-height
|
||||||
|
|
||||||
|
.info-left-top-folderSelect
|
||||||
|
display inline-block
|
||||||
|
padding 0 3px
|
||||||
|
height 34px
|
||||||
|
line-height 34px
|
||||||
|
vertical-align middle
|
||||||
|
border-radius 3px
|
||||||
|
|
||||||
|
.info-left-button
|
||||||
|
width 34px
|
||||||
|
height 34px
|
||||||
|
navButtonColor()
|
||||||
|
color $ui-favorite-star-button-color
|
||||||
|
font-size 14px
|
||||||
|
margin 13px 2px
|
||||||
|
padding 0
|
||||||
|
border-radius 17px
|
||||||
|
&:hover .info-right-button-tooltip
|
||||||
|
opacity 1
|
||||||
|
&:focus
|
||||||
|
border-color $ui-favorite-star-button-color
|
||||||
|
&:active, &:active:hover
|
||||||
|
background-color $ui-favorite-star-button-color
|
||||||
|
color $ui-button--active-color
|
||||||
|
|
||||||
|
.info-right
|
||||||
|
position absolute
|
||||||
|
right 0
|
||||||
|
top 0
|
||||||
|
background $ui-noteDetail-backgroundColor
|
||||||
|
bottom 1px
|
||||||
|
padding-left 30px
|
||||||
|
|
||||||
|
.info-right-button
|
||||||
|
width 34px
|
||||||
|
height 34px
|
||||||
|
border-radius 17px
|
||||||
|
font-size 14px
|
||||||
|
margin 13px 7px
|
||||||
|
padding 0
|
||||||
|
border none
|
||||||
|
color $ui-button-color
|
||||||
|
background-color transparent
|
||||||
|
&:hover
|
||||||
|
opacity 1
|
||||||
|
background-color $ui-button--hover-backgroundColor
|
||||||
|
|
||||||
|
|
||||||
|
body[data-theme="dark"]
|
||||||
|
.info
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
|
|
||||||
|
.info-delete
|
||||||
|
color $ui-dark-text-color
|
||||||
|
|
||||||
|
.info-delete-confirmButton
|
||||||
|
colorDarkDangerButton()
|
||||||
|
color $ui-dark-text-color
|
||||||
|
|
||||||
|
.info-delete-cancelButton
|
||||||
|
colorDarkDefaultButton()
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
color $ui-dark-text-color
|
||||||
|
|
||||||
|
.info-right
|
||||||
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
|
|
||||||
|
.info-right-button
|
||||||
|
navDarkButtonColor()
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
&:active
|
||||||
|
border-color $ui-dark-button--focus-borderColor
|
||||||
|
&:focus
|
||||||
|
border-color $ui-button--focus-borderColor
|
||||||
@@ -10,10 +10,11 @@ import dataApi from 'browser/main/lib/dataApi'
|
|||||||
import { hashHistory } from 'react-router'
|
import { hashHistory } from 'react-router'
|
||||||
import ee from 'browser/main/lib/eventEmitter'
|
import ee from 'browser/main/lib/eventEmitter'
|
||||||
import CodeMirror from 'codemirror'
|
import CodeMirror from 'codemirror'
|
||||||
import SnippetTab from './SnippetTab'
|
import SnippetTab from 'browser/components/SnippetTab'
|
||||||
import StatusBar from '../StatusBar'
|
import StatusBar from '../StatusBar'
|
||||||
import context from 'browser/lib/context'
|
import context from 'browser/lib/context'
|
||||||
import ConfigManager from 'browser/main/lib/ConfigManager'
|
import ConfigManager from 'browser/main/lib/ConfigManager'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
function pass (name) {
|
function pass (name) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
@@ -188,21 +189,6 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleShareButtonClick (e) {
|
|
||||||
let menu = new Menu()
|
|
||||||
menu.append(new MenuItem({
|
|
||||||
label: 'Export as a File',
|
|
||||||
disabled: true,
|
|
||||||
click: (e) => this.handlePreferencesButtonClick(e)
|
|
||||||
}))
|
|
||||||
menu.append(new MenuItem({
|
|
||||||
label: 'Export to Web',
|
|
||||||
disabled: true,
|
|
||||||
click: (e) => this.handlePreferencesButtonClick(e)
|
|
||||||
}))
|
|
||||||
menu.popup(remote.getCurrentWindow())
|
|
||||||
}
|
|
||||||
|
|
||||||
handleContextButtonClick (e) {
|
handleContextButtonClick (e) {
|
||||||
context.popup([{
|
context.popup([{
|
||||||
label: 'Delete',
|
label: 'Delete',
|
||||||
@@ -507,7 +493,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
key={index}
|
key={index}
|
||||||
style={{zIndex: isActive ? 5 : 4}}
|
style={{zIndex: isActive ? 5 : 4}}
|
||||||
>
|
>
|
||||||
{snippet.mode === 'markdown'
|
{snippet.mode === 'Markdown' || snippet.mode === 'GitHub Flavored Markdown'
|
||||||
? <MarkdownEditor styleName='tabView-content'
|
? <MarkdownEditor styleName='tabView-content'
|
||||||
value={snippet.content}
|
value={snippet.content}
|
||||||
config={config}
|
config={config}
|
||||||
@@ -523,6 +509,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
fontSize={editorFontSize}
|
fontSize={editorFontSize}
|
||||||
indentType={config.editor.indentType}
|
indentType={config.editor.indentType}
|
||||||
indentSize={editorIndentSize}
|
indentSize={editorIndentSize}
|
||||||
|
keyMap={config.editor.keyMap}
|
||||||
onChange={(e) => this.handleCodeChange(index)(e)}
|
onChange={(e) => this.handleCodeChange(index)(e)}
|
||||||
ref={'code-' + index}
|
ref={'code-' + index}
|
||||||
/>
|
/>
|
||||||
@@ -538,6 +525,10 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
>
|
>
|
||||||
<div styleName='info'>
|
<div styleName='info'>
|
||||||
<div styleName='info-left'>
|
<div styleName='info-left'>
|
||||||
|
<StarButton styleName='info-left-button'
|
||||||
|
onClick={(e) => this.handleStarButtonClick(e)}
|
||||||
|
isActive={note.isStarred}
|
||||||
|
/>
|
||||||
<div styleName='info-left-top'>
|
<div styleName='info-left-top'>
|
||||||
<FolderSelect styleName='info-left-top-folderSelect'
|
<FolderSelect styleName='info-left-top-folderSelect'
|
||||||
value={this.state.note.storage + '-' + this.state.note.folder}
|
value={this.state.note.storage + '-' + this.state.note.folder}
|
||||||
@@ -546,36 +537,18 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
onChange={(e) => this.handleFolderChange(e)}
|
onChange={(e) => this.handleFolderChange(e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='info-left-bottom'>
|
|
||||||
<TagSelect
|
<TagSelect
|
||||||
styleName='info-left-bottom-tagSelect'
|
ref='tags'
|
||||||
ref='tags'
|
value={this.state.note.tags}
|
||||||
value={this.state.note.tags}
|
onChange={(e) => this.handleChange(e)}
|
||||||
onChange={(e) => this.handleChange(e)}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div styleName='info-right'>
|
<div styleName='info-right'>
|
||||||
<StarButton styleName='info-right-button'
|
|
||||||
onClick={(e) => this.handleStarButtonClick(e)}
|
|
||||||
isActive={note.isStarred}
|
|
||||||
/>
|
|
||||||
<button styleName='info-right-button'
|
|
||||||
onClick={(e) => this.handleShareButtonClick(e)}
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
<i className='fa fa-share-alt fa-fw'/>
|
|
||||||
<span styleName='info-right-button-tooltip'
|
|
||||||
style={{right: 20}}
|
|
||||||
>Share Note</span>
|
|
||||||
</button>
|
|
||||||
<button styleName='info-right-button'
|
<button styleName='info-right-button'
|
||||||
onClick={(e) => this.handleContextButtonClick(e)}
|
onClick={(e) => this.handleContextButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-ellipsis-v'/>
|
<i className='fa fa-ellipsis-v' />
|
||||||
<span styleName='info-right-button-tooltip'
|
|
||||||
style={{right: 5}}
|
|
||||||
>More Options</span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -600,7 +573,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
<button styleName='plusButton'
|
<button styleName='plusButton'
|
||||||
onClick={(e) => this.handleTabPlusButtonClick(e)}
|
onClick={(e) => this.handleTabPlusButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-plus'/>
|
<i className='fa fa-plus' />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{viewList}
|
{viewList}
|
||||||
@@ -614,24 +587,25 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
? 'Select Syntax...'
|
? 'Select Syntax...'
|
||||||
: this.state.note.snippets[this.state.snippetIndex].mode
|
: this.state.note.snippets[this.state.snippetIndex].mode
|
||||||
}
|
}
|
||||||
<i className='fa fa-caret-down'/>
|
<i className='fa fa-caret-down' />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={(e) => this.handleIndentTypeButtonClick(e)}
|
onClick={(e) => this.handleIndentTypeButtonClick(e)}
|
||||||
>
|
>
|
||||||
Indent: {config.editor.indentType}
|
Indent: {config.editor.indentType}
|
||||||
<i className='fa fa-caret-down'/>
|
<i className='fa fa-caret-down' />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={(e) => this.handleIndentSizeButtonClick(e)}
|
onClick={(e) => this.handleIndentSizeButtonClick(e)}
|
||||||
>
|
>
|
||||||
size: {config.editor.indentSize}
|
size: {config.editor.indentSize}
|
||||||
<i className='fa fa-caret-down'/>
|
<i className='fa fa-caret-down' />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<StatusBar
|
<StatusBar
|
||||||
{..._.pick(this.props, ['config', 'location', 'dispatch'])}
|
{..._.pick(this.props, ['config', 'location', 'dispatch'])}
|
||||||
|
date={note.updatedAt}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,72 +1,25 @@
|
|||||||
$info-height = 75px
|
@import('NoteDetailInfo')
|
||||||
|
@import('DetailVars')
|
||||||
|
|
||||||
.root
|
.root
|
||||||
absolute top bottom right
|
absolute top bottom right
|
||||||
border-width 0 0 1px
|
border-width 0 0 1px
|
||||||
border-style solid
|
border-style solid
|
||||||
border-color $ui-borderColor
|
border-color $ui-borderColor
|
||||||
|
background-color $ui-noteDetail-backgroundColor
|
||||||
.info
|
box-shadow $note-detail-box-shadow
|
||||||
absolute top left right
|
|
||||||
height $info-height
|
|
||||||
border-bottom $ui-border
|
|
||||||
background-color $ui-backgroundColor
|
|
||||||
|
|
||||||
.info-left
|
|
||||||
float left
|
|
||||||
padding 0 5px
|
|
||||||
|
|
||||||
.info-left-top
|
|
||||||
height 40px
|
|
||||||
line-height 40px
|
|
||||||
|
|
||||||
.info-left-top-folderSelect
|
|
||||||
display inline-block
|
|
||||||
height 34px
|
|
||||||
width 200px
|
|
||||||
vertical-align middle
|
|
||||||
|
|
||||||
.info-left-bottom
|
|
||||||
height 30px
|
|
||||||
|
|
||||||
.info-left-bottom-tagSelect
|
|
||||||
height 30px
|
|
||||||
line-height 30px
|
|
||||||
|
|
||||||
.info-right
|
|
||||||
float right
|
|
||||||
|
|
||||||
.info-right-button
|
|
||||||
width 34px
|
|
||||||
height 34px
|
|
||||||
border-radius 17px
|
|
||||||
navButtonColor()
|
|
||||||
border $ui-border
|
|
||||||
font-size 14px
|
|
||||||
margin 8px 2px
|
|
||||||
padding 0
|
|
||||||
&:active
|
|
||||||
border-color $ui-button--focus-borderColor
|
|
||||||
&:hover .info-right-button-tooltip
|
|
||||||
opacity 1
|
|
||||||
&:focus
|
|
||||||
border-color $ui-button--focus-borderColor
|
|
||||||
.info-right-button-tooltip
|
|
||||||
tooltip()
|
|
||||||
position fixed
|
|
||||||
top 45px
|
|
||||||
padding 5px
|
|
||||||
opacity 0
|
|
||||||
|
|
||||||
.body
|
.body
|
||||||
absolute left right
|
absolute left right
|
||||||
top $info-height
|
left $note-detail-left-margin
|
||||||
|
right $note-detail-right-margin
|
||||||
|
top $info-height + $info-margin-under-border
|
||||||
bottom $statusBar-height
|
bottom $statusBar-height
|
||||||
|
background-color $ui-noteDetail-backgroundColor
|
||||||
|
|
||||||
.body .description
|
.body .description
|
||||||
absolute top left right
|
absolute top left right
|
||||||
height 80px
|
height 80px
|
||||||
border-bottom $ui-border
|
|
||||||
|
|
||||||
.body .description textarea
|
.body .description textarea
|
||||||
display block
|
display block
|
||||||
@@ -76,20 +29,19 @@ $info-height = 75px
|
|||||||
border none
|
border none
|
||||||
padding 10px
|
padding 10px
|
||||||
line-height 1.6
|
line-height 1.6
|
||||||
|
background-color $ui-noteDetail-backgroundColor
|
||||||
|
|
||||||
.tabList
|
.tabList
|
||||||
absolute left right
|
absolute left right
|
||||||
top 80px
|
top 80px
|
||||||
height 30px
|
height 30px
|
||||||
border-bottom $ui-border
|
|
||||||
display flex
|
display flex
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-noteDetail-backgroundColor
|
||||||
|
|
||||||
.tabList .list
|
.tabList .list
|
||||||
flex 1
|
flex 1
|
||||||
display flex
|
display flex
|
||||||
overflow hidden
|
overflow hidden
|
||||||
border-right $ui-border
|
|
||||||
|
|
||||||
.tabList .plusButton
|
.tabList .plusButton
|
||||||
navButtonColor()
|
navButtonColor()
|
||||||
@@ -97,13 +49,14 @@ $info-height = 75px
|
|||||||
|
|
||||||
.tabView
|
.tabView
|
||||||
absolute left right bottom
|
absolute left right bottom
|
||||||
top 110px
|
top 130px
|
||||||
|
|
||||||
.tabView-content
|
.tabView-content
|
||||||
absolute top left right bottom
|
absolute top left right bottom
|
||||||
|
|
||||||
.override
|
.override
|
||||||
absolute bottom left
|
absolute bottom left
|
||||||
|
left 60px
|
||||||
height 23px
|
height 23px
|
||||||
z-index 1
|
z-index 1
|
||||||
button
|
button
|
||||||
@@ -118,47 +71,19 @@ $info-height = 75px
|
|||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.root
|
.root
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
|
box-shadow none
|
||||||
|
|
||||||
.info
|
.body
|
||||||
border-bottom-color $ui-dark-borderColor
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
background-color $ui-dark-backgroundColor
|
|
||||||
|
|
||||||
.info-delete
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.info-delete-confirmButton
|
|
||||||
colorDarkDangerButton()
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.info-delete-cancelButton
|
|
||||||
colorDarkDefaultButton()
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.info-right-button
|
|
||||||
navDarkButtonColor()
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
&:active
|
|
||||||
border-color $ui-dark-button--focus-borderColor
|
|
||||||
&:hover .info-right-button-tooltip
|
|
||||||
opacity 1
|
|
||||||
&:focus
|
|
||||||
border-color $ui-button--focus-borderColor
|
|
||||||
|
|
||||||
.info-right-button-tooltip
|
|
||||||
darkTooltip()
|
|
||||||
|
|
||||||
.body .description
|
|
||||||
border-bottom-color $ui-dark-borderColor
|
|
||||||
|
|
||||||
.body .description textarea
|
.body .description textarea
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
color white
|
color white
|
||||||
|
|
||||||
.tabList
|
.tabList
|
||||||
background-color $ui-button--active-backgroundColor
|
background-color $ui-button--active-backgroundColor
|
||||||
border-bottom-color $ui-dark-borderColor
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
background-color $ui-dark-backgroundColor
|
|
||||||
|
|
||||||
.tabList .list
|
.tabList .list
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ class StarButton extends React.Component {
|
|||||||
: 'fa fa-star-o'
|
: 'fa fa-star-o'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<span styleName='tooltip'>Star Note</span>
|
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
.root
|
.root
|
||||||
position relative
|
left 7px
|
||||||
|
top 0
|
||||||
padding 0
|
padding 0
|
||||||
&:hover
|
&:hover
|
||||||
.icon
|
.icon
|
||||||
@@ -9,19 +10,11 @@
|
|||||||
|
|
||||||
.root--active
|
.root--active
|
||||||
@extend .root
|
@extend .root
|
||||||
color $brand-color
|
color $ui-favorite-star-button-color
|
||||||
&:hover
|
&:hover
|
||||||
color $brand-color !important
|
color $ui-favorite-star-button-color
|
||||||
.icon
|
.icon
|
||||||
transform rotate(-72deg)
|
transform rotate(-72deg)
|
||||||
|
|
||||||
.icon
|
.icon
|
||||||
transition transform 0.15s
|
transition transform 0.15s
|
||||||
|
|
||||||
.tooltip
|
|
||||||
tooltip()
|
|
||||||
position fixed
|
|
||||||
top 45px
|
|
||||||
right 65px
|
|
||||||
padding 5px
|
|
||||||
opacity 0
|
|
||||||
border-radius 2px
|
|
||||||
|
|||||||
@@ -107,12 +107,12 @@ class TagSelect extends React.Component {
|
|||||||
<span styleName='tag'
|
<span styleName='tag'
|
||||||
key={tag}
|
key={tag}
|
||||||
>
|
>
|
||||||
|
<span styleName='tag-label'>{tag}</span>
|
||||||
<button styleName='tag-removeButton'
|
<button styleName='tag-removeButton'
|
||||||
onClick={(e) => this.handleTagRemoveButtonClick(tag)(e)}
|
onClick={(e) => this.handleTagRemoveButtonClick(tag)(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-times fa-fw'/>
|
<i className='fa fa-times fa-fw tag-removeButton-icon' />
|
||||||
</button>
|
</button>
|
||||||
<span styleName='tag-label'>{tag}</span>
|
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -125,10 +125,7 @@ class TagSelect extends React.Component {
|
|||||||
}
|
}
|
||||||
styleName='root'
|
styleName='root'
|
||||||
>
|
>
|
||||||
<i styleName='icon'
|
{tagList}
|
||||||
className='fa fa-tags'
|
|
||||||
/>
|
|
||||||
{tagList}
|
|
||||||
<input styleName='newTag'
|
<input styleName='newTag'
|
||||||
ref='newTag'
|
ref='newTag'
|
||||||
value={this.state.newTag}
|
value={this.state.newTag}
|
||||||
@@ -136,7 +133,6 @@ class TagSelect extends React.Component {
|
|||||||
onChange={(e) => this.handleNewTagInputChange(e)}
|
onChange={(e) => this.handleNewTagInputChange(e)}
|
||||||
onKeyDown={(e) => this.handleNewTagInputKeyDown(e)}
|
onKeyDown={(e) => this.handleNewTagInputKeyDown(e)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,47 @@
|
|||||||
.root
|
.root
|
||||||
position relative
|
|
||||||
user-select none
|
|
||||||
|
|
||||||
.icon
|
|
||||||
display inline-block
|
display inline-block
|
||||||
width 30px
|
top 19px
|
||||||
|
user-select none
|
||||||
vertical-align middle
|
vertical-align middle
|
||||||
text-align center
|
width 300px
|
||||||
color $ui-button-color
|
overflow-x scroll
|
||||||
|
white-space nowrap
|
||||||
|
|
||||||
|
.root::-webkit-scrollbar
|
||||||
|
display none
|
||||||
|
|
||||||
.tag
|
.tag
|
||||||
display inline-block
|
display inline-block
|
||||||
margin 0 2px
|
margin 0 2px
|
||||||
|
padding-left 10px
|
||||||
vertical-align middle
|
vertical-align middle
|
||||||
height 20px
|
height 20px
|
||||||
background-color white
|
background-color $ui-tag-backgroundColor
|
||||||
border-radius 3px
|
border-radius 20px
|
||||||
overflow hidden
|
overflow hidden
|
||||||
clearfix()
|
clearfix()
|
||||||
|
|
||||||
.tag-removeButton
|
.tag-removeButton
|
||||||
float left
|
float right
|
||||||
height 20px
|
height 20px
|
||||||
width 18px
|
width 18px
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 0
|
||||||
border-style solid
|
border-style solid
|
||||||
border-color $ui-button--focus-borderColor
|
border-width 0
|
||||||
border-width 0 0 0 3px
|
border-radius 20px
|
||||||
line-height 18px
|
line-height 18px
|
||||||
background-color transparent
|
background-color transparent
|
||||||
color $ui-button-color
|
color $ui-button-color
|
||||||
&:hover
|
|
||||||
background-color $ui-button--hover-backgroundColor
|
.tag-removeButton-icon
|
||||||
&:active, &:active:hover
|
width 5px
|
||||||
color $ui-button--active-color
|
padding-right 4px
|
||||||
background-color $ui-button--active-backgroundColor
|
|
||||||
border-color $ui-button--focus-borderColor
|
|
||||||
&:focus
|
|
||||||
border-color $ui-button--focus-borderColor
|
|
||||||
|
|
||||||
.tag-label
|
.tag-label
|
||||||
|
font-size 12px
|
||||||
|
font-weight bold
|
||||||
|
color: #FFFFFF
|
||||||
float left
|
float left
|
||||||
height 20px
|
height 20px
|
||||||
line-height 20px
|
line-height 20px
|
||||||
@@ -62,12 +63,27 @@
|
|||||||
&:disabled
|
&:disabled
|
||||||
background-color $ui-input--disabled-backgroundColor = #DDD
|
background-color $ui-input--disabled-backgroundColor = #DDD
|
||||||
|
|
||||||
|
.add-tag-button
|
||||||
|
display inline
|
||||||
|
margin-left 5px
|
||||||
|
width 20px
|
||||||
|
height 20px
|
||||||
|
border none
|
||||||
|
border-radius 20px
|
||||||
|
padding 0
|
||||||
|
color #FFFFFF
|
||||||
|
&:hover
|
||||||
|
background-color rgba(0, 0, 0, 0.3)
|
||||||
|
&:active, &:active:hover
|
||||||
|
background-color rgba(0, 0, 0, 0.5)
|
||||||
|
color $ui-button--active-color
|
||||||
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.icon
|
.icon
|
||||||
color $ui-dark-button-color
|
color $ui-dark-button-color
|
||||||
|
|
||||||
.tag
|
.tag
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color $ui-dark-tag-backgroundColor
|
||||||
|
|
||||||
.tag-removeButton
|
.tag-removeButton
|
||||||
border-color $ui-button--focus-borderColor
|
border-color $ui-button--focus-borderColor
|
||||||
@@ -85,3 +101,10 @@ body[data-theme="dark"]
|
|||||||
border-color $ui-input--focus-borderColor = #369DCD
|
border-color $ui-input--focus-borderColor = #369DCD
|
||||||
&:disabled
|
&:disabled
|
||||||
background-color $ui-input--disabled-backgroundColor = #DDD
|
background-color $ui-input--disabled-backgroundColor = #DDD
|
||||||
|
|
||||||
|
.add-tag-button
|
||||||
|
&:hover
|
||||||
|
background-color rgba(255, 255, 255, 0.3)
|
||||||
|
&:active, &:active:hover
|
||||||
|
background-color rgba(255, 255, 255, 0.5)
|
||||||
|
color $ui-button--active-color
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class Main extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
isRightSliderFocused: false,
|
isRightSliderFocused: false,
|
||||||
listWidth: config.listWidth,
|
listWidth: config.listWidth,
|
||||||
navWidth: config.listWidth,
|
navWidth: config.navWidth,
|
||||||
isLeftSliderFocused: false
|
isLeftSliderFocused: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,6 +85,7 @@ class Main extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleMouseUp (e) {
|
handleMouseUp (e) {
|
||||||
|
// Change width of NoteList component.
|
||||||
if (this.state.isRightSliderFocused) {
|
if (this.state.isRightSliderFocused) {
|
||||||
this.setState({
|
this.setState({
|
||||||
isRightSliderFocused: false
|
isRightSliderFocused: false
|
||||||
@@ -99,6 +100,8 @@ class Main extends React.Component {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Change width of SideNav component.
|
||||||
if (this.state.isLeftSliderFocused) {
|
if (this.state.isLeftSliderFocused) {
|
||||||
this.setState({
|
this.setState({
|
||||||
isLeftSliderFocused: false
|
isLeftSliderFocused: false
|
||||||
@@ -106,10 +109,10 @@ class Main extends React.Component {
|
|||||||
let { dispatch } = this.props
|
let { dispatch } = this.props
|
||||||
let navWidth = this.state.navWidth
|
let navWidth = this.state.navWidth
|
||||||
// TODO: ConfigManager should dispatch itself.
|
// TODO: ConfigManager should dispatch itself.
|
||||||
ConfigManager.set({listWidth: navWidth})
|
ConfigManager.set({ navWidth })
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'SET_NAV_WIDTH',
|
type: 'SET_NAV_WIDTH',
|
||||||
listWidth: navWidth
|
navWidth
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -162,11 +165,11 @@ class Main extends React.Component {
|
|||||||
/>
|
/>
|
||||||
{!config.isSideNavFolded &&
|
{!config.isSideNavFolded &&
|
||||||
<div styleName={this.state.isLeftSliderFocused ? 'slider--active' : 'slider'}
|
<div styleName={this.state.isLeftSliderFocused ? 'slider--active' : 'slider'}
|
||||||
style={{left: this.state.navWidth - 1}}
|
style={{left: this.state.navWidth}}
|
||||||
onMouseDown={(e) => this.handleLeftSlideMouseDown(e)}
|
onMouseDown={(e) => this.handleLeftSlideMouseDown(e)}
|
||||||
draggable='false'
|
draggable='false'
|
||||||
>
|
>
|
||||||
<div styleName='slider-hitbox'/>
|
<div styleName='slider-hitbox' />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div styleName={config.isSideNavFolded ? 'body--expanded' : 'body'}
|
<div styleName={config.isSideNavFolded ? 'body--expanded' : 'body'}
|
||||||
@@ -191,15 +194,15 @@ class Main extends React.Component {
|
|||||||
'location'
|
'location'
|
||||||
])}
|
])}
|
||||||
/>
|
/>
|
||||||
<div styleName={this.state.isRightSliderFocused ? 'slider--active' : 'slider'}
|
<div styleName={this.state.isRightSliderFocused ? 'slider-right--active' : 'slider-right'}
|
||||||
style={{left: this.state.listWidth}}
|
style={{left: this.state.listWidth - 1}}
|
||||||
onMouseDown={(e) => this.handleRightSlideMouseDown(e)}
|
onMouseDown={(e) => this.handleRightSlideMouseDown(e)}
|
||||||
draggable='false'
|
draggable='false'
|
||||||
>
|
>
|
||||||
<div styleName='slider-hitbox' />
|
<div styleName='slider-hitbox' />
|
||||||
</div>
|
</div>
|
||||||
<Detail
|
<Detail
|
||||||
style={{left: this.state.listWidth + 1}}
|
style={{left: this.state.listWidth}}
|
||||||
{..._.pick(this.props, [
|
{..._.pick(this.props, [
|
||||||
'dispatch',
|
'dispatch',
|
||||||
'data',
|
'data',
|
||||||
|
|||||||
@@ -11,15 +11,18 @@
|
|||||||
|
|
||||||
.slider
|
.slider
|
||||||
absolute top bottom
|
absolute top bottom
|
||||||
|
top -2px
|
||||||
|
width 0
|
||||||
|
|
||||||
|
.slider-right
|
||||||
|
@extend .slider
|
||||||
width 1px
|
width 1px
|
||||||
background-color $ui-borderColor
|
|
||||||
border-width 0
|
|
||||||
border-style solid
|
|
||||||
border-color $ui-borderColor
|
|
||||||
|
|
||||||
.slider--active
|
.slider--active
|
||||||
@extend .slider
|
@extend .slider
|
||||||
background-color $ui-button--active-backgroundColor
|
|
||||||
|
.slider-right--active
|
||||||
|
@extend .slider-right
|
||||||
|
|
||||||
.slider-hitbox
|
.slider-hitbox
|
||||||
absolute top bottom left right
|
absolute top bottom left right
|
||||||
@@ -33,9 +36,6 @@ body[data-theme="dark"]
|
|||||||
.root
|
.root
|
||||||
absolute top left bottom right
|
absolute top left bottom right
|
||||||
|
|
||||||
.slider
|
.slider-right
|
||||||
background-color $ui-dark-borderColor
|
.slider-right--active
|
||||||
border-color $ui-dark-borderColor
|
box-shadow none
|
||||||
|
|
||||||
.slider--active
|
|
||||||
background-color $ui-button--active-backgroundColor
|
|
||||||
|
|||||||
@@ -1,168 +0,0 @@
|
|||||||
import React, { PropTypes } from 'react'
|
|
||||||
import ReactDOM from 'react-dom'
|
|
||||||
import api from 'browser/lib/api'
|
|
||||||
import clientKey from 'browser/lib/clientKey'
|
|
||||||
import activityRecord from 'browser/lib/activityRecord'
|
|
||||||
const clipboard = require('electron').clipboard
|
|
||||||
|
|
||||||
function notify (...args) {
|
|
||||||
return new window.Notification(...args)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDefault () {
|
|
||||||
return {
|
|
||||||
openDropdown: false,
|
|
||||||
isSharing: false,
|
|
||||||
// Fetched url
|
|
||||||
url: null,
|
|
||||||
// for tooltip Copy -> Copied!
|
|
||||||
copied: false,
|
|
||||||
failed: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class ShareButton extends React.Component {
|
|
||||||
constructor (props) {
|
|
||||||
super(props)
|
|
||||||
this.state = getDefault()
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
|
||||||
this.setState(getDefault())
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount () {
|
|
||||||
this.dropdownInterceptor = e => {
|
|
||||||
this.dropdownClicked = true
|
|
||||||
}
|
|
||||||
ReactDOM.findDOMNode(this.refs.dropdown).addEventListener('click', this.dropdownInterceptor)
|
|
||||||
this.shareViaPublicURLHandler = e => {
|
|
||||||
this.handleShareViaPublicURLClick(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount () {
|
|
||||||
document.removeEventListener('click', this.dropdownHandler)
|
|
||||||
ReactDOM.findDOMNode(this.refs.dropdown).removeEventListener('click', this.dropdownInterceptor)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleOpenButtonClick (e) {
|
|
||||||
this.openDropdown()
|
|
||||||
if (this.dropdownHandler == null) {
|
|
||||||
this.dropdownHandler = e => {
|
|
||||||
if (!this.dropdownClicked) {
|
|
||||||
this.closeDropdown()
|
|
||||||
} else {
|
|
||||||
this.dropdownClicked = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
document.removeEventListener('click', this.dropdownHandler)
|
|
||||||
document.addEventListener('click', this.dropdownHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
openDropdown () {
|
|
||||||
this.setState({openDropdown: true})
|
|
||||||
}
|
|
||||||
|
|
||||||
closeDropdown () {
|
|
||||||
document.removeEventListener('click', this.dropdownHandler)
|
|
||||||
this.setState({openDropdown: false})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleClipboardButtonClick (e) {
|
|
||||||
activityRecord.emit('MAIN_DETAIL_COPY')
|
|
||||||
clipboard.writeText(this.props.article.content)
|
|
||||||
notify('Saved to Clipboard!', {
|
|
||||||
body: 'Paste it wherever you want!'
|
|
||||||
})
|
|
||||||
this.setState({openDropdown: false})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleShareViaPublicURLClick (e) {
|
|
||||||
let { user } = this.props
|
|
||||||
let input = Object.assign({}, this.props.article, {
|
|
||||||
clientKey: clientKey.get(),
|
|
||||||
writerName: user.name
|
|
||||||
})
|
|
||||||
this.setState({
|
|
||||||
isSharing: true,
|
|
||||||
failed: false
|
|
||||||
}, () => {
|
|
||||||
api.shareViaPublicURL(input)
|
|
||||||
.then(res => {
|
|
||||||
let url = res.body.url
|
|
||||||
this.setState({url: url, isSharing: false})
|
|
||||||
activityRecord.emit('ARTICLE_SHARE')
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
this.setState({isSharing: false, failed: true})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCopyURLClick () {
|
|
||||||
clipboard.writeText(this.state.url)
|
|
||||||
this.setState({copied: true})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore copy url tooltip
|
|
||||||
handleCopyURLMouseLeave () {
|
|
||||||
this.setState({copied: false})
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
let hasPublicURL = this.state.url != null
|
|
||||||
return (
|
|
||||||
<div className='ShareButton'>
|
|
||||||
<button ref='openButton' onClick={e => this.handleOpenButtonClick(e)} className='ShareButton-open-button'>
|
|
||||||
<i className='fa fa-fw fa-share-alt'/>
|
|
||||||
{
|
|
||||||
this.state.openDropdown ? null : (
|
|
||||||
<span className='tooltip'>Share</span>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</button>
|
|
||||||
<div ref='dropdown' className={'ShareButton-dropdown' + (this.state.openDropdown ? '' : ' hide')}>
|
|
||||||
{
|
|
||||||
!hasPublicURL ? (
|
|
||||||
<button
|
|
||||||
onClick={e => this.shareViaPublicURLHandler(e)}
|
|
||||||
ref='sharePublicURL'
|
|
||||||
disabled={this.state.isSharing}>
|
|
||||||
<i className='fa fa-fw fa-external-link'/> {this.state.failed ? 'Failed : Click to Try again' : !this.state.isSharing ? 'Share via public URL' : 'Sharing...'}
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<div className='ShareButton-url'>
|
|
||||||
<input className='ShareButton-url-input' value={this.state.url} readOnly/>
|
|
||||||
<button
|
|
||||||
onClick={e => this.handleCopyURLClick(e)}
|
|
||||||
className='ShareButton-url-button'
|
|
||||||
onMouseLeave={e => this.handleCopyURLMouseLeave(e)}
|
|
||||||
>
|
|
||||||
<i className='fa fa-fw fa-clipboard'/>
|
|
||||||
<div className='ShareButton-url-button-tooltip'>{this.state.copied ? 'Copied!' : 'Copy URL'}</div>
|
|
||||||
</button>
|
|
||||||
<div className='ShareButton-url-alert'>This url is valid for 7 days.</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
<button onClick={e => this.handleClipboardButtonClick(e)}>
|
|
||||||
<i className='fa fa-fw fa-clipboard'/> Copy to clipboard
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ShareButton.propTypes = {
|
|
||||||
article: PropTypes.shape({
|
|
||||||
publicURL: PropTypes.string,
|
|
||||||
content: PropTypes.string
|
|
||||||
}),
|
|
||||||
user: PropTypes.shape({
|
|
||||||
name: PropTypes.string
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,25 +1,28 @@
|
|||||||
|
$control-height = 30px
|
||||||
|
|
||||||
.root
|
.root
|
||||||
absolute left bottom
|
absolute left bottom
|
||||||
border-top $ui-border
|
|
||||||
top $topBar-height - 1
|
top $topBar-height - 1
|
||||||
|
background-color $ui-noteList-backgroundColor
|
||||||
|
|
||||||
.control
|
.control
|
||||||
absolute top left right
|
absolute top left right
|
||||||
user-select none
|
user-select none
|
||||||
height 25px
|
height $control-height
|
||||||
font-size 10px
|
font-size 12px
|
||||||
border-bottom $ui-border
|
|
||||||
line-height 25px
|
line-height 25px
|
||||||
display flex
|
display flex
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-noteList-backgroundColor
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
|
|
||||||
.control-sortBy
|
.control-sortBy
|
||||||
flex 1
|
flex 1
|
||||||
padding-left 5px
|
padding-left 25px
|
||||||
|
|
||||||
.control-sortBy-select
|
.control-sortBy-select
|
||||||
margin-left 5px
|
margin-left 0
|
||||||
|
font-size 12px
|
||||||
|
color $ui-inactive-text-color
|
||||||
padding 0
|
padding 0
|
||||||
border none
|
border none
|
||||||
background-color transparent
|
background-color transparent
|
||||||
@@ -36,8 +39,6 @@
|
|||||||
color $ui-active-color
|
color $ui-active-color
|
||||||
&:hover
|
&:hover
|
||||||
color $ui-text-color
|
color $ui-text-color
|
||||||
.control-button-tooltip
|
|
||||||
opacity 1
|
|
||||||
|
|
||||||
.control-button--active
|
.control-button--active
|
||||||
@extend .control-button
|
@extend .control-button
|
||||||
@@ -45,178 +46,22 @@
|
|||||||
&:hover
|
&:hover
|
||||||
color $ui-active-color
|
color $ui-active-color
|
||||||
|
|
||||||
.control-button-tooltip
|
|
||||||
tooltip()
|
|
||||||
position absolute
|
|
||||||
top 20px
|
|
||||||
right 5px
|
|
||||||
padding 5px
|
|
||||||
opacity 0
|
|
||||||
white-space nowrap
|
|
||||||
border-radius 2px
|
|
||||||
z-index 1
|
|
||||||
|
|
||||||
.list
|
.list
|
||||||
absolute left right bottom
|
absolute left right bottom
|
||||||
top 24px
|
top $control-height
|
||||||
overflow auto
|
overflow auto
|
||||||
|
|
||||||
.item
|
|
||||||
position relative
|
|
||||||
border-bottom $ui-border
|
|
||||||
padding 2px 5px
|
|
||||||
user-select none
|
|
||||||
cursor pointer
|
|
||||||
transition background-color 0.15s
|
|
||||||
&:hover
|
|
||||||
background-color alpha($ui-active-color, 20%)
|
|
||||||
&:active
|
|
||||||
background-color $ui-active-color
|
|
||||||
color white
|
|
||||||
.item-title
|
|
||||||
.item-title-empty
|
|
||||||
.item-title-icon
|
|
||||||
.item-bottom-tagIcon
|
|
||||||
.item-bottom-tagList-empty
|
|
||||||
.item-bottom-time
|
|
||||||
color white
|
|
||||||
.item-bottom-tagList-item
|
|
||||||
background-color transparent
|
|
||||||
color white
|
|
||||||
|
|
||||||
.item--active
|
|
||||||
@extend .item
|
|
||||||
background-color $ui-active-color
|
|
||||||
color white
|
|
||||||
.item-title
|
|
||||||
.item-title-empty
|
|
||||||
.item-title-icon
|
|
||||||
.item-bottom-tagIcon
|
|
||||||
.item-bottom-tagList-empty
|
|
||||||
.item-bottom-time
|
|
||||||
color white
|
|
||||||
.item-bottom-tagList-item
|
|
||||||
background-color transparent
|
|
||||||
color white
|
|
||||||
&:hover
|
|
||||||
background-color $ui-active-color
|
|
||||||
|
|
||||||
.item-border
|
|
||||||
absolute top bottom left right
|
|
||||||
border-style solid
|
|
||||||
border-width 2px
|
|
||||||
border-color transparent
|
|
||||||
transition 0.15s
|
|
||||||
|
|
||||||
.item-title
|
|
||||||
height 24px
|
|
||||||
box-sizing border-box
|
|
||||||
line-height 24px
|
|
||||||
padding 0
|
|
||||||
overflow ellipsis
|
|
||||||
color $ui-text-color
|
|
||||||
|
|
||||||
.item-title-icon
|
|
||||||
font-size 12px
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
padding-right 3px
|
|
||||||
|
|
||||||
.item-title-empty
|
|
||||||
font-weight normal
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
|
|
||||||
.item-bottom
|
|
||||||
margin-top 2px
|
|
||||||
height 20px
|
|
||||||
font-size 12px
|
|
||||||
line-height 20px
|
|
||||||
overflow ellipsis
|
|
||||||
display flex
|
|
||||||
|
|
||||||
.item-bottom-tagIcon
|
|
||||||
vertical-align middle
|
|
||||||
color $ui-button-color
|
|
||||||
height 20px
|
|
||||||
line-height 20px
|
|
||||||
|
|
||||||
.item-bottom-tagList
|
|
||||||
flex 1
|
|
||||||
overflow ellipsis
|
|
||||||
line-height 20px
|
|
||||||
|
|
||||||
.item-bottom-tagList-item
|
|
||||||
margin 0 4px
|
|
||||||
padding 0 4px
|
|
||||||
height 20px
|
|
||||||
box-sizing border-box
|
|
||||||
border-radius 3px
|
|
||||||
vertical-align middle
|
|
||||||
border-style solid
|
|
||||||
border-color $ui-button--focus-borderColor
|
|
||||||
border-width 0 0 0 3px
|
|
||||||
background-color $ui-backgroundColor
|
|
||||||
color $ui-text-color
|
|
||||||
|
|
||||||
.item-bottom-tagList-empty
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
vertical-align middle
|
|
||||||
font-size 10px
|
|
||||||
margin-left 5px
|
|
||||||
|
|
||||||
.item-bottom-time
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
margin-left 5px
|
|
||||||
font-size 10px
|
|
||||||
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.root
|
.root
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
background-color $ui-dark-backgroundColor
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
|
|
||||||
.item
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
&:hover
|
|
||||||
background-color alpha($ui-active-color, 20%)
|
|
||||||
|
|
||||||
.item--active
|
|
||||||
@extend .item
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
.item-title
|
|
||||||
color white
|
|
||||||
.item-bottom-tagList-item
|
|
||||||
background-color transparent
|
|
||||||
color white
|
|
||||||
.item-bottom-tagList-empty
|
|
||||||
color white
|
|
||||||
&:hover
|
|
||||||
background-color $ui-active-color
|
|
||||||
|
|
||||||
.item-title
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.item-title-icon
|
|
||||||
color $ui-darkinactive-text-color
|
|
||||||
|
|
||||||
.item-title-empty
|
|
||||||
color $ui-dark-inactive-text-color
|
|
||||||
|
|
||||||
.item-bottom-tagIcon
|
|
||||||
color $ui-dark-button-color
|
|
||||||
|
|
||||||
.item-bottom-tagList-item
|
|
||||||
border-color $ui-dark-button--focus-borderColor
|
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.item-bottom-tagList-empty
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
vertical-align middle
|
|
||||||
|
|
||||||
.control
|
.control
|
||||||
background-color $ui-dark-backgroundColor
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
|
|
||||||
|
.control
|
||||||
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
.control-sortBy-select
|
|
||||||
color $ui-dark-text-color
|
|
||||||
|
|
||||||
.control-button
|
.control-button
|
||||||
color $ui-dark-inactive-text-color
|
color $ui-dark-inactive-text-color
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import _ from 'lodash'
|
|||||||
import ee from 'browser/main/lib/eventEmitter'
|
import ee from 'browser/main/lib/eventEmitter'
|
||||||
import dataApi from 'browser/main/lib/dataApi'
|
import dataApi from 'browser/main/lib/dataApi'
|
||||||
import ConfigManager from 'browser/main/lib/ConfigManager'
|
import ConfigManager from 'browser/main/lib/ConfigManager'
|
||||||
|
import NoteItem from 'browser/components/NoteItem'
|
||||||
|
import NoteItemSimple from 'browser/components/NoteItemSimple'
|
||||||
|
|
||||||
const { remote } = require('electron')
|
const { remote } = require('electron')
|
||||||
const { Menu, MenuItem, dialog } = remote
|
const { Menu, MenuItem, dialog } = remote
|
||||||
@@ -314,57 +316,40 @@ class NoteList extends React.Component {
|
|||||||
.sort(sortFunc)
|
.sort(sortFunc)
|
||||||
|
|
||||||
let noteList = notes
|
let noteList = notes
|
||||||
.map((note) => {
|
.map(note => {
|
||||||
if (note == null) return null
|
if (note == null) {
|
||||||
let tagElements = _.isArray(note.tags)
|
return null
|
||||||
? note.tags.map((tag) => {
|
}
|
||||||
return (
|
|
||||||
<span styleName='item-bottom-tagList-item'
|
const isDefault = config.listStyle === 'DEFAULT'
|
||||||
key={tag}>
|
const isActive = location.query.key === note.storage + '-' + note.key
|
||||||
{tag}
|
const dateDisplay = moment(
|
||||||
</span>
|
config.sortBy === 'CREATED_AT'
|
||||||
)
|
? note.createdAt : note.updatedAt
|
||||||
})
|
).fromNow()
|
||||||
: []
|
const key = `${note.storage}-${note.key}`
|
||||||
let isActive = location.query.key === note.storage + '-' + note.key
|
|
||||||
|
if (isDefault) {
|
||||||
|
return (
|
||||||
|
<NoteItem
|
||||||
|
isActive={isActive}
|
||||||
|
note={note}
|
||||||
|
dateDisplay={dateDisplay}
|
||||||
|
key={key}
|
||||||
|
handleNoteClick={this.handleNoteClick.bind(this)}
|
||||||
|
handleNoteContextMenu={this.handleNoteContextMenu.bind(this)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div styleName={isActive
|
<NoteItemSimple
|
||||||
? 'item--active'
|
isActive={isActive}
|
||||||
: 'item'
|
note={note}
|
||||||
}
|
key={key}
|
||||||
key={note.storage + '-' + note.key}
|
handleNoteClick={this.handleNoteClick.bind(this)}
|
||||||
onClick={(e) => this.handleNoteClick(e, note.storage + '-' + note.key)}
|
handleNoteContextMenu={this.handleNoteContextMenu.bind(this)}
|
||||||
onContextMenu={(e) => this.handleNoteContextMenu(e, note.storage + '-' + note.key)}
|
/>
|
||||||
>
|
|
||||||
<div styleName='item-title'>
|
|
||||||
{note.type === 'SNIPPET_NOTE'
|
|
||||||
? <i styleName='item-title-icon' className='fa fa-fw fa-code'/>
|
|
||||||
: <i styleName='item-title-icon' className='fa fa-fw fa-file-text-o'/>
|
|
||||||
}
|
|
||||||
{note.title.trim().length > 0
|
|
||||||
? note.title
|
|
||||||
: <span styleName='item-title-empty'>Empty</span>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{config.listStyle === 'DEFAULT' &&
|
|
||||||
<div styleName='item-bottom'>
|
|
||||||
<i styleName='item-bottom-tagIcon'
|
|
||||||
className='fa fa-tags fa-fw'
|
|
||||||
/>
|
|
||||||
<div styleName='item-bottom-tagList'>
|
|
||||||
{tagElements.length > 0
|
|
||||||
? tagElements
|
|
||||||
: <span styleName='item-bottom-tagList-empty'>Not tagged yet</span>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div styleName='item-bottom-time'>
|
|
||||||
{moment(config.sortBy === 'CREATED_AT' ? note.createdAt : note.updatedAt).fromNow()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -391,10 +376,7 @@ class NoteList extends React.Component {
|
|||||||
}
|
}
|
||||||
onClick={(e) => this.handleListStyleButtonClick(e, 'DEFAULT')}
|
onClick={(e) => this.handleListStyleButtonClick(e, 'DEFAULT')}
|
||||||
>
|
>
|
||||||
<i className='fa fa-th-list'/>
|
<i className='fa fa-th-large' />
|
||||||
<span styleName='control-button-tooltip'>
|
|
||||||
Default Size
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
<button styleName={config.listStyle === 'SMALL'
|
<button styleName={config.listStyle === 'SMALL'
|
||||||
? 'control-button--active'
|
? 'control-button--active'
|
||||||
@@ -402,10 +384,7 @@ class NoteList extends React.Component {
|
|||||||
}
|
}
|
||||||
onClick={(e) => this.handleListStyleButtonClick(e, 'SMALL')}
|
onClick={(e) => this.handleListStyleButtonClick(e, 'SMALL')}
|
||||||
>
|
>
|
||||||
<i className='fa fa-list'/>
|
<i className='fa fa-list-ul' />
|
||||||
<span styleName='control-button-tooltip'>
|
|
||||||
Small Size
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='list'
|
<div styleName='list'
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
.root
|
.root
|
||||||
absolute top left bottom
|
absolute top left bottom
|
||||||
width $sideNav-width
|
width $sideNav-width
|
||||||
border-right $ui-border
|
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-backgroundColor
|
||||||
user-select none
|
user-select none
|
||||||
color $ui-text-color
|
color $ui-text-color
|
||||||
|
|
||||||
.top
|
.top
|
||||||
height $topBar-height
|
height $topBar-height
|
||||||
border-bottom $ui-border
|
|
||||||
|
|
||||||
.top-menu
|
.top-menu
|
||||||
navButtonColor()
|
navButtonColor()
|
||||||
height $topBar-height - 1
|
height $topBar-height - 1
|
||||||
padding 0 10px
|
padding 0 15px
|
||||||
font-size 14px
|
font-size 14px
|
||||||
width 100%
|
width 100%
|
||||||
text-align left
|
text-align left
|
||||||
@@ -22,32 +20,10 @@
|
|||||||
margin-left 5px
|
margin-left 5px
|
||||||
overflow ellipsis
|
overflow ellipsis
|
||||||
|
|
||||||
.menu
|
|
||||||
margin 0
|
|
||||||
|
|
||||||
.menu-button
|
|
||||||
navButtonColor()
|
|
||||||
height 32px
|
|
||||||
padding 0 10px
|
|
||||||
font-size 14px
|
|
||||||
width 100%
|
|
||||||
text-align left
|
|
||||||
overflow ellipsis
|
|
||||||
|
|
||||||
.menu-button--active
|
|
||||||
@extend .menu-button
|
|
||||||
background-color $ui-button--active-backgroundColor
|
|
||||||
color $ui-button--active-color
|
|
||||||
&:hover
|
|
||||||
background-color $ui-button--active-backgroundColor
|
|
||||||
|
|
||||||
.menu-button-label
|
|
||||||
margin-left 5px
|
|
||||||
|
|
||||||
.storageList
|
.storageList
|
||||||
absolute left right
|
absolute left right
|
||||||
bottom 32px
|
bottom 37px
|
||||||
top 120px
|
top 160px
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
|
|
||||||
.storageList-empty
|
.storageList-empty
|
||||||
@@ -135,16 +111,6 @@ body[data-theme="dark"]
|
|||||||
.top-menu
|
.top-menu
|
||||||
navDarkButtonColor()
|
navDarkButtonColor()
|
||||||
|
|
||||||
.menu-button
|
|
||||||
navDarkButtonColor()
|
|
||||||
|
|
||||||
.menu-button--active
|
|
||||||
@extend .menu-button
|
|
||||||
background-color $ui-dark-button--active-backgroundColor
|
|
||||||
color $ui-dark-button--active-color
|
|
||||||
&:hover
|
|
||||||
background-color $ui-dark-button--active-backgroundColor
|
|
||||||
|
|
||||||
.storageList-empty
|
.storageList-empty
|
||||||
color $ui-dark-inactive-text-color
|
color $ui-dark-inactive-text-color
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import modal from 'browser/main/lib/modal'
|
|||||||
import CreateFolderModal from 'browser/main/modals/CreateFolderModal'
|
import CreateFolderModal from 'browser/main/modals/CreateFolderModal'
|
||||||
import RenameFolderModal from 'browser/main/modals/RenameFolderModal'
|
import RenameFolderModal from 'browser/main/modals/RenameFolderModal'
|
||||||
import dataApi from 'browser/main/lib/dataApi'
|
import dataApi from 'browser/main/lib/dataApi'
|
||||||
|
import StorageItemChild from 'browser/components/StorageItem'
|
||||||
|
|
||||||
const { remote } = require('electron')
|
const { remote } = require('electron')
|
||||||
const { Menu, MenuItem, dialog } = remote
|
const { Menu, MenuItem, dialog } = remote
|
||||||
@@ -134,34 +135,24 @@ class StorageItem extends React.Component {
|
|||||||
let { storage, location, isFolded, data } = this.props
|
let { storage, location, isFolded, data } = this.props
|
||||||
let { folderNoteMap } = data
|
let { folderNoteMap } = data
|
||||||
let folderList = storage.folders.map((folder) => {
|
let folderList = storage.folders.map((folder) => {
|
||||||
let isActive = location.pathname.match(new RegExp('\/storages\/' + storage.key + '\/folders\/' + folder.key))
|
let isActive = !!(location.pathname.match(new RegExp('\/storages\/' + storage.key + '\/folders\/' + folder.key)))
|
||||||
let noteSet = folderNoteMap.get(storage.key + '-' + folder.key)
|
let noteSet = folderNoteMap.get(storage.key + '-' + folder.key)
|
||||||
|
|
||||||
let noteCount = noteSet != null
|
let noteCount = noteSet != null
|
||||||
? noteSet.size
|
? noteSet.size
|
||||||
: 0
|
: 0
|
||||||
return <button styleName={isActive
|
return (
|
||||||
? 'folderList-item--active'
|
<StorageItemChild
|
||||||
: 'folderList-item'
|
key={folder.key}
|
||||||
}
|
isActive={isActive}
|
||||||
key={folder.key}
|
handleButtonClick={(e) => this.handleFolderButtonClick(folder.key)(e)}
|
||||||
onClick={(e) => this.handleFolderButtonClick(folder.key)(e)}
|
handleContextMenu={(e) => this.handleFolderButtonContextMenu(e, folder)}
|
||||||
onContextMenu={(e) => this.handleFolderButtonContextMenu(e, folder)}
|
folderName={folder.name}
|
||||||
>
|
folderColor={folder.color}
|
||||||
<span styleName='folderList-item-name'
|
isFolded={isFolded}
|
||||||
style={{borderColor: folder.color}}
|
noteCount={noteCount}
|
||||||
>
|
/>
|
||||||
{isFolded ? folder.name.substring(0, 1) : folder.name}
|
)
|
||||||
</span>
|
|
||||||
{!isFolded &&
|
|
||||||
<span styleName='folderList-item-noteCount'>{noteCount}</span>
|
|
||||||
}
|
|
||||||
{isFolded &&
|
|
||||||
<span styleName='folderList-item-tooltip'>
|
|
||||||
{folder.name}
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
</button>
|
|
||||||
})
|
})
|
||||||
|
|
||||||
let isActive = location.pathname.match(new RegExp('\/storages\/' + storage.key + '$'))
|
let isActive = location.pathname.match(new RegExp('\/storages\/' + storage.key + '$'))
|
||||||
@@ -190,7 +181,7 @@ class StorageItem extends React.Component {
|
|||||||
<button styleName='header-addFolderButton'
|
<button styleName='header-addFolderButton'
|
||||||
onClick={(e) => this.handleAddFolderButtonClick(e)}
|
onClick={(e) => this.handleAddFolderButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-plus'/>
|
<i className='fa fa-plus' />
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
.root
|
.root
|
||||||
width 100%
|
width 100%
|
||||||
user-select none
|
user-select none
|
||||||
|
|
||||||
.header
|
.header
|
||||||
position relative
|
position relative
|
||||||
height 26px
|
height 26px
|
||||||
width 100%
|
width 100%
|
||||||
|
margin-bottom 5px
|
||||||
transition 0.15s
|
transition 0.15s
|
||||||
&:hover
|
&:hover
|
||||||
background-color $ui-button--hover-backgroundColor
|
background-color $ui-button--hover-backgroundColor
|
||||||
@@ -45,7 +47,7 @@
|
|||||||
.header-info
|
.header-info
|
||||||
display block
|
display block
|
||||||
width 100%
|
width 100%
|
||||||
height 26px
|
height 30px
|
||||||
padding-left 25px
|
padding-left 25px
|
||||||
padding-right 10px
|
padding-right 10px
|
||||||
line-height 26px
|
line-height 26px
|
||||||
@@ -78,63 +80,6 @@
|
|||||||
&:active
|
&:active
|
||||||
color $ui-active-color
|
color $ui-active-color
|
||||||
|
|
||||||
.folderList-item
|
|
||||||
display flex
|
|
||||||
width 100%
|
|
||||||
height 26px
|
|
||||||
background-color transparent
|
|
||||||
color $ui-inactive-text-color
|
|
||||||
padding 0
|
|
||||||
margin-bottom 2px
|
|
||||||
text-align left
|
|
||||||
border none
|
|
||||||
overflow ellipsis
|
|
||||||
font-size 14px
|
|
||||||
&:first-child
|
|
||||||
margin-top 0
|
|
||||||
&:hover
|
|
||||||
background-color $ui-button--hover-backgroundColor
|
|
||||||
&:active
|
|
||||||
color $ui-button--active-color
|
|
||||||
background-color $ui-button--active-backgroundColor
|
|
||||||
|
|
||||||
.folderList-item--active
|
|
||||||
@extend .folderList-item
|
|
||||||
color $ui-button--active-color
|
|
||||||
background-color $ui-button--active-backgroundColor
|
|
||||||
&:hover
|
|
||||||
color $ui-button--active-color
|
|
||||||
background-color $ui-button--active-backgroundColor
|
|
||||||
|
|
||||||
.folderList-item-name
|
|
||||||
display block
|
|
||||||
flex 1
|
|
||||||
padding 0 10px
|
|
||||||
height 26px
|
|
||||||
line-height 26px
|
|
||||||
border-width 0 0 0 6px
|
|
||||||
border-style solid
|
|
||||||
border-color transparent
|
|
||||||
|
|
||||||
.folderList-item-noteCount
|
|
||||||
float right
|
|
||||||
line-height 26px
|
|
||||||
padding-right 5px
|
|
||||||
font-size 12px
|
|
||||||
|
|
||||||
.folderList-item-tooltip
|
|
||||||
tooltip()
|
|
||||||
position fixed
|
|
||||||
padding 0 10px
|
|
||||||
left 44px
|
|
||||||
z-index 10
|
|
||||||
pointer-events none
|
|
||||||
opacity 0
|
|
||||||
border-top-right-radius 2px
|
|
||||||
border-bottom-right-radius 2px
|
|
||||||
height 26px
|
|
||||||
line-height 26px
|
|
||||||
|
|
||||||
.root--folded
|
.root--folded
|
||||||
@extend .root
|
@extend .root
|
||||||
.header
|
.header
|
||||||
@@ -161,11 +106,7 @@
|
|||||||
.header-info--folded-tooltip-path
|
.header-info--folded-tooltip-path
|
||||||
font-size 10px
|
font-size 10px
|
||||||
margin 0 5px
|
margin 0 5px
|
||||||
.folderList-item:hover, .folderList-item--active:hover
|
|
||||||
.folderList-item-tooltip
|
|
||||||
opacity 1
|
|
||||||
.folderList-item-name
|
|
||||||
padding-left 14px
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.header-toggleButton
|
.header-toggleButton
|
||||||
.header-addFolderButton
|
.header-addFolderButton
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ import { openModal } from 'browser/main/lib/modal'
|
|||||||
import PreferencesModal from '../modals/PreferencesModal'
|
import PreferencesModal from '../modals/PreferencesModal'
|
||||||
import ConfigManager from 'browser/main/lib/ConfigManager'
|
import ConfigManager from 'browser/main/lib/ConfigManager'
|
||||||
import StorageItem from './StorageItem'
|
import StorageItem from './StorageItem'
|
||||||
|
import SideNavFilter from 'browser/components/SideNavFilter'
|
||||||
const electron = require('electron')
|
|
||||||
const { remote } = electron
|
|
||||||
|
|
||||||
class SideNav extends React.Component {
|
class SideNav extends React.Component {
|
||||||
// TODO: should not use electron stuff v0.7
|
// TODO: should not use electron stuff v0.7
|
||||||
@@ -39,8 +37,8 @@ class SideNav extends React.Component {
|
|||||||
let { data, location, config, dispatch } = this.props
|
let { data, location, config, dispatch } = this.props
|
||||||
|
|
||||||
let isFolded = config.isSideNavFolded
|
let isFolded = config.isSideNavFolded
|
||||||
let isHomeActive = location.pathname.match(/^\/home$/)
|
let isHomeActive = !!location.pathname.match(/^\/home$/)
|
||||||
let isStarredActive = location.pathname.match(/^\/starred$/)
|
let isStarredActive = !!location.pathname.match(/^\/starred$/)
|
||||||
|
|
||||||
let storageList = data.storageMap.map((storage, key) => {
|
let storageList = data.storageMap.map((storage, key) => {
|
||||||
return <StorageItem
|
return <StorageItem
|
||||||
@@ -64,25 +62,18 @@ class SideNav extends React.Component {
|
|||||||
<button styleName='top-menu'
|
<button styleName='top-menu'
|
||||||
onClick={(e) => this.handleMenuButtonClick(e)}
|
onClick={(e) => this.handleMenuButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-navicon fa-fw'/>
|
<i className='fa fa-navicon fa-fw' />
|
||||||
<span styleName='top-menu-label'>Menu</span>
|
<span styleName='top-menu-label'>Menu</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div styleName='menu'>
|
<SideNavFilter
|
||||||
<button styleName={isHomeActive ? 'menu-button--active' : 'menu-button'}
|
isFolded={isFolded}
|
||||||
onClick={(e) => this.handleHomeButtonClick(e)}
|
isHomeActive={isHomeActive}
|
||||||
>
|
handleAllNotesButtonClick={(e) => this.handleHomeButtonClick(e)}
|
||||||
<i className='fa fa-files-o fa-fw'/>
|
isStarredActive={isStarredActive}
|
||||||
<span styleName='menu-button-label'>All Notes</span>
|
handleStarredButtonClick={(e) => this.handleStarredButtonClick(e)}
|
||||||
</button>
|
/>
|
||||||
<button styleName={isStarredActive ? 'menu-button--active' : 'menu-button'}
|
|
||||||
onClick={(e) => this.handleStarredButtonClick(e)}
|
|
||||||
>
|
|
||||||
<i className='fa fa-star fa-fw'/>
|
|
||||||
<span styleName='menu-button-label'>Starred</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div styleName='storageList'>
|
<div styleName='storageList'>
|
||||||
{storageList.length > 0 ? storageList : (
|
{storageList.length > 0 ? storageList : (
|
||||||
@@ -93,8 +84,8 @@ class SideNav extends React.Component {
|
|||||||
onClick={(e) => this.handleToggleButtonClick(e)}
|
onClick={(e) => this.handleToggleButtonClick(e)}
|
||||||
>
|
>
|
||||||
{isFolded
|
{isFolded
|
||||||
? <i className='fa fa-angle-double-right'/>
|
? <i className='fa fa-angle-double-right' />
|
||||||
: <i className='fa fa-angle-double-left'/>
|
: <i className='fa fa-angle-double-left' />
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
|
@import('../Detail/DetailVars')
|
||||||
|
|
||||||
.root
|
.root
|
||||||
absolute bottom left right
|
absolute bottom left right
|
||||||
height $statusBar-height
|
height $statusBar-height
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-noteDetail-backgroundColor
|
||||||
border-top $ui-border
|
border-top $ui-border
|
||||||
display flex
|
display flex
|
||||||
|
box-shadow $note-detail-box-shadow
|
||||||
|
|
||||||
.blank
|
.blank
|
||||||
flex 1
|
flex 1
|
||||||
@@ -39,8 +42,9 @@
|
|||||||
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.root
|
.root
|
||||||
background-color $ui-dark-backgroundColor
|
background-color $ui-dark-noteDetail-backgroundColor
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
|
box-shadow none
|
||||||
|
|
||||||
.zoom
|
.zoom
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { PropTypes } from 'react'
|
|||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './StatusBar.styl'
|
import styles from './StatusBar.styl'
|
||||||
import ZoomManager from 'browser/main/lib/ZoomManager'
|
import ZoomManager from 'browser/main/lib/ZoomManager'
|
||||||
|
import LastUpdatedString from '../Detail/LastUpdatedString'
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const { remote, ipcRenderer } = electron
|
const { remote, ipcRenderer } = electron
|
||||||
@@ -52,22 +53,23 @@ class StatusBar extends React.Component {
|
|||||||
<div className='StatusBar'
|
<div className='StatusBar'
|
||||||
styleName='root'
|
styleName='root'
|
||||||
>
|
>
|
||||||
<div styleName='blank' />
|
|
||||||
{status.updateReady
|
|
||||||
? <button onClick={this.updateApp} styleName='update'>
|
|
||||||
<i styleName='update-icon' className='fa fa-cloud-download' /> Ready to Update!
|
|
||||||
</button>
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
{/*<button styleName='help'>
|
|
||||||
<i className='fa fa-info-circle' />
|
|
||||||
</button>*/}
|
|
||||||
<button styleName='zoom'
|
<button styleName='zoom'
|
||||||
onClick={(e) => this.handleZoomButtonClick(e)}
|
onClick={(e) => this.handleZoomButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-search-plus' />
|
<i className='fa fa-search-plus' />
|
||||||
{Math.floor(config.zoom * 100)}%
|
{Math.floor(config.zoom * 100)}%
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<div styleName='blank' />
|
||||||
|
|
||||||
|
{status.updateReady
|
||||||
|
? <button onClick={this.updateApp} styleName='update'>
|
||||||
|
<i styleName='update-icon' className='fa fa-cloud-download' /> Ready to Update!
|
||||||
|
</button>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
|
||||||
|
<LastUpdatedString date={this.props.date} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,8 @@ StatusBar.contextTypes = {
|
|||||||
status: PropTypes.shape({
|
status: PropTypes.shape({
|
||||||
updateReady: PropTypes.bool.isRequired
|
updateReady: PropTypes.bool.isRequired
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
config: PropTypes.shape({}).isRequired
|
config: PropTypes.shape({}).isRequired,
|
||||||
|
date: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusBar.propTypes = {
|
StatusBar.propTypes = {
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
.root
|
.root
|
||||||
position relative
|
position relative
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-noteList-backgroundColor
|
||||||
height $topBar-height - 1
|
height $topBar-height - 1
|
||||||
|
|
||||||
.root--expanded
|
.root--expanded
|
||||||
@extend .root
|
@extend .root
|
||||||
|
|
||||||
$control-height = 34px
|
$control-height = 34px
|
||||||
|
|
||||||
.control
|
.control
|
||||||
position absolute
|
position absolute
|
||||||
top 8px
|
top 13px
|
||||||
left 8px
|
left 8px
|
||||||
right 8px
|
right 8px
|
||||||
height $control-height
|
height $control-height
|
||||||
border $ui-border
|
|
||||||
border-radius 20px
|
|
||||||
overflow hidden
|
overflow hidden
|
||||||
display flex
|
display flex
|
||||||
|
|
||||||
@@ -28,6 +28,7 @@ $control-height = 34px
|
|||||||
line-height 32px
|
line-height 32px
|
||||||
width 35px
|
width 35px
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
|
background-color $ui-noteList-backgroundColor
|
||||||
|
|
||||||
.control-search-input
|
.control-search-input
|
||||||
display block
|
display block
|
||||||
@@ -38,6 +39,7 @@ $control-height = 34px
|
|||||||
height 100%
|
height 100%
|
||||||
outline none
|
outline none
|
||||||
border none
|
border none
|
||||||
|
background-color $ui-noteList-backgroundColor
|
||||||
|
|
||||||
.control-search-optionList
|
.control-search-optionList
|
||||||
position fixed
|
position fixed
|
||||||
@@ -58,6 +60,7 @@ $control-height = 34px
|
|||||||
overflow ellipsis
|
overflow ellipsis
|
||||||
&:hover
|
&:hover
|
||||||
background-color alpha($ui-active-color, 10%)
|
background-color alpha($ui-active-color, 10%)
|
||||||
|
|
||||||
.control-search-optionList-item-folder
|
.control-search-optionList-item-folder
|
||||||
border-left 4px solid transparent
|
border-left 4px solid transparent
|
||||||
padding 2px 5px
|
padding 2px 5px
|
||||||
@@ -66,40 +69,30 @@ $control-height = 34px
|
|||||||
font-size 12px
|
font-size 12px
|
||||||
height 16px
|
height 16px
|
||||||
margin-bottom 4px
|
margin-bottom 4px
|
||||||
|
|
||||||
.control-search-optionList-item-folder-surfix
|
.control-search-optionList-item-folder-surfix
|
||||||
font-size 10px
|
font-size 10px
|
||||||
margin-left 5px
|
margin-left 5px
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
|
|
||||||
.control-search-optionList-item-type
|
.control-search-optionList-item-type
|
||||||
font-size 12px
|
font-size 12px
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
padding-right 3px
|
padding-right 3px
|
||||||
|
|
||||||
.control-search-optionList-empty
|
.control-search-optionList-empty
|
||||||
height 150px
|
height 150px
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
line-height 150px
|
line-height 150px
|
||||||
text-align center
|
text-align center
|
||||||
|
|
||||||
.control-contextButton
|
|
||||||
display block
|
|
||||||
width 20px
|
|
||||||
height $control-height - 2
|
|
||||||
navButtonColor()
|
|
||||||
border-left $ui-border
|
|
||||||
font-size 14px
|
|
||||||
line-height 28px
|
|
||||||
padding 0
|
|
||||||
&:active
|
|
||||||
border-color $ui-button--active-backgroundColor
|
|
||||||
&:hover .control-newPostButton-tooltip
|
|
||||||
opacity 1
|
|
||||||
|
|
||||||
.control-newPostButton
|
.control-newPostButton
|
||||||
display block
|
display block
|
||||||
width 36px
|
width 32px
|
||||||
height $control-height - 2
|
height $control-height - 2
|
||||||
navButtonColor()
|
navButtonColor()
|
||||||
border-left $ui-border
|
border $ui-border
|
||||||
|
border-radius 32px
|
||||||
font-size 14px
|
font-size 14px
|
||||||
line-height 28px
|
line-height 28px
|
||||||
padding 0
|
padding 0
|
||||||
@@ -112,17 +105,18 @@ $control-height = 34px
|
|||||||
tooltip()
|
tooltip()
|
||||||
position fixed
|
position fixed
|
||||||
pointer-events none
|
pointer-events none
|
||||||
top 45px
|
top 50px
|
||||||
left 385px
|
left 433px
|
||||||
z-index 10
|
z-index 200
|
||||||
padding 5px
|
padding 5px
|
||||||
line-height normal
|
line-height normal
|
||||||
|
border-radius 2px
|
||||||
opacity 0
|
opacity 0
|
||||||
transition 0.1s
|
transition 0.1s
|
||||||
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.root, .root--expanded
|
.root, .root--expanded
|
||||||
background-color $ui-dark-backgroundColor
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
|
|
||||||
.control
|
.control
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
@@ -134,11 +128,13 @@ body[data-theme="dark"]
|
|||||||
line-height 32px
|
line-height 32px
|
||||||
width 35px
|
width 35px
|
||||||
color $ui-dark-inactive-text-color
|
color $ui-dark-inactive-text-color
|
||||||
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
|
|
||||||
.control-search-input
|
.control-search-input
|
||||||
input
|
input
|
||||||
background-color $dark-background-color
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
color $ui-dark-text-color
|
color $ui-dark-text-color
|
||||||
|
|
||||||
.control-search-optionList
|
.control-search-optionList
|
||||||
color white
|
color white
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color $ui-dark-button--hover-backgroundColor
|
||||||
@@ -162,10 +158,10 @@ body[data-theme="dark"]
|
|||||||
.control-search-optionList-empty
|
.control-search-optionList-empty
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
|
|
||||||
.control-contextButton,
|
|
||||||
.control-newPostButton
|
.control-newPostButton
|
||||||
colorDarkDefaultButton()
|
colorDarkDefaultButton()
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-dark-noteList-backgroundColor
|
||||||
&:active
|
&:active
|
||||||
border-color $ui-dark-button--active-backgroundColor
|
border-color $ui-dark-button--active-backgroundColor
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import ConfigManager from 'browser/main/lib/ConfigManager'
|
|||||||
import dataApi from 'browser/main/lib/dataApi'
|
import dataApi from 'browser/main/lib/dataApi'
|
||||||
|
|
||||||
const OSX = window.process.platform === 'darwin'
|
const OSX = window.process.platform === 'darwin'
|
||||||
const { remote } = require('electron')
|
|
||||||
const { Menu, MenuItem } = remote
|
|
||||||
|
|
||||||
class TopBar extends React.Component {
|
class TopBar extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -71,10 +69,10 @@ class TopBar extends React.Component {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (storage == null) throw new Error('No storage to create a note')
|
if (storage == null) window.alert('No storage to create a note')
|
||||||
let folder = _.find(storage.folders, {key: params.folderKey})
|
let folder = _.find(storage.folders, {key: params.folderKey})
|
||||||
if (folder == null) folder = storage.folders[0]
|
if (folder == null) folder = storage.folders[0]
|
||||||
if (folder == null) throw new Error('No folder to craete a note')
|
if (folder == null) window.alert('No folder to create a note')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
storage,
|
storage,
|
||||||
@@ -192,47 +190,6 @@ class TopBar extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleContextButtonClick (e) {
|
|
||||||
let { config } = this.props
|
|
||||||
|
|
||||||
let menu = new Menu()
|
|
||||||
menu.append(new MenuItem({
|
|
||||||
label: 'Create Markdown Note',
|
|
||||||
click: (e) => this.createNote('MARKDOWN_NOTE')
|
|
||||||
}))
|
|
||||||
menu.append(new MenuItem({
|
|
||||||
label: 'Create Snippet Note',
|
|
||||||
click: (e) => this.createNote('SNIPPET_NOTE')
|
|
||||||
}))
|
|
||||||
menu.append(new MenuItem({
|
|
||||||
type: 'separator'
|
|
||||||
}))
|
|
||||||
menu.append(new MenuItem({
|
|
||||||
label: 'Change Default Note',
|
|
||||||
submenu: [
|
|
||||||
{
|
|
||||||
type: 'radio',
|
|
||||||
label: 'Markdown Note',
|
|
||||||
checked: config.ui.defaultNote === 'MARKDOWN_NOTE',
|
|
||||||
click: (e) => this.setDefaultNote('MARKDOWN_NOTE')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'radio',
|
|
||||||
label: 'Snippet Note',
|
|
||||||
checked: config.ui.defaultNote === 'SNIPPET_NOTE',
|
|
||||||
click: (e) => this.setDefaultNote('SNIPPET_NOTE')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'radio',
|
|
||||||
label: 'Always Ask',
|
|
||||||
checked: config.ui.defaultNote === 'ALWAYS_ASK',
|
|
||||||
click: (e) => this.setDefaultNote('ALWAYS_ASK')
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}))
|
|
||||||
menu.popup(remote.getCurrentWindow())
|
|
||||||
}
|
|
||||||
|
|
||||||
createNote (noteType) {
|
createNote (noteType) {
|
||||||
let { dispatch, location } = this.props
|
let { dispatch, location } = this.props
|
||||||
if (noteType !== 'MARKDOWN_NOTE' && noteType !== 'SNIPPET_NOTE') throw new Error('Invalid note type.')
|
if (noteType !== 'MARKDOWN_NOTE' && noteType !== 'SNIPPET_NOTE') throw new Error('Invalid note type.')
|
||||||
@@ -303,8 +260,8 @@ class TopBar extends React.Component {
|
|||||||
<span styleName='control-search-optionList-item-folder-surfix'>in {storage.name}</span>
|
<span styleName='control-search-optionList-item-folder-surfix'>in {storage.name}</span>
|
||||||
</div>
|
</div>
|
||||||
{note.type === 'SNIPPET_NOTE'
|
{note.type === 'SNIPPET_NOTE'
|
||||||
? <i styleName='control-search-optionList-item-type' className='fa fa-code'/>
|
? <i styleName='control-search-optionList-item-type' className='fa fa-code' />
|
||||||
: <i styleName='control-search-optionList-item-type' className='fa fa-file-text-o'/>
|
: <i styleName='control-search-optionList-item-type' className='fa fa-file-text-o' />
|
||||||
}
|
}
|
||||||
{note.title}
|
{note.title}
|
||||||
</div>
|
</div>
|
||||||
@@ -317,7 +274,7 @@ class TopBar extends React.Component {
|
|||||||
>
|
>
|
||||||
<div styleName='control'>
|
<div styleName='control'>
|
||||||
<div styleName='control-search'>
|
<div styleName='control-search'>
|
||||||
<i styleName='control-search-icon' className='fa fa-search fa-fw'/>
|
<i styleName='control-search-icon' className='fa fa-search fa-fw' />
|
||||||
<div styleName='control-search-input'
|
<div styleName='control-search-input'
|
||||||
onFocus={(e) => this.handleSearchFocus(e)}
|
onFocus={(e) => this.handleSearchFocus(e)}
|
||||||
onBlur={(e) => this.handleSearchBlur(e)}
|
onBlur={(e) => this.handleSearchBlur(e)}
|
||||||
@@ -344,23 +301,18 @@ class TopBar extends React.Component {
|
|||||||
<button styleName='left-search-clearButton'
|
<button styleName='left-search-clearButton'
|
||||||
onClick={(e) => this.handleSearchClearButton(e)}
|
onClick={(e) => this.handleSearchClearButton(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-times'/>
|
<i className='fa fa-times' />
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<button styleName='control-newPostButton'
|
<button styleName='control-newPostButton'
|
||||||
onClick={(e) => this.handleNewPostButtonClick(e)}>
|
onClick={(e) => this.handleNewPostButtonClick(e)}>
|
||||||
<i className='fa fa-plus'/>
|
<i className='fa fa-plus' />
|
||||||
<span styleName='control-newPostButton-tooltip'>
|
<span styleName='control-newPostButton-tooltip'>
|
||||||
New Note {OSX ? '⌘' : '^'} + n
|
Make a Note {OSX ? '⌘' : '^'} + n
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button styleName='control-contextButton'
|
|
||||||
onClick={(e) => this.handleContextButtonClick(e)}
|
|
||||||
>
|
|
||||||
<i className='fa fa-caret-down'/>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ body[data-theme="dark"]
|
|||||||
font-family inherit !important
|
font-family inherit !important
|
||||||
line-height 1.4em
|
line-height 1.4em
|
||||||
height 100%
|
height 100%
|
||||||
|
.CodeMirror > div > textarea
|
||||||
|
margin-bottom -1em
|
||||||
.CodeMirror-focused .CodeMirror-selected
|
.CodeMirror-focused .CodeMirror-selected
|
||||||
background #B1D7FE
|
background #B1D7FE
|
||||||
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection
|
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ let isInitialized = false
|
|||||||
export const DEFAULT_CONFIG = {
|
export const DEFAULT_CONFIG = {
|
||||||
zoom: 1,
|
zoom: 1,
|
||||||
isSideNavFolded: false,
|
isSideNavFolded: false,
|
||||||
listWidth: 250,
|
listWidth: 280,
|
||||||
navWidth: 200,
|
navWidth: 200,
|
||||||
sortBy: 'UPDATED_AT', // 'CREATED_AT', 'UPDATED_AT', 'APLHABETICAL'
|
sortBy: 'UPDATED_AT', // 'CREATED_AT', 'UPDATED_AT', 'APLHABETICAL'
|
||||||
listStyle: 'DEFAULT', // 'DEFAULT', 'SMALL'
|
listStyle: 'DEFAULT', // 'DEFAULT', 'SMALL'
|
||||||
@@ -25,6 +25,7 @@ export const DEFAULT_CONFIG = {
|
|||||||
},
|
},
|
||||||
editor: {
|
editor: {
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
|
keyMap: 'sublime',
|
||||||
fontSize: '14',
|
fontSize: '14',
|
||||||
fontFamily: 'Monaco, Consolas',
|
fontFamily: 'Monaco, Consolas',
|
||||||
indentType: 'space',
|
indentType: 'space',
|
||||||
@@ -34,7 +35,7 @@ export const DEFAULT_CONFIG = {
|
|||||||
preview: {
|
preview: {
|
||||||
fontSize: '14',
|
fontSize: '14',
|
||||||
fontFamily: 'Lato',
|
fontFamily: 'Lato',
|
||||||
codeBlockTheme: 'xcode',
|
codeBlockTheme: 'elegant',
|
||||||
lineNumber: true
|
lineNumber: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ class ModalBase extends React.Component {
|
|||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className={'ModalBase' + (this.state.isHidden ? ' hide' : '')}>
|
<div className={'ModalBase' + (this.state.isHidden ? ' hide' : '')}>
|
||||||
<div onClick={(e) => this.close(e)} className='modalBack'/>
|
<div onClick={(e) => this.close(e)} className='modalBack' />
|
||||||
{this.state.component == null ? null : (
|
{this.state.component == null ? null : (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<this.state.component {...this.state.componentProps} close={this.close}/>
|
<this.state.component {...this.state.componentProps} close={this.close} />
|
||||||
</Provider>
|
</Provider>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -33,7 +33,7 @@ class ModalBase extends React.Component {
|
|||||||
|
|
||||||
let el = document.createElement('div')
|
let el = document.createElement('div')
|
||||||
document.body.appendChild(el)
|
document.body.appendChild(el)
|
||||||
let modalBase = ReactDOM.render(<ModalBase/>, el)
|
let modalBase = ReactDOM.render(<ModalBase />, el)
|
||||||
|
|
||||||
export function openModal (component, props) {
|
export function openModal (component, props) {
|
||||||
if (modalBase == null) { return }
|
if (modalBase == null) { return }
|
||||||
|
|||||||
@@ -75,24 +75,27 @@ class CreateFolderModal extends React.Component {
|
|||||||
onKeyDown={(e) => this.handleKeyDown(e)}
|
onKeyDown={(e) => this.handleKeyDown(e)}
|
||||||
>
|
>
|
||||||
<div styleName='header'>
|
<div styleName='header'>
|
||||||
<div styleName='title'>New Folder</div>
|
<div styleName='title'>Create new folder</div>
|
||||||
</div>
|
</div>
|
||||||
<button styleName='closeButton'
|
<button styleName='close' onClick={(e) => this.handleCloseButtonClick(e)}>
|
||||||
onClick={(e) => this.handleCloseButtonClick(e)}
|
<div styleName='close-mark'>X</div>
|
||||||
>Close</button>
|
<div styleName='close-text'>esc</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
<div styleName='control'>
|
<div styleName='control'>
|
||||||
<input styleName='control-input'
|
<div styleName='control-folder'>
|
||||||
placeholder='Folder Name'
|
<div styleName='control-folder-label'>Folder name</div>
|
||||||
ref='name'
|
<input styleName='control-folder-input'
|
||||||
value={this.state.name}
|
ref='name'
|
||||||
onChange={(e) => this.handleChange(e)}
|
value={this.state.name}
|
||||||
onKeyDown={(e) => this.handleInputKeyDown(e)}
|
onChange={(e) => this.handleChange(e)}
|
||||||
/>
|
onKeyDown={(e) => this.handleInputKeyDown(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<button styleName='control-confirmButton'
|
<button styleName='control-confirmButton'
|
||||||
onClick={(e) => this.handleConfirmButtonClick(e)}
|
onClick={(e) => this.handleConfirmButtonClick(e)}
|
||||||
>
|
>
|
||||||
Confirm
|
Create Folder
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,47 +1,52 @@
|
|||||||
.root
|
.root
|
||||||
modal()
|
modal()
|
||||||
max-width 340px
|
width 700px
|
||||||
|
height 200px
|
||||||
overflow hidden
|
overflow hidden
|
||||||
position relative
|
position relative
|
||||||
|
padding 0 40px
|
||||||
|
|
||||||
.header
|
.header
|
||||||
height 50px
|
height 50px
|
||||||
|
margin-bottom 10px
|
||||||
|
margin-top 10px
|
||||||
font-size 18px
|
font-size 18px
|
||||||
line-height 50px
|
line-height 50px
|
||||||
padding 0 15px
|
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-backgroundColor
|
||||||
border-bottom solid 1px $ui-borderColor
|
|
||||||
color $ui-text-color
|
color $ui-text-color
|
||||||
|
|
||||||
.closeButton
|
.close-mark
|
||||||
|
font-size 15px
|
||||||
|
|
||||||
|
.close
|
||||||
|
height 50px
|
||||||
position absolute
|
position absolute
|
||||||
top 10px
|
background-color transparent
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
border none
|
||||||
|
top 7px
|
||||||
right 10px
|
right 10px
|
||||||
height 30px
|
|
||||||
width 0 25px
|
|
||||||
border $ui-border
|
|
||||||
border-radius 2px
|
|
||||||
color $ui-text-color
|
|
||||||
colorDefaultButton()
|
|
||||||
|
|
||||||
.control
|
|
||||||
padding 25px 15px 15px
|
|
||||||
text-align center
|
text-align center
|
||||||
|
width top-bar--height
|
||||||
|
height top-bar--height
|
||||||
|
|
||||||
.control-input
|
.control-folder-label
|
||||||
|
text-align left
|
||||||
|
font-size 14px
|
||||||
|
color $ui-text-color
|
||||||
|
|
||||||
|
.control-folder-input
|
||||||
display block
|
display block
|
||||||
height 30px
|
height 30px
|
||||||
width 240px
|
width 620px
|
||||||
padding 0 5px
|
padding 0 5px
|
||||||
margin 0 auto 15px
|
margin 10px auto 15px
|
||||||
border none
|
border 1px solid #C9C9C9 // TODO: use variable.
|
||||||
border-bottom solid 1px $border-color
|
border-radius 5px
|
||||||
border-radius 2px
|
|
||||||
background-color transparent
|
background-color transparent
|
||||||
outline none
|
outline none
|
||||||
vertical-align middle
|
vertical-align middle
|
||||||
font-size 18px
|
font-size 18px
|
||||||
text-align center
|
|
||||||
&:disabled
|
&:disabled
|
||||||
background-color $ui-input--disabled-backgroundColor
|
background-color $ui-input--disabled-backgroundColor
|
||||||
&:focus, &:active
|
&:focus, &:active
|
||||||
@@ -50,21 +55,35 @@
|
|||||||
.control-confirmButton
|
.control-confirmButton
|
||||||
display block
|
display block
|
||||||
height 30px
|
height 30px
|
||||||
|
width 620px
|
||||||
border none
|
border none
|
||||||
border-radius 2px
|
border-radius 5px
|
||||||
padding 0 25px
|
padding 0 25px
|
||||||
margin 0 auto
|
margin 20px auto
|
||||||
|
font-size 14px
|
||||||
colorPrimaryButton()
|
colorPrimaryButton()
|
||||||
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.root
|
.root
|
||||||
modalDark()
|
modalDark()
|
||||||
|
width 700px
|
||||||
|
height 200px
|
||||||
|
overflow hidden
|
||||||
|
position relative
|
||||||
|
padding 0 40px
|
||||||
|
|
||||||
.header
|
.header
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color transparent
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
color $ui-dark-text-color
|
color $ui-dark-text-color
|
||||||
|
|
||||||
|
.control-folder-label
|
||||||
|
color $ui-dark-text-color
|
||||||
|
|
||||||
|
.control-folder-input
|
||||||
|
border 1px solid #C9C9C9 // TODO: use variable.
|
||||||
|
color white
|
||||||
|
|
||||||
.closeButton
|
.closeButton
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
color $ui-dark-text-color
|
color $ui-dark-text-color
|
||||||
@@ -72,8 +91,3 @@ body[data-theme="dark"]
|
|||||||
|
|
||||||
.description
|
.description
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
|
|
||||||
.control-input
|
|
||||||
border-color $ui-dark-borderColor
|
|
||||||
color white
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ export default class DeleteArticleModal extends React.Component {
|
|||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className='DeleteArticleModal modal'>
|
<div className='DeleteArticleModal modal'>
|
||||||
<div className='title'><i className='fa fa-fw fa-trash'/> Delete an article.</div>
|
<div className='title'><i className='fa fa-fw fa-trash' /> Delete an article.</div>
|
||||||
|
|
||||||
<div className='message'>Do you really want to delete?</div>
|
<div className='message'>Do you really want to delete?</div>
|
||||||
|
|
||||||
<div className='control'>
|
<div className='control'>
|
||||||
<button ref='no' onClick={(e) => this.handleNoButtonClick(e)}><i className='fa fa-fw fa-close'/> No</button>
|
<button ref='no' onClick={(e) => this.handleNoButtonClick(e)}><i className='fa fa-fw fa-close' /> No</button>
|
||||||
<button ref='yes' onClick={(e) => this.handleYesButtonClick(e)} className='danger'><i className='fa fa-fw fa-check'/> Yes</button>
|
<button ref='yes' onClick={(e) => this.handleYesButtonClick(e)} className='danger'><i className='fa fa-fw fa-check' /> Yes</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './InitModal.styl'
|
import styles from './InitModal.styl'
|
||||||
import dataApi from 'browser/main/lib/dataApi'
|
import dataApi from 'browser/main/lib/dataApi'
|
||||||
import store from 'browser/main/store'
|
import store from 'browser/main/store'
|
||||||
import { hashHistory } from 'react-router'
|
import { hashHistory } from 'react-router'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import keygen from 'browser/lib/keygen'
|
|
||||||
|
|
||||||
const CSON = require('@rokt33r/season')
|
const CSON = require('@rokt33r/season')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
@@ -197,7 +196,7 @@ class InitModal extends React.Component {
|
|||||||
render () {
|
render () {
|
||||||
if (this.state.isLoading) {
|
if (this.state.isLoading) {
|
||||||
return <div styleName='root--loading'>
|
return <div styleName='root--loading'>
|
||||||
<i styleName='spinner' className='fa fa-spin fa-spinner'/>
|
<i styleName='spinner' className='fa fa-spin fa-spinner' />
|
||||||
<div styleName='loadingMessage'>Preparing initialization...</div>
|
<div styleName='loadingMessage'>Preparing initialization...</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -235,7 +234,7 @@ class InitModal extends React.Component {
|
|||||||
|
|
||||||
{this.state.legacyStorageExists &&
|
{this.state.legacyStorageExists &&
|
||||||
<div styleName='body-migration'>
|
<div styleName='body-migration'>
|
||||||
<label><input type='checkbox' checked={this.state.migrationRequested} onChange={(e) => this.handleMigrationRequestedChange(e)}/> Migrate old data from the legacy app v0.5</label>
|
<label><input type='checkbox' checked={this.state.migrationRequested} onChange={(e) => this.handleMigrationRequestedChange(e)} /> Migrate old data from the legacy app v0.5</label>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +246,7 @@ class InitModal extends React.Component {
|
|||||||
>
|
>
|
||||||
{this.state.isSending
|
{this.state.isSending
|
||||||
? <span>
|
? <span>
|
||||||
<i className='fa fa-spin fa-spinner'/> Loading...
|
<i className='fa fa-spin fa-spinner' /> Loading...
|
||||||
</span>
|
</span>
|
||||||
: 'Let\'s Go!'
|
: 'Let\'s Go!'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './NewNoteModal.styl'
|
import styles from './NewNoteModal.styl'
|
||||||
import dataApi from 'browser/main/lib/dataApi'
|
import dataApi from 'browser/main/lib/dataApi'
|
||||||
@@ -100,7 +100,7 @@ class NewNoteModal extends React.Component {
|
|||||||
onKeyDown={(e) => this.handleKeyDown(e)}
|
onKeyDown={(e) => this.handleKeyDown(e)}
|
||||||
>
|
>
|
||||||
<div styleName='header'>
|
<div styleName='header'>
|
||||||
<div styleName='title'>New Note</div>
|
<div styleName='title'>Make a Note</div>
|
||||||
</div>
|
</div>
|
||||||
<button styleName='closeButton'
|
<button styleName='closeButton'
|
||||||
onClick={(e) => this.handleCloseButtonClick(e)}
|
onClick={(e) => this.handleCloseButtonClick(e)}
|
||||||
@@ -114,8 +114,8 @@ class NewNoteModal extends React.Component {
|
|||||||
>
|
>
|
||||||
<i styleName='control-button-icon'
|
<i styleName='control-button-icon'
|
||||||
className='fa fa-file-text-o'
|
className='fa fa-file-text-o'
|
||||||
/><br/>
|
/><br />
|
||||||
<span styleName='control-button-label'>Markdown Note</span><br/>
|
<span styleName='control-button-label'>Markdown Note</span><br />
|
||||||
<span styleName='control-button-description'>It is good for any type of documents. Check List, Code block and Latex block are available.</span>
|
<span styleName='control-button-description'>It is good for any type of documents. Check List, Code block and Latex block are available.</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -126,14 +126,14 @@ class NewNoteModal extends React.Component {
|
|||||||
>
|
>
|
||||||
<i styleName='control-button-icon'
|
<i styleName='control-button-icon'
|
||||||
className='fa fa-code'
|
className='fa fa-code'
|
||||||
/><br/>
|
/><br />
|
||||||
<span styleName='control-button-label'>Snippet Note</span><br/>
|
<span styleName='control-button-label'>Snippet Note</span><br />
|
||||||
<span styleName='control-button-description'>This format is specialized on managing snippets like Gist. Multiple snippets can be grouped as a note.
|
<span styleName='control-button-description'>This format is specialized on managing snippets like Gist. Multiple snippets can be grouped as a note.
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div styleName='description'><i className='fa fa-arrows-h'/> Tab to switch format</div>
|
<div styleName='description'><i className='fa fa-arrows-h' /> Tab to switch format</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,39 +1,44 @@
|
|||||||
|
@import('./Tab')
|
||||||
|
|
||||||
.root
|
.root
|
||||||
padding 15px
|
padding 15px
|
||||||
color $ui-text-color
|
color $ui-text-color
|
||||||
|
margin-bottom 30px
|
||||||
|
|
||||||
.group
|
.group
|
||||||
margin-bottom 45px
|
margin-bottom 45px
|
||||||
|
|
||||||
.group-header
|
.group-header
|
||||||
font-size 24px
|
@extend .header
|
||||||
color $ui-text-color
|
color $ui-text-color
|
||||||
padding 5px
|
|
||||||
border-bottom $default-border
|
|
||||||
margin-bottom 15px
|
|
||||||
|
|
||||||
.group-header2
|
.group-header2
|
||||||
font-size 18px
|
font-size 20px
|
||||||
color $ui-text-color
|
color $ui-text-color
|
||||||
padding 5px
|
|
||||||
margin-bottom 15px
|
margin-bottom 15px
|
||||||
|
margin-top 30px
|
||||||
|
|
||||||
.group-section
|
.group-section
|
||||||
margin-bottom 15px
|
margin-bottom 20px
|
||||||
display flex
|
display flex
|
||||||
line-height 30px
|
line-height 30px
|
||||||
|
|
||||||
.group-section-label
|
.group-section-label
|
||||||
width 150px
|
width 150px
|
||||||
text-align right
|
text-align left
|
||||||
margin-right 10px
|
margin-right 10px
|
||||||
font-size 14px
|
font-size 14px
|
||||||
|
|
||||||
.group-section-control
|
.group-section-control
|
||||||
flex 1
|
flex 1
|
||||||
|
|
||||||
.group-section-control-input
|
.group-section-control-input
|
||||||
height 30px
|
height 30px
|
||||||
vertical-align middle
|
vertical-align middle
|
||||||
width 150px
|
width 400px
|
||||||
font-size 12px
|
font-size $tab--button-font-size
|
||||||
border solid 1px $border-color
|
border solid 1px $border-color
|
||||||
border-radius 2px
|
border-radius $tab--input-border-radius
|
||||||
padding 0 5px
|
padding 0 5px
|
||||||
&:disabled
|
&:disabled
|
||||||
background-color $ui-input--disabled-backgroundColor
|
background-color $ui-input--disabled-backgroundColor
|
||||||
@@ -45,7 +50,6 @@
|
|||||||
padding-left 15px
|
padding-left 15px
|
||||||
|
|
||||||
.group-control
|
.group-control
|
||||||
border-top $default-border
|
|
||||||
padding-top 10px
|
padding-top 10px
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
height 40px
|
height 40px
|
||||||
@@ -56,22 +60,26 @@
|
|||||||
line-height 30px
|
line-height 30px
|
||||||
padding 0 5px
|
padding 0 5px
|
||||||
float right
|
float right
|
||||||
|
|
||||||
.group-control-leftButton
|
.group-control-leftButton
|
||||||
float left
|
|
||||||
colorDefaultButton()
|
colorDefaultButton()
|
||||||
border $default-border
|
border none
|
||||||
border-radius 2px
|
border-radius 5px
|
||||||
height 30px
|
font-size $tab--button-font-size
|
||||||
|
height $tab--button-height
|
||||||
padding 0 15px
|
padding 0 15px
|
||||||
margin-right 5px
|
margin-right 10px
|
||||||
|
|
||||||
.group-control-rightButton
|
.group-control-rightButton
|
||||||
float right
|
float right
|
||||||
colorPrimaryButton()
|
colorPrimaryButton()
|
||||||
border none
|
border none
|
||||||
border-radius 2px
|
border-radius $tab--button-border-radius
|
||||||
height 30px
|
font-size $tab--button-font-size
|
||||||
|
height $tab--button-height
|
||||||
padding 0 15px
|
padding 0 15px
|
||||||
margin-right 5px
|
margin-right 10px
|
||||||
|
|
||||||
.group-hint
|
.group-hint
|
||||||
border $ui-border
|
border $ui-border
|
||||||
padding 10px 15px
|
padding 10px 15px
|
||||||
@@ -86,6 +94,14 @@
|
|||||||
p
|
p
|
||||||
line-height 1.2
|
line-height 1.2
|
||||||
|
|
||||||
|
.note-for-keymap
|
||||||
|
margin-left: 10px
|
||||||
|
font-size: 12px
|
||||||
|
|
||||||
|
colorDarkControl()
|
||||||
|
border-color $ui-dark-borderColor
|
||||||
|
background-color $ui-dark-backgroundColor
|
||||||
|
color $ui-dark-text-color
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.root
|
.root
|
||||||
color $ui-dark-text-color
|
color $ui-dark-text-color
|
||||||
@@ -108,6 +124,7 @@ body[data-theme="dark"]
|
|||||||
.group-control-rightButton
|
.group-control-rightButton
|
||||||
colorDarkPrimaryButton()
|
colorDarkPrimaryButton()
|
||||||
.group-hint
|
.group-hint
|
||||||
border-color $ui-dark-borderColor
|
colorDarkControl()
|
||||||
background-color $ui-dark-backgroundColor
|
.group-section-control
|
||||||
color $ui-dark-text-color
|
select, .group-section-control-input
|
||||||
|
colorDarkControl()
|
||||||
|
|||||||
154
browser/main/modals/PreferencesModal/HotkeyTab.js
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './ConfigTab.styl'
|
||||||
|
import ConfigManager from 'browser/main/lib/ConfigManager'
|
||||||
|
import store from 'browser/main/store'
|
||||||
|
|
||||||
|
const electron = require('electron')
|
||||||
|
const ipc = electron.ipcRenderer
|
||||||
|
|
||||||
|
class HotkeyTab extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
isHotkeyHintOpen: false,
|
||||||
|
config: props.config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
this.handleSettingDone = () => {
|
||||||
|
this.setState({keymapAlert: {
|
||||||
|
type: 'success',
|
||||||
|
message: 'Successfully applied!'
|
||||||
|
}})
|
||||||
|
}
|
||||||
|
this.handleSettingError = (err) => {
|
||||||
|
this.setState({keymapAlert: {
|
||||||
|
type: 'error',
|
||||||
|
message: err.message != null ? err.message : 'Error occurs!'
|
||||||
|
}})
|
||||||
|
}
|
||||||
|
ipc.addListener('APP_SETTING_DONE', this.handleSettingDone)
|
||||||
|
ipc.addListener('APP_SETTING_ERROR', this.handleSettingError)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
ipc.removeListener('APP_SETTING_DONE', this.handleSettingDone)
|
||||||
|
ipc.removeListener('APP_SETTING_ERROR', this.handleSettingError)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSaveButtonClick (e) {
|
||||||
|
let newConfig = {
|
||||||
|
hotkey: this.state.config.hotkey
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigManager.set(newConfig)
|
||||||
|
|
||||||
|
store.dispatch({
|
||||||
|
type: 'SET_UI',
|
||||||
|
config: newConfig
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleHintToggleButtonClick (e) {
|
||||||
|
this.setState({
|
||||||
|
isHotkeyHintOpen: !this.state.isHotkeyHintOpen
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleHotkeyChange (e) {
|
||||||
|
let { config } = this.state
|
||||||
|
config.hotkey = {
|
||||||
|
toggleFinder: this.refs.toggleFinder.value,
|
||||||
|
toggleMain: this.refs.toggleMain.value
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
config
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
let keymapAlert = this.state.keymapAlert
|
||||||
|
let keymapAlertElement = keymapAlert != null
|
||||||
|
? <p className={`alert ${keymapAlert.type}`}>
|
||||||
|
{keymapAlert.message}
|
||||||
|
</p>
|
||||||
|
: null
|
||||||
|
let { config } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div styleName='root'>
|
||||||
|
<div styleName='group'>
|
||||||
|
<div styleName='group-header'>Hotkey</div>
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>Toggle Main</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input styleName='group-section-control-input'
|
||||||
|
onChange={(e) => this.handleHotkeyChange(e)}
|
||||||
|
ref='toggleMain'
|
||||||
|
value={config.hotkey.toggleMain}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>Toggle Finder(popup)</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input styleName='group-section-control-input'
|
||||||
|
onChange={(e) => this.handleHotkeyChange(e)}
|
||||||
|
ref='toggleFinder'
|
||||||
|
value={config.hotkey.toggleFinder}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div styleName='group-control'>
|
||||||
|
<button styleName='group-control-leftButton'
|
||||||
|
onClick={(e) => this.handleHintToggleButtonClick(e)}
|
||||||
|
>
|
||||||
|
{this.state.isHotkeyHintOpen
|
||||||
|
? 'Hide Hint'
|
||||||
|
: 'Hint?'
|
||||||
|
}
|
||||||
|
</button>
|
||||||
|
<button styleName='group-control-rightButton'
|
||||||
|
onClick={(e) => this.handleSaveButtonClick(e)}>Save
|
||||||
|
</button>
|
||||||
|
{keymapAlertElement}
|
||||||
|
</div>
|
||||||
|
{this.state.isHotkeyHintOpen &&
|
||||||
|
<div styleName='group-hint'>
|
||||||
|
<p>Available Keys</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>0</code> to <code>9</code></li>
|
||||||
|
<li><code>A</code> to <code>Z</code></li>
|
||||||
|
<li><code>F1</code> to <code>F24</code></li>
|
||||||
|
<li>Punctuations like <code>~</code>, <code>!</code>, <code>@</code>, <code>#</code>, <code>$</code>, etc.</li>
|
||||||
|
<li><code>Plus</code></li>
|
||||||
|
<li><code>Space</code></li>
|
||||||
|
<li><code>Backspace</code></li>
|
||||||
|
<li><code>Delete</code></li>
|
||||||
|
<li><code>Insert</code></li>
|
||||||
|
<li><code>Return</code> (or <code>Enter</code> as alias)</li>
|
||||||
|
<li><code>Up</code>, <code>Down</code>, <code>Left</code> and <code>Right</code></li>
|
||||||
|
<li><code>Home</code> and <code>End</code></li>
|
||||||
|
<li><code>PageUp</code> and <code>PageDown</code></li>
|
||||||
|
<li><code>Escape</code> (or <code>Esc</code> for short)</li>
|
||||||
|
<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>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HotkeyTab.propTypes = {
|
||||||
|
dispatch: PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(HotkeyTab, styles)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './InfoTab.styl'
|
import styles from './InfoTab.styl'
|
||||||
|
|
||||||
@@ -22,17 +22,24 @@ class InfoTab extends React.Component {
|
|||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div styleName='root'>
|
<div styleName='root'>
|
||||||
|
<div styleName='header'>Info</div>
|
||||||
|
|
||||||
<div styleName='top'>
|
<div styleName='top'>
|
||||||
<img styleName='icon' src='../resources/app.png' width='150' height='150'/>
|
<div styleName='icon-space'>
|
||||||
<div styleName='appId'>Boostnote {appVersion}</div>
|
<img styleName='icon' src='../resources/app.png' width='92' height='92' />
|
||||||
<div styleName='description'>
|
<div styleName='icon-right'>
|
||||||
A simple markdown/snippet note app for developer.
|
<div styleName='appId'>Boostnote {appVersion}</div>
|
||||||
|
<div styleName='description'>
|
||||||
|
A simple markdown/snippet note app for developer.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div styleName='clear' />
|
||||||
<div styleName='madeBy'>Made by
|
<div styleName='madeBy'>Made by
|
||||||
<a href='http://maisin.co/'
|
<a href='http://maisin.co/'
|
||||||
onClick={(e) => this.handleLinkClick(e)}
|
onClick={(e) => this.handleLinkClick(e)}
|
||||||
>MAISIN&CO.</a></div>
|
>MAISIN&CO.</a></div>
|
||||||
<div styleName='copyright'>Copyright 2016 MAISIN&CO. All rights reserved.</div>
|
<div styleName='copyright'>Copyright 2017 MAISIN&CO. All rights reserved.</div>
|
||||||
</div>
|
</div>
|
||||||
<ul styleName='list'>
|
<ul styleName='list'>
|
||||||
<li>
|
<li>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@import('./Tab')
|
||||||
|
|
||||||
.root
|
.root
|
||||||
padding 15px
|
padding 15px
|
||||||
white-space pre
|
white-space pre
|
||||||
@@ -5,27 +7,39 @@
|
|||||||
color $ui-text-color
|
color $ui-text-color
|
||||||
width 100%
|
width 100%
|
||||||
|
|
||||||
|
.clear
|
||||||
|
clear both
|
||||||
|
|
||||||
.top
|
.top
|
||||||
text-align center
|
text-align left
|
||||||
margin-bottom 25px
|
margin-bottom 20px
|
||||||
|
|
||||||
|
.icon-space
|
||||||
|
margin 20px 0
|
||||||
|
height 100px
|
||||||
|
|
||||||
|
.icon
|
||||||
|
display inline-block
|
||||||
|
vertical-align middle
|
||||||
|
|
||||||
|
.icon-right
|
||||||
|
display inline-block
|
||||||
|
vertical-align middle
|
||||||
|
margin-left 20px
|
||||||
|
|
||||||
.appId
|
.appId
|
||||||
font-size 24px
|
font-size 24px
|
||||||
|
margin-bottom 13px
|
||||||
|
|
||||||
.description
|
.description
|
||||||
overflow hidden
|
|
||||||
white-space normal
|
|
||||||
line-height 1.5
|
|
||||||
margin 5px auto 10px
|
|
||||||
font-size 14px
|
font-size 14px
|
||||||
text-align center
|
|
||||||
|
|
||||||
.madeBy
|
.madeBy
|
||||||
font-size 12px
|
font-size 14px
|
||||||
$ui-inactive-text-color
|
$ui-inactive-text-color
|
||||||
|
|
||||||
.copyright
|
.copyright
|
||||||
font-size 12px
|
font-size 14px
|
||||||
$ui-inactive-text-color
|
$ui-inactive-text-color
|
||||||
|
|
||||||
.list
|
.list
|
||||||
@@ -36,7 +50,7 @@
|
|||||||
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.root
|
.root
|
||||||
color $ui-dark-text-color
|
color $tab--dark-text-color
|
||||||
|
|
||||||
.madeBy
|
.madeBy
|
||||||
color $ui-dark-inactive-text-color
|
color $ui-dark-inactive-text-color
|
||||||
|
|||||||
@@ -1,51 +1,93 @@
|
|||||||
|
@import('./Tab')
|
||||||
|
|
||||||
|
top-bar--height = 50px
|
||||||
|
|
||||||
.root
|
.root
|
||||||
modal()
|
modal()
|
||||||
max-width 540px
|
max-width 800px
|
||||||
min-height 400px
|
min-height 500px
|
||||||
height 80%
|
height 80%
|
||||||
overflow hidden
|
overflow hidden
|
||||||
position relative
|
position relative
|
||||||
|
|
||||||
.nav
|
.top-bar
|
||||||
absolute top left right
|
absolute top left right
|
||||||
height 50px
|
height top-bar--height
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-backgroundColor
|
||||||
border-bottom solid 1px $ui-borderColor
|
border-bottom solid 1px $ui-borderColor
|
||||||
|
p
|
||||||
|
text-align center
|
||||||
|
font-size 18px
|
||||||
|
line-height top-bar--height
|
||||||
|
|
||||||
|
.top-bar-close
|
||||||
|
position absolute
|
||||||
|
background-color transparent
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
border none
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
text-align center
|
||||||
|
width top-bar--height
|
||||||
|
height top-bar--height
|
||||||
|
|
||||||
|
.nav
|
||||||
|
absolute top left right
|
||||||
|
top top-bar--height
|
||||||
|
left 0
|
||||||
|
width 140px
|
||||||
|
margin-left 30px
|
||||||
|
margin-top 20px
|
||||||
|
background-color $ui-backgroundColor
|
||||||
|
|
||||||
.nav-button
|
.nav-button
|
||||||
width 80px
|
font-size 14px
|
||||||
height 50px
|
text-align left
|
||||||
|
width 100px
|
||||||
|
margin 4px 0
|
||||||
|
padding 7px 0
|
||||||
|
padding-left 7px
|
||||||
border none
|
border none
|
||||||
|
border-radius 3px
|
||||||
background-color transparent
|
background-color transparent
|
||||||
color #939395
|
color $ui-text-color
|
||||||
font-size 14px
|
font-size 14px
|
||||||
&:hover
|
&:hover
|
||||||
color #515151
|
color $ui-active-color
|
||||||
|
|
||||||
.nav-button--active
|
.nav-button--active
|
||||||
@extend .nav-button
|
@extend .nav-button
|
||||||
color #6AA5E9
|
color white
|
||||||
|
background-color $ui-active-color
|
||||||
&:hover
|
&:hover
|
||||||
color #6AA5E9
|
color white
|
||||||
|
|
||||||
.nav-button-icon
|
.nav-button-icon
|
||||||
display block
|
display block
|
||||||
|
|
||||||
.content
|
.content
|
||||||
absolute left right bottom
|
absolute left right bottom
|
||||||
top 50px
|
top top-bar--height
|
||||||
|
left 140px
|
||||||
|
margin-top 10px
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
|
|
||||||
body[data-theme="dark"]
|
body[data-theme="dark"]
|
||||||
.root
|
.root
|
||||||
modalDark()
|
modalDark()
|
||||||
|
|
||||||
|
.top-bar
|
||||||
|
background-color transparent
|
||||||
|
border-color #4A4D52
|
||||||
|
p
|
||||||
|
color $tab--dark-text-color
|
||||||
|
|
||||||
.nav
|
.nav
|
||||||
background-color $ui-dark-button--hover-backgroundColor
|
background-color transparent
|
||||||
border-color $ui-dark-borderColor
|
border-color $ui-dark-borderColor
|
||||||
|
|
||||||
.nav-button
|
.nav-button
|
||||||
background-color transparent
|
background-color transparent
|
||||||
color #939395
|
color $tab--dark-text-color
|
||||||
&:hover
|
&:hover
|
||||||
color $ui-dark-text-color
|
color $ui-dark-text-color
|
||||||
|
|||||||
@@ -106,7 +106,10 @@ class UnstyledFolderItem extends React.Component {
|
|||||||
const popover = { position: 'absolute', zIndex: 2 }
|
const popover = { position: 'absolute', zIndex: 2 }
|
||||||
const cover = {
|
const cover = {
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
top: 0, right: 0, bottom: 0, left: 0
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
left: 0
|
||||||
}
|
}
|
||||||
const pickerStyle = Object.assign({}, {
|
const pickerStyle = Object.assign({}, {
|
||||||
position: 'absolute'
|
position: 'absolute'
|
||||||
@@ -137,7 +140,7 @@ class UnstyledFolderItem extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
<i className='fa fa-square'/>
|
<i className='fa fa-square' />
|
||||||
</button>
|
</button>
|
||||||
<input styleName='folderList-item-left-nameInput'
|
<input styleName='folderList-item-left-nameInput'
|
||||||
value={this.state.folder.name}
|
value={this.state.folder.name}
|
||||||
@@ -300,10 +303,10 @@ class StorageItem extends React.Component {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
let { storage, dispatch } = this.props
|
let { storage } = this.props
|
||||||
dataApi.removeStorage(storage.key)
|
dataApi.removeStorage(storage.key)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
dispatch({
|
store.dispatch({
|
||||||
type: 'REMOVE_STORAGE',
|
type: 'REMOVE_STORAGE',
|
||||||
storageKey: storage.key
|
storageKey: storage.key
|
||||||
})
|
})
|
||||||
@@ -368,17 +371,17 @@ class StorageItem extends React.Component {
|
|||||||
: <div styleName='header-label'
|
: <div styleName='header-label'
|
||||||
onClick={(e) => this.handleLabelClick(e)}
|
onClick={(e) => this.handleLabelClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-folder-open'/>
|
<i className='fa fa-folder-open' />
|
||||||
{storage.name}
|
{storage.name}
|
||||||
<span styleName='header-label-path'>({storage.path})</span>
|
<span styleName='header-label-path'>({storage.path})</span>
|
||||||
<i styleName='header-label-editButton' className='fa fa-pencil'/>
|
<i styleName='header-label-editButton' className='fa fa-pencil' />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div styleName='header-control'>
|
<div styleName='header-control'>
|
||||||
<button styleName='header-control-button'
|
<button styleName='header-control-button'
|
||||||
onClick={(e) => this.handleNewFolderButtonClick(e)}
|
onClick={(e) => this.handleNewFolderButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-plus'/>
|
<i className='fa fa-plus' />
|
||||||
<span styleName='header-control-button-tooltip'
|
<span styleName='header-control-button-tooltip'
|
||||||
style={{left: -20}}
|
style={{left: -20}}
|
||||||
>Add Folder</span>
|
>Add Folder</span>
|
||||||
@@ -386,7 +389,7 @@ class StorageItem extends React.Component {
|
|||||||
<button styleName='header-control-button'
|
<button styleName='header-control-button'
|
||||||
onClick={(e) => this.handleExternalButtonClick(e)}
|
onClick={(e) => this.handleExternalButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-external-link'/>
|
<i className='fa fa-external-link' />
|
||||||
<span styleName='header-control-button-tooltip'
|
<span styleName='header-control-button-tooltip'
|
||||||
style={{left: -50}}
|
style={{left: -50}}
|
||||||
>Open Storage folder</span>
|
>Open Storage folder</span>
|
||||||
@@ -394,7 +397,7 @@ class StorageItem extends React.Component {
|
|||||||
<button styleName='header-control-button'
|
<button styleName='header-control-button'
|
||||||
onClick={(e) => this.handleUnlinkButtonClick(e)}
|
onClick={(e) => this.handleUnlinkButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-unlink'/>
|
<i className='fa fa-unlink' />
|
||||||
<span styleName='header-control-button-tooltip'
|
<span styleName='header-control-button-tooltip'
|
||||||
style={{left: -10}}
|
style={{left: -10}}
|
||||||
>Unlink</span>
|
>Unlink</span>
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class StoragesTab extends React.Component {
|
|||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
<div styleName='list'>
|
<div styleName='list'>
|
||||||
|
<div styleName='header'>Storages</div>
|
||||||
{storageList.length > 0
|
{storageList.length > 0
|
||||||
? storageList
|
? storageList
|
||||||
: <div styleName='list-empty'>No storage found.</div>
|
: <div styleName='list-empty'>No storage found.</div>
|
||||||
@@ -71,7 +72,7 @@ class StoragesTab extends React.Component {
|
|||||||
<button styleName='list-control-addStorageButton'
|
<button styleName='list-control-addStorageButton'
|
||||||
onClick={(e) => this.handleAddStorageButton(e)}
|
onClick={(e) => this.handleAddStorageButton(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-plus'/> Add Storage
|
<i className='fa fa-plus' /> Add Storage
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@import('./Tab')
|
||||||
|
|
||||||
.root
|
.root
|
||||||
padding 15px
|
padding 15px
|
||||||
color $ui-text-color
|
color $ui-text-color
|
||||||
@@ -26,11 +28,12 @@
|
|||||||
.list-control
|
.list-control
|
||||||
height 30px
|
height 30px
|
||||||
.list-control-addStorageButton
|
.list-control-addStorageButton
|
||||||
height 30px
|
height $tab--button-height
|
||||||
padding 0 15px
|
padding 0 15px
|
||||||
border $ui-border
|
border $ui-border
|
||||||
colorDefaultButton()
|
colorDefaultButton()
|
||||||
border-radius 2px
|
font-size $tab--button-font-size
|
||||||
|
border-radius $tab--button-border-radius
|
||||||
|
|
||||||
.addStorage
|
.addStorage
|
||||||
margin-bottom 15px
|
margin-bottom 15px
|
||||||
|
|||||||
18
browser/main/modals/PreferencesModal/Tab.styl
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Common style for tabs on config modal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$tab--input-border-radius = 5px
|
||||||
|
$tab--button-border-radius = 5px
|
||||||
|
$tab--button-height = 40px
|
||||||
|
$tab--button-font-size = 14px
|
||||||
|
|
||||||
|
$tab--dark-text-color = #E5E5E5
|
||||||
|
|
||||||
|
.header
|
||||||
|
font-size 24px
|
||||||
|
margin-bottom 30px
|
||||||
|
|
||||||
|
body[data-theme="dark"]
|
||||||
|
.header
|
||||||
|
color $tab--dark-text-color
|
||||||
@@ -1,107 +1,21 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './ConfigTab.styl'
|
import styles from './ConfigTab.styl'
|
||||||
import hljsTheme from 'browser/lib/hljsThemes'
|
|
||||||
import ConfigManager from 'browser/main/lib/ConfigManager'
|
import ConfigManager from 'browser/main/lib/ConfigManager'
|
||||||
import store from 'browser/main/store'
|
import store from 'browser/main/store'
|
||||||
import consts from 'browser/lib/consts'
|
import consts from 'browser/lib/consts'
|
||||||
|
|
||||||
const electron = require('electron')
|
|
||||||
const ipc = electron.ipcRenderer
|
|
||||||
|
|
||||||
const OSX = global.process.platform === 'darwin'
|
const OSX = global.process.platform === 'darwin'
|
||||||
|
|
||||||
class ConfigTab extends React.Component {
|
class UiTab extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
isHotkeyHintOpen: false,
|
|
||||||
config: props.config
|
config: props.config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
|
||||||
this.handleSettingDone = () => {
|
|
||||||
this.setState({keymapAlert: {
|
|
||||||
type: 'success',
|
|
||||||
message: 'Successfully applied!'
|
|
||||||
}})
|
|
||||||
}
|
|
||||||
this.handleSettingError = (err) => {
|
|
||||||
this.setState({keymapAlert: {
|
|
||||||
type: 'error',
|
|
||||||
message: err.message != null ? err.message : 'Error occurs!'
|
|
||||||
}})
|
|
||||||
}
|
|
||||||
ipc.addListener('APP_SETTING_DONE', this.handleSettingDone)
|
|
||||||
ipc.addListener('APP_SETTING_ERROR', this.handleSettingError)
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount () {
|
|
||||||
ipc.removeListener('APP_SETTING_DONE', this.handleSettingDone)
|
|
||||||
ipc.removeListener('APP_SETTING_ERROR', this.handleSettingError)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSaveButtonClick (e) {
|
|
||||||
let newConfig = {
|
|
||||||
hotkey: this.state.config.hotkey
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigManager.set(newConfig)
|
|
||||||
|
|
||||||
store.dispatch({
|
|
||||||
type: 'SET_UI',
|
|
||||||
config: newConfig
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleKeyDown (e) {
|
|
||||||
if (e.keyCode === 13) {
|
|
||||||
this.submitHotKey()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleConfigKeyDown (e) {
|
|
||||||
if (e.keyCode === 13) {
|
|
||||||
this.submitConfig()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleLineNumberingClick (e) {
|
|
||||||
let config = this.state.config
|
|
||||||
|
|
||||||
config['preview-line-number'] = e.target.checked
|
|
||||||
this.setState({
|
|
||||||
config
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDisableDirectWriteClick (e) {
|
|
||||||
let config = this.state.config
|
|
||||||
config['disable-direct-write'] = e.target.checked
|
|
||||||
this.setState({
|
|
||||||
config
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleHintToggleButtonClick (e) {
|
|
||||||
this.setState({
|
|
||||||
isHotkeyHintOpen: !this.state.isHotkeyHintOpen
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleHotkeyChange (e) {
|
|
||||||
let { config } = this.state
|
|
||||||
config.hotkey = {
|
|
||||||
toggleFinder: this.refs.toggleFinder.value,
|
|
||||||
toggleMain: this.refs.toggleMain.value
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
config
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleUIChange (e) {
|
handleUIChange (e) {
|
||||||
let { config } = this.state
|
let { config } = this.state
|
||||||
|
|
||||||
@@ -117,7 +31,8 @@ class ConfigTab extends React.Component {
|
|||||||
fontFamily: this.refs.editorFontFamily.value,
|
fontFamily: this.refs.editorFontFamily.value,
|
||||||
indentType: this.refs.editorIndentType.value,
|
indentType: this.refs.editorIndentType.value,
|
||||||
indentSize: this.refs.editorIndentSize.value,
|
indentSize: this.refs.editorIndentSize.value,
|
||||||
switchPreview: this.refs.editorSwitchPreview.value
|
switchPreview: this.refs.editorSwitchPreview.value,
|
||||||
|
keyMap: this.refs.editorKeyMap.value
|
||||||
}
|
}
|
||||||
config.preview = {
|
config.preview = {
|
||||||
fontSize: this.refs.previewFontSize.value,
|
fontSize: this.refs.previewFontSize.value,
|
||||||
@@ -126,13 +41,11 @@ class ConfigTab extends React.Component {
|
|||||||
lineNumber: this.refs.previewLineNumber.checked
|
lineNumber: this.refs.previewLineNumber.checked
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({ config })
|
||||||
config
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSaveUIClick (e) {
|
handleSaveUIClick (e) {
|
||||||
let newConfig = {
|
const newConfig = {
|
||||||
ui: this.state.config.ui,
|
ui: this.state.config.ui,
|
||||||
editor: this.state.config.editor,
|
editor: this.state.config.editor,
|
||||||
preview: this.state.config.preview
|
preview: this.state.config.preview
|
||||||
@@ -147,85 +60,17 @@ class ConfigTab extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
let keymapAlert = this.state.keymapAlert
|
const themes = consts.THEMES
|
||||||
let keymapAlertElement = keymapAlert != null
|
const { config } = this.state
|
||||||
? <p className={`alert ${keymapAlert.type}`}>
|
|
||||||
{keymapAlert.message}
|
|
||||||
</p>
|
|
||||||
: null
|
|
||||||
let themes = consts.THEMES
|
|
||||||
let hljsThemeList = hljsTheme()
|
|
||||||
let { config } = this.state
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div styleName='root'>
|
<div styleName='root'>
|
||||||
<div styleName='group'>
|
|
||||||
<div styleName='group-header'>Hotkey</div>
|
|
||||||
<div styleName='group-section'>
|
|
||||||
<div styleName='group-section-label'>Toggle Main</div>
|
|
||||||
<div styleName='group-section-control'>
|
|
||||||
<input styleName='group-section-control-input'
|
|
||||||
onChange={(e) => this.handleHotkeyChange(e)}
|
|
||||||
ref='toggleMain'
|
|
||||||
value={config.hotkey.toggleMain}
|
|
||||||
type='text'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div styleName='group-section'>
|
|
||||||
<div styleName='group-section-label'>Toggle Finder(popup)</div>
|
|
||||||
<div styleName='group-section-control'>
|
|
||||||
<input styleName='group-section-control-input'
|
|
||||||
onChange={(e) => this.handleHotkeyChange(e)}
|
|
||||||
ref='toggleFinder'
|
|
||||||
value={config.hotkey.toggleFinder}
|
|
||||||
type='text'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div styleName='group-control'>
|
|
||||||
<button styleName='group-control-leftButton'
|
|
||||||
onClick={(e) => this.handleHintToggleButtonClick(e)}
|
|
||||||
>
|
|
||||||
{this.state.isHotkeyHintOpen
|
|
||||||
? 'Hide Hint'
|
|
||||||
: 'Show Hint'
|
|
||||||
}
|
|
||||||
</button>
|
|
||||||
<button styleName='group-control-rightButton'
|
|
||||||
onClick={(e) => this.handleSaveButtonClick(e)}>Save Hotkey
|
|
||||||
</button>
|
|
||||||
{keymapAlertElement}
|
|
||||||
</div>
|
|
||||||
{this.state.isHotkeyHintOpen &&
|
|
||||||
<div styleName='group-hint'>
|
|
||||||
<p>Available Keys</p>
|
|
||||||
<ul>
|
|
||||||
<li><code>0</code> to <code>9</code></li>
|
|
||||||
<li><code>A</code> to <code>Z</code></li>
|
|
||||||
<li><code>F1</code> to <code>F24</code></li>
|
|
||||||
<li>Punctuations like <code>~</code>, <code>!</code>, <code>@</code>, <code>#</code>, <code>$</code>, etc.</li>
|
|
||||||
<li><code>Plus</code></li>
|
|
||||||
<li><code>Space</code></li>
|
|
||||||
<li><code>Backspace</code></li>
|
|
||||||
<li><code>Delete</code></li>
|
|
||||||
<li><code>Insert</code></li>
|
|
||||||
<li><code>Return</code> (or <code>Enter</code> as alias)</li>
|
|
||||||
<li><code>Up</code>, <code>Down</code>, <code>Left</code> and <code>Right</code></li>
|
|
||||||
<li><code>Home</code> and <code>End</code></li>
|
|
||||||
<li><code>PageUp</code> and <code>PageDown</code></li>
|
|
||||||
<li><code>Escape</code> (or <code>Esc</code> for short)</li>
|
|
||||||
<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>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div styleName='group'>
|
<div styleName='group'>
|
||||||
<div styleName='group-header'>UI</div>
|
<div styleName='group-header'>UI</div>
|
||||||
|
|
||||||
|
<div styleName='group-header2'>Theme</div>
|
||||||
|
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>Theme</div>
|
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<select value={config.ui.theme}
|
<select value={config.ui.theme}
|
||||||
onChange={(e) => this.handleUIChange(e)}
|
onChange={(e) => this.handleUIChange(e)}
|
||||||
@@ -334,6 +179,23 @@ class ConfigTab extends React.Component {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>
|
||||||
|
Editor Keymap
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<select value={config.editor.keyMap}
|
||||||
|
ref='editorKeyMap'
|
||||||
|
onChange={(e) => this.handleUIChange(e)}
|
||||||
|
>
|
||||||
|
<option value='sublime'>default</option>
|
||||||
|
<option value='vim'>vim</option>
|
||||||
|
</select>
|
||||||
|
<span styleName='note-for-keymap'>Please reload boostnote after you change the keymap</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div styleName='group-header2'>Preview</div>
|
<div styleName='group-header2'>Preview</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
@@ -369,8 +231,8 @@ class ConfigTab extends React.Component {
|
|||||||
onChange={(e) => this.handleUIChange(e)}
|
onChange={(e) => this.handleUIChange(e)}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
hljsThemeList.map((theme) => {
|
themes.map((theme) => {
|
||||||
return (<option value={theme.name} key={theme.name}>{theme.caption}</option>)
|
return (<option value={theme} key={theme}>{theme}</option>)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
@@ -400,11 +262,11 @@ class ConfigTab extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigTab.propTypes = {
|
UiTab.propTypes = {
|
||||||
user: PropTypes.shape({
|
user: PropTypes.shape({
|
||||||
name: PropTypes.string
|
name: PropTypes.string
|
||||||
}),
|
}),
|
||||||
dispatch: PropTypes.func
|
dispatch: PropTypes.func
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CSSModules(ConfigTab, styles)
|
export default CSSModules(UiTab, styles)
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import ConfigTab from './ConfigTab'
|
import HotkeyTab from './HotkeyTab'
|
||||||
|
import UiTab from './UiTab'
|
||||||
import InfoTab from './InfoTab'
|
import InfoTab from './InfoTab'
|
||||||
import StoragesTab from './StoragesTab'
|
import StoragesTab from './StoragesTab'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
@@ -32,16 +33,27 @@ class Preferences extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleEscButtonClick () {
|
||||||
|
this.props.close()
|
||||||
|
}
|
||||||
|
|
||||||
renderContent () {
|
renderContent () {
|
||||||
const { boundingBox } = this.state
|
const { boundingBox } = this.state
|
||||||
let { dispatch, config, data } = this.props
|
let { dispatch, config, data } = this.props
|
||||||
|
|
||||||
switch (this.state.currentTab) {
|
switch (this.state.currentTab) {
|
||||||
case 'INFO':
|
case 'INFO':
|
||||||
return <InfoTab/>
|
return <InfoTab />
|
||||||
case 'CONFIG':
|
case 'HOTKEY':
|
||||||
return (
|
return (
|
||||||
<ConfigTab
|
<HotkeyTab
|
||||||
|
dispatch={dispatch}
|
||||||
|
config={config}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case 'UI':
|
||||||
|
return (
|
||||||
|
<UiTab
|
||||||
dispatch={dispatch}
|
dispatch={dispatch}
|
||||||
config={config}
|
config={config}
|
||||||
/>
|
/>
|
||||||
@@ -73,9 +85,10 @@ class Preferences extends React.Component {
|
|||||||
let content = this.renderContent()
|
let content = this.renderContent()
|
||||||
|
|
||||||
let tabs = [
|
let tabs = [
|
||||||
{target: 'STORAGES', label: 'Storages', icon: 'database'},
|
{target: 'STORAGES', label: 'Storages'},
|
||||||
{target: 'CONFIG', label: 'Config', icon: 'cogs'},
|
{target: 'HOTKEY', label: 'Hotkey'},
|
||||||
{target: 'INFO', label: 'Info', icon: 'info-circle'}
|
{target: 'UI', label: 'UI'},
|
||||||
|
{target: 'INFO', label: 'Info'}
|
||||||
]
|
]
|
||||||
|
|
||||||
let navButtons = tabs.map((tab) => {
|
let navButtons = tabs.map((tab) => {
|
||||||
@@ -88,9 +101,6 @@ class Preferences extends React.Component {
|
|||||||
key={tab.target}
|
key={tab.target}
|
||||||
onClick={(e) => this.handleNavButtonClick(tab.target)(e)}
|
onClick={(e) => this.handleNavButtonClick(tab.target)(e)}
|
||||||
>
|
>
|
||||||
<i styleName='nav-button-icon'
|
|
||||||
className={'fa fa-' + tab.icon}
|
|
||||||
/>
|
|
||||||
<span styleName='nav-button-label'>
|
<span styleName='nav-button-label'>
|
||||||
{tab.label}
|
{tab.label}
|
||||||
</span>
|
</span>
|
||||||
@@ -104,6 +114,13 @@ class Preferences extends React.Component {
|
|||||||
tabIndex='-1'
|
tabIndex='-1'
|
||||||
onKeyDown={(e) => this.handleKeyDown(e)}
|
onKeyDown={(e) => this.handleKeyDown(e)}
|
||||||
>
|
>
|
||||||
|
<div styleName='top-bar'>
|
||||||
|
<p>Your menu for Boostnote</p>
|
||||||
|
</div>
|
||||||
|
<button styleName='top-bar-close' onClick={(e) => this.handleEscButtonClick(e)}>
|
||||||
|
<div styleName='top-bar-close-mark'>X</div>
|
||||||
|
<div styleName='top-bar-close-text'>esc</div>
|
||||||
|
</button>
|
||||||
<div styleName='nav'>
|
<div styleName='nav'>
|
||||||
{navButtons}
|
{navButtons}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,15 +8,18 @@ $danger-lighten-color = lighten(#c9302c, 5%)
|
|||||||
$statusBar-height = 24px
|
$statusBar-height = 24px
|
||||||
$sideNav-width = 200px
|
$sideNav-width = 200px
|
||||||
$sideNav--folded-width = 44px
|
$sideNav--folded-width = 44px
|
||||||
$topBar-height = 50px
|
$topBar-height = 60px
|
||||||
|
|
||||||
// UI default
|
// UI default
|
||||||
$ui-text-color = #515151
|
$ui-text-color = #515151
|
||||||
$ui-inactive-text-color = #939395
|
$ui-inactive-text-color = #939395
|
||||||
$ui-borderColor = #D1D1D1
|
$ui-borderColor = #D1D1D1
|
||||||
$ui-backgroundColor = #FAFAFA
|
$ui-backgroundColor = #FFFFFF
|
||||||
|
$ui-noteList-backgroundColor = #F3F3F3
|
||||||
|
$ui-noteDetail-backgroundColor = #F4F4F4
|
||||||
$ui-border = solid 1px $ui-borderColor
|
$ui-border = solid 1px $ui-borderColor
|
||||||
$ui-active-color = #6AA5E9
|
$ui-active-color = #6AA5E9
|
||||||
|
$ui-tag-backgroundColor = rgba(0, 0, 0, 0.3)
|
||||||
|
|
||||||
// UI Button
|
// UI Button
|
||||||
$ui-button-color = #939395
|
$ui-button-color = #939395
|
||||||
@@ -44,6 +47,9 @@ tooltip()
|
|||||||
$ui-input--focus-borderColor = #369DCD
|
$ui-input--focus-borderColor = #369DCD
|
||||||
$ui-input--disabled-backgroundColor = #DDD
|
$ui-input--disabled-backgroundColor = #DDD
|
||||||
|
|
||||||
|
// Parts
|
||||||
|
$ui-favorite-star-button-color = #FFC216
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* # Border
|
* # Border
|
||||||
*/
|
*/
|
||||||
@@ -135,7 +141,10 @@ modal()
|
|||||||
|
|
||||||
// Dark theme
|
// Dark theme
|
||||||
$ui-dark-borderColor = lighten(#21252B, 20%)
|
$ui-dark-borderColor = lighten(#21252B, 20%)
|
||||||
$ui-dark-backgroundColor = darken(#21252B, 10%)
|
$ui-dark-backgroundColor = #1D1D1D
|
||||||
|
$ui-dark-noteList-backgroundColor = #181818
|
||||||
|
$ui-dark-noteDetail-backgroundColor = #0D0D0D
|
||||||
|
$ui-dark-tag-backgroundColor = rgba(255, 255, 255, 0.3)
|
||||||
$dark-background-color = lighten($ui-dark-backgroundColor, 10%)
|
$dark-background-color = lighten($ui-dark-backgroundColor, 10%)
|
||||||
$ui-dark-text-color = #DDDDDD
|
$ui-dark-text-color = #DDDDDD
|
||||||
$ui-dark-button--active-color = white
|
$ui-dark-button--active-color = white
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ By this, webpack will watch the code changes and apply it automatically.
|
|||||||
We use Grunt.
|
We use Grunt.
|
||||||
Acutal deploy can be run by `grunt`. However, you shouldn't use because the default task is including codesign and authenticode.
|
Acutal deploy can be run by `grunt`. However, you shouldn't use because the default task is including codesign and authenticode.
|
||||||
|
|
||||||
So, we prepare a script which just make an excutable file.
|
So, we prepare a script which just make an executable file.
|
||||||
|
|
||||||
```
|
```
|
||||||
grunt pre-build
|
grunt pre-build
|
||||||
|
|||||||
10
gruntfile.js
@@ -5,16 +5,16 @@ const packager = require('electron-packager')
|
|||||||
const WIN = process.platform === 'win32'
|
const WIN = process.platform === 'win32'
|
||||||
|
|
||||||
module.exports = function (grunt) {
|
module.exports = function (grunt) {
|
||||||
var auth_code
|
var authCode
|
||||||
try {
|
try {
|
||||||
auth_code = grunt.file.readJSON('secret/auth_code.json')
|
authCode = grunt.file.readJSON('secret/auth_code.json')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.origError.code === 'ENOENT') {
|
if (e.origError.code === 'ENOENT') {
|
||||||
console.warn('secret/auth_code.json is not found. CodeSigning is not available.')
|
console.warn('secret/auth_code.json is not found. CodeSigning is not available.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const OSX_COMMON_NAME = auth_code != null ? auth_code.OSX_COMMON_NAME : ''
|
const OSX_COMMON_NAME = authCode != null ? authCode.OSX_COMMON_NAME : ''
|
||||||
const WIN_CERT_PASSWORD = auth_code != null ? auth_code.WIN_CERT_PASSWORD : ''
|
const WIN_CERT_PASSWORD = authCode != null ? authCode.WIN_CERT_PASSWORD : ''
|
||||||
|
|
||||||
var initConfig = {
|
var initConfig = {
|
||||||
pkg: grunt.file.readJSON('package.json'),
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
@@ -98,7 +98,7 @@ module.exports = function (grunt) {
|
|||||||
prune: true,
|
prune: true,
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
out: path.join(__dirname, 'dist'),
|
out: path.join(__dirname, 'dist'),
|
||||||
ignore: /node_modules\/ace-builds\/(?!src-min)|node_modules\/ace-builds\/(?=src-min-noconflict)|node_modules\/devicon\/icons|dist|^\/browser|^\/secret|\.babelrc|\.gitignore|^\/\.gitmodules|^\/gruntfile|^\/readme.md|^\/webpack|^\/appdmg\.json|^\/node_modules\/grunt/
|
ignore: /node_modules\/ace-builds\/(?!src-min)|node_modules\/ace-builds\/(?=src-min-noconflict)|node_modules\/devicon\/icons|^\/browser|^\/secret|\.babelrc|\.gitignore|^\/\.gitmodules|^\/gruntfile|^\/readme.md|^\/webpack|^\/appdmg\.json|^\/node_modules\/grunt/
|
||||||
}
|
}
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case 'win':
|
case 'win':
|
||||||
|
|||||||
@@ -1,19 +1,10 @@
|
|||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const app = electron.app
|
const app = electron.app
|
||||||
const Menu = electron.Menu
|
|
||||||
|
|
||||||
var finderWindow = null
|
|
||||||
|
|
||||||
app.on('ready', function () {
|
app.on('ready', function () {
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
app.dock.hide()
|
app.dock.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
// var template = require('./finder-menu')
|
|
||||||
// var menu = Menu.buildFromTemplate(template)
|
|
||||||
// Menu.setApplicationMenu(menu)
|
|
||||||
|
|
||||||
finderWindow = require('./finder-window')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = app
|
module.exports = app
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css" media="screen" charset="utf-8">
|
<link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css" media="screen" charset="utf-8">
|
||||||
<link rel="stylesheet" href="../node_modules/highlight.js/styles/xcode.css" id="hljs-css">
|
|
||||||
<link rel="shortcut icon" href="favicon.ico">
|
<link rel="shortcut icon" href="favicon.ico">
|
||||||
<link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css">
|
<link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css">
|
||||||
|
|
||||||
@@ -32,23 +31,31 @@
|
|||||||
<script src="../node_modules/codemirror/addon/mode/overlay.js"></script>
|
<script src="../node_modules/codemirror/addon/mode/overlay.js"></script>
|
||||||
<script src="../node_modules/codemirror/addon/mode/loadmode.js"></script>
|
<script src="../node_modules/codemirror/addon/mode/loadmode.js"></script>
|
||||||
<script src="../node_modules/codemirror/keymap/sublime.js"></script>
|
<script src="../node_modules/codemirror/keymap/sublime.js"></script>
|
||||||
|
<script src="../node_modules/codemirror/keymap/vim.js"></script>
|
||||||
<script src="../node_modules/codemirror/addon/runmode/runmode.js"></script>
|
<script src="../node_modules/codemirror/addon/runmode/runmode.js"></script>
|
||||||
|
|
||||||
<script src="../compiled/katex.js"></script>
|
<script src="../node_modules/raphael/raphael.min.js"></script>
|
||||||
<script src="../compiled/react.js"></script>
|
<script src="../node_modules/flowchart.js/release/flowchart.min.js"></script>
|
||||||
<script src="../compiled/react-dom.js"></script>
|
|
||||||
<script src="../compiled/redux.js"></script>
|
<script src="../node_modules/katex/dist/katex.min.js"></script>
|
||||||
<script src="../compiled/react-redux.js"></script>
|
<script src="../node_modules/react/dist/react.min.js"></script>
|
||||||
|
<script src="../node_modules/react-dom/dist/react-dom.min.js"></script>
|
||||||
|
<script src="../node_modules/redux/dist/redux.min.js"></script>
|
||||||
|
<script src="../node_modules/react-redux/dist/react-redux.min.js"></script>
|
||||||
|
<script>
|
||||||
|
window._ = require('lodash');
|
||||||
|
</script>
|
||||||
|
<script src="../node_modules/js-sequence-diagrams/fucknpm/sequence-diagram-min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
electron.webFrame.setZoomLevelLimits(1, 1)
|
electron.webFrame.setZoomLevelLimits(1, 1)
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
var scriptUrl = _.find(electron.remote.process.argv, a => a === '--hot')
|
var scriptUrl = _.find(electron.remote.process.argv, (a) => a === '--hot')
|
||||||
? 'http://localhost:8080/assets/finder.js'
|
? 'http://localhost:8080/assets/finder.js'
|
||||||
: '../compiled/finder.js'
|
: '../compiled/finder.js'
|
||||||
var scriptEl=document.createElement('script')
|
var scriptEl = document.createElement('script')
|
||||||
scriptEl.setAttribute("type","text/javascript")
|
scriptEl.setAttribute('type', 'text/javascript')
|
||||||
scriptEl.setAttribute("src", scriptUrl)
|
scriptEl.setAttribute('src', scriptUrl)
|
||||||
document.body.appendChild(scriptEl)
|
document.body.appendChild(scriptEl)
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ const electron = require('electron')
|
|||||||
const app = electron.app
|
const app = electron.app
|
||||||
const Menu = electron.Menu
|
const Menu = electron.Menu
|
||||||
const ipc = electron.ipcMain
|
const ipc = electron.ipcMain
|
||||||
const autoUpdater = electron.autoUpdater
|
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const ChildProcess = require('child_process')
|
const ChildProcess = require('child_process')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
@@ -11,9 +10,8 @@ const GhReleases = require('electron-gh-releases')
|
|||||||
var ipcServer = null
|
var ipcServer = null
|
||||||
|
|
||||||
var mainWindow = null
|
var mainWindow = null
|
||||||
var finderWindow = null
|
|
||||||
|
|
||||||
var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) {
|
var shouldQuit = app.makeSingleInstance(function (commandLine, workingDirectory) {
|
||||||
if (mainWindow) {
|
if (mainWindow) {
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
mainWindow.minimize()
|
mainWindow.minimize()
|
||||||
@@ -26,12 +24,8 @@ var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory)
|
|||||||
|
|
||||||
if (shouldQuit) {
|
if (shouldQuit) {
|
||||||
app.quit()
|
app.quit()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var version = app.getVersion()
|
|
||||||
var versionText = (version == null || version.length === 0) ? 'DEV version' : 'v' + version
|
|
||||||
|
|
||||||
var isUpdateReady = false
|
var isUpdateReady = false
|
||||||
|
|
||||||
var ghReleasesOpts = {
|
var ghReleasesOpts = {
|
||||||
@@ -108,14 +102,9 @@ app.on('ready', function () {
|
|||||||
Menu.setApplicationMenu(menu)
|
Menu.setApplicationMenu(menu)
|
||||||
break
|
break
|
||||||
case 'win32':
|
case 'win32':
|
||||||
finderWindow = require('./finder-window')
|
|
||||||
mainWindow.setMenu(menu)
|
mainWindow.setMenu(menu)
|
||||||
break
|
break
|
||||||
case 'linux':
|
case 'linux':
|
||||||
// Finder is available on cinnamon only.
|
|
||||||
if (process.env.DESKTOP_SESSION === 'cinnamon') {
|
|
||||||
finderWindow = require('./finder-window')
|
|
||||||
}
|
|
||||||
Menu.setApplicationMenu(menu)
|
Menu.setApplicationMenu(menu)
|
||||||
mainWindow.setMenu(menu)
|
mainWindow.setMenu(menu)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ var file = {
|
|||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'New Note',
|
label: 'New Note',
|
||||||
accelerator: OSX ? 'Command + N' : 'Control + N',
|
accelerator: 'CmdOrCtrl + N',
|
||||||
click: function () {
|
click: function () {
|
||||||
mainWindow.webContents.send('top:new-note')
|
mainWindow.webContents.send('top:new-note')
|
||||||
}
|
}
|
||||||
@@ -125,20 +125,14 @@ var view = {
|
|||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'Reload',
|
label: 'Reload',
|
||||||
accelerator: (function () {
|
accelerator: 'CmdOrCtrl+R',
|
||||||
if (process.platform === 'darwin') return 'Command+R'
|
|
||||||
else return 'Ctrl+R'
|
|
||||||
})(),
|
|
||||||
click: function () {
|
click: function () {
|
||||||
BrowserWindow.getFocusedWindow().reload()
|
BrowserWindow.getFocusedWindow().reload()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Toggle Developer Tools',
|
label: 'Toggle Developer Tools',
|
||||||
accelerator: (function () {
|
accelerator: OSX ? 'Command+Alt+I' : 'Ctrl+Shift+I',
|
||||||
if (process.platform === 'darwin') return 'Command+Alt+I'
|
|
||||||
else return 'Ctrl+Shift+I'
|
|
||||||
})(),
|
|
||||||
click: function () {
|
click: function () {
|
||||||
BrowserWindow.getFocusedWindow().toggleDevTools()
|
BrowserWindow.getFocusedWindow().toggleDevTools()
|
||||||
}
|
}
|
||||||
@@ -175,7 +169,7 @@ var help = {
|
|||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'Boostnote official site',
|
label: 'Boostnote official site',
|
||||||
click: function () { shell.openExternal('https://b00st.io/') }
|
click: function () { shell.openExternal('https://boostnote.io/') }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Issue Tracker',
|
label: 'Issue Tracker',
|
||||||
|
|||||||
@@ -2,12 +2,18 @@ const electron = require('electron')
|
|||||||
const app = electron.app
|
const app = electron.app
|
||||||
const BrowserWindow = electron.BrowserWindow
|
const BrowserWindow = electron.BrowserWindow
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
const Config = require('electron-config')
|
||||||
|
const config = new Config()
|
||||||
|
|
||||||
var mainWindow = new BrowserWindow({
|
var showMenu = process.platform !== 'win32'
|
||||||
width: 1080,
|
let windowSize = config.get('windowsize') || { width: 1080, height: 720 }
|
||||||
height: 720,
|
|
||||||
minWidth: 420,
|
let mainWindow = new BrowserWindow({
|
||||||
|
width: windowSize.width,
|
||||||
|
height: windowSize.height,
|
||||||
|
minWidth: 500,
|
||||||
minHeight: 320,
|
minHeight: 320,
|
||||||
|
autoHideMenuBar: showMenu,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
zoomFactor: 1.0,
|
zoomFactor: 1.0,
|
||||||
blinkFeatures: 'OverlayScrollbars'
|
blinkFeatures: 'OverlayScrollbars'
|
||||||
@@ -43,6 +49,7 @@ if (process.platform !== 'linux' || process.env.DESKTOP_SESSION === 'cinnamon')
|
|||||||
})
|
})
|
||||||
|
|
||||||
app.on('before-quit', function (e) {
|
app.on('before-quit', function (e) {
|
||||||
|
config.set('windowsize', mainWindow.getBounds())
|
||||||
mainWindow.removeAllListeners()
|
mainWindow.removeAllListeners()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css" media="screen" charset="utf-8">
|
<link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css" media="screen" charset="utf-8">
|
||||||
<link rel="stylesheet" href="../node_modules/highlight.js/styles/xcode.css" id="hljs-css">
|
|
||||||
<link rel="shortcut icon" href="../resources/favicon.ico">
|
<link rel="shortcut icon" href="../resources/favicon.ico">
|
||||||
<link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css">
|
<link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css">
|
||||||
<title>Boostnote</title>
|
<title>Boostnote</title>
|
||||||
@@ -58,20 +57,27 @@
|
|||||||
<script src="../node_modules/codemirror/addon/mode/overlay.js"></script>
|
<script src="../node_modules/codemirror/addon/mode/overlay.js"></script>
|
||||||
<script src="../node_modules/codemirror/addon/mode/loadmode.js"></script>
|
<script src="../node_modules/codemirror/addon/mode/loadmode.js"></script>
|
||||||
<script src="../node_modules/codemirror/keymap/sublime.js"></script>
|
<script src="../node_modules/codemirror/keymap/sublime.js"></script>
|
||||||
|
<script src="../node_modules/codemirror/keymap/vim.js"></script>
|
||||||
<script src="../node_modules/codemirror/addon/runmode/runmode.js"></script>
|
<script src="../node_modules/codemirror/addon/runmode/runmode.js"></script>
|
||||||
|
|
||||||
<script src="../node_modules/codemirror/addon/edit/continuelist.js"></script>
|
<script src="../node_modules/codemirror/addon/edit/continuelist.js"></script>
|
||||||
|
|
||||||
<script src="../compiled/katex.js"></script>
|
<script src="../node_modules/raphael/raphael.min.js"></script>
|
||||||
<script src="../compiled/react.js"></script>
|
<script src="../node_modules/flowchart.js/release/flowchart.min.js"></script>
|
||||||
<script src="../compiled/react-dom.js"></script>
|
<script>
|
||||||
<script src="../compiled/redux.js"></script>
|
window._ = require('lodash')
|
||||||
<script src="../compiled/react-redux.js"></script>
|
</script>
|
||||||
|
|
||||||
|
<script src="../node_modules/js-sequence-diagrams/fucknpm/sequence-diagram-min.js"></script>
|
||||||
|
<script src="../node_modules/katex/dist/katex.min.js"></script>
|
||||||
|
<script src="../node_modules/react/dist/react.min.js"></script>
|
||||||
|
<script src="../node_modules/react-dom/dist/react-dom.min.js"></script>
|
||||||
|
<script src="../node_modules/redux/dist/redux.min.js"></script>
|
||||||
|
<script src="../node_modules/react-redux/dist/react-redux.min.js"></script>
|
||||||
<script type='text/javascript'>
|
<script type='text/javascript'>
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
electron.webFrame.setZoomLevelLimits(1, 1)
|
electron.webFrame.setZoomLevelLimits(1, 1)
|
||||||
const _ = require('lodash')
|
var scriptUrl = window._.find(electron.remote.process.argv, (a) => a === '--hot')
|
||||||
var scriptUrl = _.find(electron.remote.process.argv, (a) => a === '--hot')
|
|
||||||
? 'http://localhost:8080/assets/main.js'
|
? 'http://localhost:8080/assets/main.js'
|
||||||
: '../compiled/main.js'
|
: '../compiled/main.js'
|
||||||
var scriptEl = document.createElement('script')
|
var scriptEl = document.createElement('script')
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"directory": "compiled",
|
|
||||||
"targets": {
|
|
||||||
"react": "https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.js",
|
|
||||||
"react-dom": "https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.js",
|
|
||||||
"redux": "https://cdnjs.cloudflare.com/ajax/libs/redux/3.5.2/redux.js",
|
|
||||||
"react-redux": "https://unpkg.com/react-redux@4.4.5/dist/react-redux.min.js",
|
|
||||||
"katex": "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.js",
|
|
||||||
"katex-style": "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
36
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "boost",
|
"name": "boost",
|
||||||
"version": "0.7.1",
|
"version": "0.8.1",
|
||||||
"description": "Boostnote",
|
"description": "Boostnote",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
@@ -8,10 +8,10 @@
|
|||||||
"start": "electron ./index.js",
|
"start": "electron ./index.js",
|
||||||
"hot": "electron ./index.js --hot",
|
"hot": "electron ./index.js --hot",
|
||||||
"webpack": "webpack-dev-server --hot --inline --config webpack.config.js",
|
"webpack": "webpack-dev-server --hot --inline --config webpack.config.js",
|
||||||
"postinstall": "npm run vendor",
|
|
||||||
"vendor": "oh-my-cdn",
|
|
||||||
"compile": "grunt compile",
|
"compile": "grunt compile",
|
||||||
"test": "PWD=$(pwd) NODE_ENV=test ava"
|
"test": "PWD=$(pwd) NODE_ENV=test ava",
|
||||||
|
"fix": "npm run lint --fix",
|
||||||
|
"lint": "eslint ./**/*.js"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"electron-version": "1.2.8"
|
"electron-version": "1.2.8"
|
||||||
@@ -36,20 +36,26 @@
|
|||||||
"Romain Bazile (https://github.com/gromain)",
|
"Romain Bazile (https://github.com/gromain)",
|
||||||
"Bruno Paz (https://github.com/brpaz)",
|
"Bruno Paz (https://github.com/brpaz)",
|
||||||
"Fabian Mueller (https://github.com/dotcs)",
|
"Fabian Mueller (https://github.com/dotcs)",
|
||||||
"Yoshihisa Mochihara (https://github.com/yosmoc)"
|
"Yoshihisa Mochihara (https://github.com/yosmoc)",
|
||||||
|
"Mike Resoli (https://github.com/mikeres0)",
|
||||||
|
"tjado (https://github.com/tejado)",
|
||||||
|
"Sota Sugiura (https://github.com/sota1235)"
|
||||||
],
|
],
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/BoostIO/Boostnote/issues"
|
"url": "https://github.com/BoostIO/Boostnote/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://b00st.io",
|
"homepage": "https://boostnote.io",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rokt33r/markdown-it-math": "^4.0.1",
|
"@rokt33r/markdown-it-math": "^4.0.1",
|
||||||
"@rokt33r/season": "^5.3.0",
|
"@rokt33r/season": "^5.3.0",
|
||||||
"codemirror": "^5.19.0",
|
"codemirror": "^5.19.0",
|
||||||
|
"electron-config": "^0.2.1",
|
||||||
"electron-gh-releases": "^2.0.2",
|
"electron-gh-releases": "^2.0.2",
|
||||||
|
"flowchart.js": "^1.6.5",
|
||||||
"font-awesome": "^4.3.0",
|
"font-awesome": "^4.3.0",
|
||||||
"highlight.js": "^9.3.0",
|
|
||||||
"immutable": "^3.8.1",
|
"immutable": "^3.8.1",
|
||||||
|
"js-sequence-diagrams": "^1000000.0.6",
|
||||||
|
"katex": "^0.6.0",
|
||||||
"lodash": "^4.11.1",
|
"lodash": "^4.11.1",
|
||||||
"markdown-it": "^6.0.1",
|
"markdown-it": "^6.0.1",
|
||||||
"markdown-it-checkbox": "^1.1.0",
|
"markdown-it-checkbox": "^1.1.0",
|
||||||
@@ -59,6 +65,11 @@
|
|||||||
"mixpanel": "^0.4.1",
|
"mixpanel": "^0.4.1",
|
||||||
"moment": "^2.10.3",
|
"moment": "^2.10.3",
|
||||||
"node-ipc": "^8.1.0",
|
"node-ipc": "^8.1.0",
|
||||||
|
"raphael": "^2.2.7",
|
||||||
|
"react": "^15.0.2",
|
||||||
|
"react-dom": "^15.0.2",
|
||||||
|
"react-redux": "^4.4.5",
|
||||||
|
"redux": "^3.5.2",
|
||||||
"sander": "^0.5.1",
|
"sander": "^0.5.1",
|
||||||
"superagent": "^1.2.0",
|
"superagent": "^1.2.0",
|
||||||
"superagent-promise": "^1.0.3"
|
"superagent-promise": "^1.0.3"
|
||||||
@@ -78,6 +89,9 @@
|
|||||||
"dom-storage": "^2.0.2",
|
"dom-storage": "^2.0.2",
|
||||||
"electron-packager": "^6.0.0",
|
"electron-packager": "^6.0.0",
|
||||||
"electron-prebuilt": "^1.2.8",
|
"electron-prebuilt": "^1.2.8",
|
||||||
|
"eslint": "^3.13.1",
|
||||||
|
"eslint-config-standard": "^6.2.1",
|
||||||
|
"eslint-config-standard-jsx": "^3.2.0",
|
||||||
"faker": "^3.1.0",
|
"faker": "^3.1.0",
|
||||||
"grunt": "^0.4.5",
|
"grunt": "^0.4.5",
|
||||||
"grunt-electron-installer": "^1.2.0",
|
"grunt-electron-installer": "^1.2.0",
|
||||||
@@ -85,7 +99,6 @@
|
|||||||
"jsdom": "^9.4.2",
|
"jsdom": "^9.4.2",
|
||||||
"merge-stream": "^1.0.0",
|
"merge-stream": "^1.0.0",
|
||||||
"nib": "^1.1.0",
|
"nib": "^1.1.0",
|
||||||
"oh-my-cdn": "^0.1.1",
|
|
||||||
"react": "^15.3.0",
|
"react": "^15.3.0",
|
||||||
"react-color": "^2.2.2",
|
"react-color": "^2.2.2",
|
||||||
"react-css-modules": "^3.7.6",
|
"react-css-modules": "^3.7.6",
|
||||||
@@ -104,14 +117,9 @@
|
|||||||
"grunt-electron-installer-debian": "^0.2.0"
|
"grunt-electron-installer-debian": "^0.2.0"
|
||||||
},
|
},
|
||||||
"optional": false,
|
"optional": false,
|
||||||
"standard": {
|
|
||||||
"globals": [
|
|
||||||
"localStorage"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ava": {
|
"ava": {
|
||||||
"files": [
|
"files": [
|
||||||
"tests/**/*.js"
|
"tests/**/*-test.js"
|
||||||
],
|
],
|
||||||
"require": [
|
"require": [
|
||||||
"babel-register"
|
"babel-register"
|
||||||
|
|||||||
46
readme-ja.md
@@ -1,37 +1,28 @@
|
|||||||
# Boostnote
|
# Boostnote
|
||||||
|
|
||||||
> [Boostnote store](#goods)をはじめました!! :tada: そして、[Pateron](https://www.patreon.com/boostnote)からも私達を支援することができます!
|
> [Boostnote shop](https://boostnote.paintory.com/)をはじめました!! :tada:
|
||||||
|
そして、[Pateron](https://www.patreon.com/boostnote)からも私達を支援することができます!
|
||||||
|
|
||||||

|

|
||||||

|
|
||||||
|
|
||||||
オープンソースノートアプリ
|
|
||||||
|
|
||||||
次の用務がある場合にはIssue trackerを利用してください。
|
**ロードマップ・リクエスト一覧は[こちら](https://github.com/BoostIO/Boostnote/wiki/List-of-the-requested-features)です!**
|
||||||
|
皆さんからのプルリクをお待ちしています!
|
||||||
|
|
||||||
|
以下のような場合には、Issue trackerを利用してください。
|
||||||
- Boostnoteに関して質問したい時
|
- Boostnoteに関して質問したい時
|
||||||
- Boostnoteや計画事項にフィードバックがしたい時
|
- Boostnoteや計画事項にフィードバックがしたい時
|
||||||
- Boostnoteにバグを報告したい時
|
- Boostnoteにバグを報告したい時
|
||||||
- Boostnoteに寄与したい時
|
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
|
|
||||||
単に何かを書くのが楽しくなってほしいです。 :grinning:
|
書くことが楽しくなって欲しいです。 :grinning:
|
||||||
|
|
||||||
- ターゲット OS : OSX, Windows, Linux(後々はモバイルも!)
|
- ターゲット OS : OSX, Windows, Linux(後々はモバイルも!)
|
||||||
- Cloud : Google drive, Dropbox, One drive, iCloud...
|
- Cloud : Google drive, Dropbox, One drive, iCloud...
|
||||||
- オープンソースで残ること!
|
- オープンソースで残ること!
|
||||||
|
|
||||||
## 印象を受けたアプリ/サービス
|
|
||||||
|
|
||||||
- Atom
|
|
||||||
- Quiver
|
|
||||||
- Evernote
|
|
||||||
- GitKraken
|
|
||||||
- GitBook
|
|
||||||
- Gist
|
|
||||||
- Gistbox
|
|
||||||
- Snippets Lab
|
|
||||||
|
|
||||||
|
|
||||||
## Using stack
|
## Using stack
|
||||||
|
|
||||||
@@ -51,12 +42,12 @@
|
|||||||
|
|
||||||
## Goods
|
## Goods
|
||||||
|
|
||||||
<img src="https://b00st.io/images/t3.png" width="250"/>
|
<img src="https://boostnote.io/images/t3.png" width="250"/>
|
||||||
<img src="https://b00st.io/images/t1.png" width="250"/>
|
<img src="https://boostnote.io/images/t1.png" width="250"/>
|
||||||
|
|
||||||
[Boostnote store](https://boostnote.paintory.com/)から幾つかのグッズを販売しています。
|
[Boostnote shop](https://boostnote.paintory.com/)から幾つかのグッズを販売しています。
|
||||||
|
|
||||||
商品は全世界何処でも届けることができます。このストアは[Paintory](https://paintory.com/)から提供されます。
|
商品は全世界どこへでも届ける事が出来ます!
|
||||||
|
|
||||||
## Donation
|
## Donation
|
||||||
|
|
||||||
@@ -64,18 +55,23 @@
|
|||||||
|
|
||||||
## Author & Maintainer
|
## Author & Maintainer
|
||||||
|
|
||||||
[Rokt33r(Dick Choi of MAISIN&CO.)](https://github.com/rokt33r)
|
- [Rokt33r](https://github.com/rokt33r)
|
||||||
|
- [sota1235](https://github.com/sota1235)
|
||||||
|
- [Kohei TAKATA](https://github.com/kohei-takata)
|
||||||
|
- [Kazu Yokomizo](https://github.com/kazup01)
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
- [Kazu Yokomizo](https://github.com/kazup01)
|
|
||||||
- [dojineko](https://github.com/dojineko)
|
- [dojineko](https://github.com/dojineko)
|
||||||
- [Romain Bazile](https://github.com/gromain)
|
- [Romain Bazile](https://github.com/gromain)
|
||||||
- [Bruno Paz](https://github.com/brpaz)
|
- [Bruno Paz](https://github.com/brpaz)
|
||||||
- [Fabian Mueller](https://github.com/dotcs)
|
- [Fabian Mueller](https://github.com/dotcs)
|
||||||
|
- [Yoshihisa Mochihara](https://github.com/yosmoc)
|
||||||
|
- [Mike Resoli](https://github.com/mikeres0)
|
||||||
|
- [tjado](https://github.com/tejado)
|
||||||
|
|
||||||
## Copyright & License
|
## Copyright & License
|
||||||
|
|
||||||
Copyright (C) 2016 MAISIN&CO.
|
Copyright (C) 2017 Maisin&Co.
|
||||||
|
|
||||||
[GPL v3](./LICENSE).
|
[GPL v3](./LICENSE).
|
||||||
|
|||||||
13
readme-ko.md
@@ -1,9 +1,8 @@
|
|||||||
# Boostnote
|
# Boostnote
|
||||||
|
|
||||||
> [Boostnote store](#goods)가 생겼습니다!! :tada: 그리고,[Pateron](https://www.patreon.com/boostnote)에서도 저희를 지원 하실 수 있습니다.!
|
> [Boostnote store](https://boostnote.paintory.com/)가 생겼습니다!! :tada: 그리고,[Pateron](https://www.patreon.com/boostnote)에서도 저희를 지원 하실 수 있습니다.!
|
||||||
|
|
||||||

|

|
||||||

|
|
||||||
|
|
||||||
오픈소스 노트 앱
|
오픈소스 노트 앱
|
||||||
|
|
||||||
@@ -52,8 +51,8 @@
|
|||||||
|
|
||||||
## Goods
|
## Goods
|
||||||
|
|
||||||
<img src="https://b00st.io/images/t3.png" width="250"/>
|
<img src="https://boostnote.io/images/t3.png" width="250"/>
|
||||||
<img src="https://b00st.io/images/t1.png" width="250"/>
|
<img src="https://boostnote.io/images/t1.png" width="250"/>
|
||||||
|
|
||||||
[Boostnote store](https://boostnote.paintory.com/)에서 몇가지 상품들을 팔고있습니다.
|
[Boostnote store](https://boostnote.paintory.com/)에서 몇가지 상품들을 팔고있습니다.
|
||||||
|
|
||||||
@@ -74,6 +73,10 @@
|
|||||||
- [Romain Bazile](https://github.com/gromain)
|
- [Romain Bazile](https://github.com/gromain)
|
||||||
- [Bruno Paz](https://github.com/brpaz)
|
- [Bruno Paz](https://github.com/brpaz)
|
||||||
- [Fabian Mueller](https://github.com/dotcs)
|
- [Fabian Mueller](https://github.com/dotcs)
|
||||||
|
- [Yoshihisa Mochihara](https://github.com/yosmoc)
|
||||||
|
- [Mike Resoli](https://github.com/mikeres0)
|
||||||
|
- [tjado](https://github.com/tejado)
|
||||||
|
- [sota1235](https://github.com/sota1235)
|
||||||
|
|
||||||
## Copyright & License
|
## Copyright & License
|
||||||
|
|
||||||
|
|||||||
103
readme.md
@@ -1,89 +1,36 @@
|
|||||||
# Boostnote
|
<h1 align="center">
|
||||||
|
<a href="https://github.com/BoostIO/Boostnote"><img src="./resources/app.png" alt="Boostnote" width="180"></a>
|
||||||
|
<br>
|
||||||
|
Boostnote
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
</h1>
|
||||||
|
<h4 align="center">Note-taking app for programmers. </h4>
|
||||||
|
<h5 align="center">macOS, Windows and Linux</h5>
|
||||||
|
<h5 align="center">Built with Electron, React + Redux, Webpack and CSSModules</h5>
|
||||||
|
|
||||||
> We launched [Boostnote store](#goods)!! :tada: Also, you can support us from [Patreon](https://www.patreon.com/boostnote) and [Open collective](https://opencollective.com/boostnote)!
|

|
||||||
|
|
||||||

|
[](https://travis-ci.org/BoostIO/Boostnote)
|
||||||

|
|
||||||
|
|
||||||
Simple opensource note app for developer.
|
|
||||||
|
|
||||||
You can use the issue tracker of this repository for
|
|
||||||
- asking a question about Boostnote
|
|
||||||
- giving a feedback about Boostnote and its future plan
|
|
||||||
- reporting a bug of Boostnote
|
|
||||||
- wanting to contribute Boostnote
|
|
||||||
|
|
||||||
We have a slack if you want to engage us deeply, ask @rokt33r to join.
|
|
||||||
|
|
||||||
- [日本語](./readme-ja.md)
|
|
||||||
- [한국어](./readme-ko.md)
|
|
||||||
|
|
||||||
## Goal
|
|
||||||
|
|
||||||
We just want you to enjoying writing anything. :grinning:
|
|
||||||
|
|
||||||
- Target OS : OSX, Windows, Linux(also mobile somewhen!)
|
|
||||||
- Cloud : Google drive, Dropbox, One drive, iCloud...
|
|
||||||
- Remaining opensource forever!
|
|
||||||
|
|
||||||
Check planned features [here](https://github.com/BoostIO/Boostnote/issues/68)!
|
|
||||||
|
|
||||||
## Inspired by
|
|
||||||
|
|
||||||
- Atom
|
|
||||||
- Quiver
|
|
||||||
- Evernote
|
|
||||||
- GitKraken
|
|
||||||
- GitBook
|
|
||||||
- Gist
|
|
||||||
- Gistbox
|
|
||||||
- Snippets Lab
|
|
||||||
|
|
||||||
## Using stack
|
|
||||||
|
|
||||||
- Electron
|
|
||||||
- React
|
|
||||||
- Webpack
|
|
||||||
- Redux
|
|
||||||
- CSSModules
|
|
||||||
|
|
||||||
## Codestyle
|
|
||||||
|
|
||||||
[](https://github.com/feross/standard)
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
- [Build](docs/build.md)
|
|
||||||
|
|
||||||
## Goods
|
|
||||||
|
|
||||||
<img src="https://b00st.io/images/t3.png" width="250"/>
|
|
||||||
<img src="https://b00st.io/images/t1.png" width="250"/>
|
|
||||||
|
|
||||||
We're currently selling some goods from [Boostnote store](https://boostnote.paintory.com/).
|
|
||||||
|
|
||||||
The product can be sent anywhere in the world. This store is powered by [Paintory](https://paintory.com/)
|
|
||||||
|
|
||||||
## Donation
|
|
||||||
|
|
||||||
We launched a [Patreon page](https://www.patreon.com/boostnote).
|
|
||||||
Also, We've been approved [Open collective](https://opencollective.com/boostnote).
|
|
||||||
|
|
||||||
## Author & Maintainer
|
## Author & Maintainer
|
||||||
|
- [Rokt33r](https://github.com/rokt33r)
|
||||||
[Rokt33r(Dick Choi of MAISIN&CO.)](https://github.com/rokt33r)
|
- [sota1235](https://github.com/sota1235)
|
||||||
|
- [Kohei TAKATA](https://github.com/kohei-takata)
|
||||||
|
- [Kazu Yokomizo](https://github.com/kazup01)
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
[Great contributors](https://github.com/BoostIO/Boostnote/graphs/contributors) :tada:
|
||||||
|
|
||||||
- [Kazu Yokomizo](https://github.com/kazup01)
|
|
||||||
- [dojineko](https://github.com/dojineko)
|
|
||||||
- [Romain Bazile](https://github.com/gromain)
|
|
||||||
- [Bruno Paz](https://github.com/brpaz)
|
|
||||||
- [Fabian Mueller](https://github.com/dotcs)
|
|
||||||
- [Yoshihisa Mochihara](https://github.com/yosmoc)
|
|
||||||
|
|
||||||
## Copyright & License
|
## More Information
|
||||||
|
* Website: http://boostnote.io/
|
||||||
|
* Roadmap(upcoming features and bug fixes): https://goo.gl/Mdu44q
|
||||||
|
* Boostnote Shop(Products are shipped to all over the world :+1:): https://boostnote.paintory.com/
|
||||||
|
* Donation: [Patreon](https://www.patreon.com/boostnote)
|
||||||
|
* Development: https://github.com/BoostIO/Boostnote/blob/master/docs/build.md
|
||||||
|
* Copyright (C) 2017 Maisin&Co.
|
||||||
|
|
||||||
Copyright (C) 2016 MAISIN&CO.
|
## License
|
||||||
|
|
||||||
[GPL v3](./LICENSE).
|
[GPL v3](./LICENSE).
|
||||||
|
|||||||
BIN
resources/app.icns
Normal file → Executable file
BIN
resources/app.ico
Normal file → Executable file
|
Before Width: | Height: | Size: 361 KiB After Width: | Height: | Size: 361 KiB |
BIN
resources/app.png
Normal file → Executable file
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 36 KiB |
BIN
resources/boostnote-install.gif
Normal file → Executable file
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 12 KiB |
BIN
resources/boostnote-install.png
Normal file → Executable file
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 30 KiB |
BIN
resources/boostnote-install@2x.png
Normal file → Executable file
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 71 KiB |
BIN
resources/dmg.icns
Normal file → Executable file
BIN
resources/dmg.ico
Normal file → Executable file
|
Before Width: | Height: | Size: 361 KiB After Width: | Height: | Size: 361 KiB |
BIN
resources/dmg.png
Normal file → Executable file
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 11 KiB |