mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-14 02:06:29 +00:00
Merge branch 'master' into new-snippet-tabbar
# Conflicts: # browser/main/Detail/SnippetNoteDetail.js
This commit is contained in:
@@ -8,6 +8,8 @@ import copyImage from 'browser/main/lib/dataApi/copyImage'
|
|||||||
import { findStorage } from 'browser/lib/findStorage'
|
import { findStorage } from 'browser/lib/findStorage'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import eventEmitter from 'browser/main/lib/eventEmitter'
|
import eventEmitter from 'browser/main/lib/eventEmitter'
|
||||||
|
import iconv from 'iconv-lite'
|
||||||
|
const { ipcRenderer } = require('electron')
|
||||||
|
|
||||||
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
|
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
|
||||||
|
|
||||||
@@ -32,8 +34,13 @@ export default class CodeEditor extends React.Component {
|
|||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
|
this.scrollHandler = _.debounce(this.handleScroll.bind(this), 100, {leading: false, trailing: true})
|
||||||
this.changeHandler = (e) => this.handleChange(e)
|
this.changeHandler = (e) => this.handleChange(e)
|
||||||
|
this.focusHandler = () => {
|
||||||
|
ipcRenderer.send('editor:focused', true)
|
||||||
|
}
|
||||||
this.blurHandler = (editor, e) => {
|
this.blurHandler = (editor, e) => {
|
||||||
|
ipcRenderer.send('editor:focused', false)
|
||||||
if (e == null) return null
|
if (e == null) return null
|
||||||
let el = e.relatedTarget
|
let el = e.relatedTarget
|
||||||
while (el != null) {
|
while (el != null) {
|
||||||
@@ -81,7 +88,6 @@ export default class CodeEditor extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.scrollHandler = _.debounce(this.handleScroll.bind(this), 100, {leading: false, trailing: true})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
@@ -139,6 +145,7 @@ export default class CodeEditor extends React.Component {
|
|||||||
|
|
||||||
this.setMode(this.props.mode)
|
this.setMode(this.props.mode)
|
||||||
|
|
||||||
|
this.editor.on('focus', this.focusHandler)
|
||||||
this.editor.on('blur', this.blurHandler)
|
this.editor.on('blur', this.blurHandler)
|
||||||
this.editor.on('change', this.changeHandler)
|
this.editor.on('change', this.changeHandler)
|
||||||
this.editor.on('paste', this.pasteHandler)
|
this.editor.on('paste', this.pasteHandler)
|
||||||
@@ -162,6 +169,7 @@ export default class CodeEditor extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
|
this.editor.off('focus', this.focusHandler)
|
||||||
this.editor.off('blur', this.blurHandler)
|
this.editor.off('blur', this.blurHandler)
|
||||||
this.editor.off('change', this.changeHandler)
|
this.editor.off('change', this.changeHandler)
|
||||||
this.editor.off('paste', this.pasteHandler)
|
this.editor.off('paste', this.pasteHandler)
|
||||||
@@ -317,7 +325,7 @@ export default class CodeEditor extends React.Component {
|
|||||||
fetch(pastedTxt, {
|
fetch(pastedTxt, {
|
||||||
method: 'get'
|
method: 'get'
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
return (response.text())
|
return this.decodeResponse(response)
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
const parsedResponse = (new window.DOMParser()).parseFromString(response, 'text/html')
|
const parsedResponse = (new window.DOMParser()).parseFromString(response, 'text/html')
|
||||||
const value = editor.getValue()
|
const value = editor.getValue()
|
||||||
@@ -335,6 +343,31 @@ export default class CodeEditor extends React.Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decodeResponse (response) {
|
||||||
|
const headers = response.headers
|
||||||
|
const _charset = headers.has('content-type')
|
||||||
|
? this.extractContentTypeCharset(headers.get('content-type'))
|
||||||
|
: undefined
|
||||||
|
return response.arrayBuffer().then((buff) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const charset = _charset !== undefined && iconv.encodingExists(_charset) ? _charset : 'utf-8'
|
||||||
|
resolve(iconv.decode(new Buffer(buff), charset).toString())
|
||||||
|
} catch (e) {
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
extractContentTypeCharset (contentType) {
|
||||||
|
return contentType.split(';').filter((str) => {
|
||||||
|
return str.trim().toLowerCase().startsWith('charset')
|
||||||
|
}).map((str) => {
|
||||||
|
return str.replace(/['"]/g, '').split('=')[1]
|
||||||
|
})[0]
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { className, fontSize } = this.props
|
const { className, fontSize } = this.props
|
||||||
let fontFamily = this.props.fontFamily
|
let fontFamily = this.props.fontFamily
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ class MarkdownEditor extends React.Component {
|
|||||||
lineNumber={config.preview.lineNumber}
|
lineNumber={config.preview.lineNumber}
|
||||||
indentSize={editorIndentSize}
|
indentSize={editorIndentSize}
|
||||||
scrollPastEnd={config.preview.scrollPastEnd}
|
scrollPastEnd={config.preview.scrollPastEnd}
|
||||||
|
smartQuotes={config.preview.smartQuotes}
|
||||||
ref='preview'
|
ref='preview'
|
||||||
onContextMenu={(e) => this.handleContextMenu(e)}
|
onContextMenu={(e) => this.handleContextMenu(e)}
|
||||||
onDoubleClick={(e) => this.handleDoubleClick(e)}
|
onDoubleClick={(e) => this.handleDoubleClick(e)}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import markdown from 'browser/lib/markdown'
|
import Markdown from 'browser/lib/markdown'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import CodeMirror from 'codemirror'
|
import CodeMirror from 'codemirror'
|
||||||
import 'codemirror-mode-elixir'
|
import 'codemirror-mode-elixir'
|
||||||
@@ -130,6 +130,13 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
this.printHandler = () => this.handlePrint()
|
this.printHandler = () => this.handlePrint()
|
||||||
|
|
||||||
this.linkClickHandler = this.handlelinkClick.bind(this)
|
this.linkClickHandler = this.handlelinkClick.bind(this)
|
||||||
|
this.initMarkdown = this.initMarkdown.bind(this)
|
||||||
|
this.initMarkdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
initMarkdown () {
|
||||||
|
const { smartQuotes } = this.props
|
||||||
|
this.markdown = new Markdown({ typographer: smartQuotes })
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePreviewAnchorClick (e) {
|
handlePreviewAnchorClick (e) {
|
||||||
@@ -198,7 +205,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
const {fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme} = this.getStyleParams()
|
const {fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme} = this.getStyleParams()
|
||||||
|
|
||||||
const inlineStyles = buildStyle(fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme, lineNumber)
|
const inlineStyles = buildStyle(fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme, lineNumber)
|
||||||
const body = markdown.render(noteContent)
|
const body = this.markdown.render(noteContent)
|
||||||
const files = [this.GetCodeThemeLink(codeBlockTheme), ...CSS_FILES]
|
const files = [this.GetCodeThemeLink(codeBlockTheme), ...CSS_FILES]
|
||||||
|
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
@@ -216,6 +223,8 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
|
|
||||||
return `<html>
|
return `<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name = "viewport" content = "width = device-width, initial-scale = 1, maximum-scale = 1">
|
||||||
<style id="style">${inlineStyles}</style>
|
<style id="style">${inlineStyles}</style>
|
||||||
${styles}
|
${styles}
|
||||||
</head>
|
</head>
|
||||||
@@ -309,6 +318,10 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
|
|
||||||
componentDidUpdate (prevProps) {
|
componentDidUpdate (prevProps) {
|
||||||
if (prevProps.value !== this.props.value) this.rewriteIframe()
|
if (prevProps.value !== this.props.value) this.rewriteIframe()
|
||||||
|
if (prevProps.smartQuotes !== this.props.smartQuotes) {
|
||||||
|
this.initMarkdown()
|
||||||
|
this.rewriteIframe()
|
||||||
|
}
|
||||||
if (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 ||
|
||||||
@@ -374,7 +387,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
value = value.replace(codeBlock, htmlTextHelper.encodeEntities(codeBlock))
|
value = value.replace(codeBlock, htmlTextHelper.encodeEntities(codeBlock))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.refs.root.contentWindow.document.body.innerHTML = markdown.render(value)
|
this.refs.root.contentWindow.document.body.innerHTML = this.markdown.render(value)
|
||||||
|
|
||||||
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
|
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
|
||||||
this.fixDecodedURI(el)
|
this.fixDecodedURI(el)
|
||||||
@@ -390,9 +403,9 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
})
|
})
|
||||||
|
|
||||||
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('img'), (el) => {
|
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('img'), (el) => {
|
||||||
el.src = markdown.normalizeLinkText(el.src)
|
el.src = this.markdown.normalizeLinkText(el.src)
|
||||||
if (!/\/:storage/.test(el.src)) return
|
if (!/\/:storage/.test(el.src)) return
|
||||||
el.src = `file:///${markdown.normalizeLinkText(path.join(storagePath, 'images', path.basename(el.src)))}`
|
el.src = `file:///${this.markdown.normalizeLinkText(path.join(storagePath, 'images', path.basename(el.src)))}`
|
||||||
})
|
})
|
||||||
|
|
||||||
codeBlockTheme = consts.THEMES.some((_theme) => _theme === codeBlockTheme)
|
codeBlockTheme = consts.THEMES.some((_theme) => _theme === codeBlockTheme)
|
||||||
@@ -419,9 +432,9 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
el.innerHTML = ''
|
el.innerHTML = ''
|
||||||
if (codeBlockTheme.indexOf('solarized') === 0) {
|
if (codeBlockTheme.indexOf('solarized') === 0) {
|
||||||
const [refThema, color] = codeBlockTheme.split(' ')
|
const [refThema, color] = codeBlockTheme.split(' ')
|
||||||
el.parentNode.className += ` cm-s-${refThema} cm-s-${color} CodeMirror`
|
el.parentNode.className += ` cm-s-${refThema} cm-s-${color}`
|
||||||
} else {
|
} else {
|
||||||
el.parentNode.className += ` cm-s-${codeBlockTheme} CodeMirror`
|
el.parentNode.className += ` cm-s-${codeBlockTheme}`
|
||||||
}
|
}
|
||||||
CodeMirror.runMode(content, syntax.mime, el, {
|
CodeMirror.runMode(content, syntax.mime, el, {
|
||||||
tabSize: indentSize
|
tabSize: indentSize
|
||||||
@@ -504,9 +517,20 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
|
|
||||||
handlelinkClick (e) {
|
handlelinkClick (e) {
|
||||||
const noteHash = e.target.href.split('/').pop()
|
const noteHash = e.target.href.split('/').pop()
|
||||||
const regexIsNoteLink = /^(.{20})-(.{20})$/
|
// this will match the new uuid v4 hash and the old hash
|
||||||
|
// e.g.
|
||||||
|
// :note:1c211eb7dcb463de6490 and
|
||||||
|
// :note:7dd23275-f2b4-49cb-9e93-3454daf1af9c
|
||||||
|
const regexIsNoteLink = /^:note:([a-zA-Z0-9-]{20,36})$/
|
||||||
if (regexIsNoteLink.test(noteHash)) {
|
if (regexIsNoteLink.test(noteHash)) {
|
||||||
eventEmitter.emit('list:jump', noteHash)
|
eventEmitter.emit('list:jump', noteHash.replace(':note:', ''))
|
||||||
|
}
|
||||||
|
// this will match the old link format storage.key-note.key
|
||||||
|
// e.g.
|
||||||
|
// 877f99c3268608328037-1c211eb7dcb463de6490
|
||||||
|
const regexIsLegacyNoteLink = /^(.{20})-(.{20})$/
|
||||||
|
if (regexIsLegacyNoteLink.test(noteHash)) {
|
||||||
|
eventEmitter.emit('list:jump', noteHash.split('-')[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,5 +557,6 @@ MarkdownPreview.propTypes = {
|
|||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
showCopyNotification: PropTypes.bool,
|
showCopyNotification: PropTypes.bool,
|
||||||
storagePath: PropTypes.string
|
storagePath: PropTypes.string,
|
||||||
|
smartQuotes: PropTypes.bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
codeBlockFontFamily={config.editor.fontFamily}
|
codeBlockFontFamily={config.editor.fontFamily}
|
||||||
lineNumber={config.preview.lineNumber}
|
lineNumber={config.preview.lineNumber}
|
||||||
scrollPastEnd={config.preview.scrollPastEnd}
|
scrollPastEnd={config.preview.scrollPastEnd}
|
||||||
|
smartQuotes={config.preview.smartQuotes}
|
||||||
ref='preview'
|
ref='preview'
|
||||||
tabInde='0'
|
tabInde='0'
|
||||||
value={value}
|
value={value}
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ const NoteItem = ({
|
|||||||
? 'item--active'
|
? 'item--active'
|
||||||
: 'item'
|
: 'item'
|
||||||
}
|
}
|
||||||
key={`${note.storage}-${note.key}`}
|
key={note.key}
|
||||||
onClick={e => handleNoteClick(e, `${note.storage}-${note.key}`)}
|
onClick={e => handleNoteClick(e, note.key)}
|
||||||
onContextMenu={e => handleNoteContextMenu(e, `${note.storage}-${note.key}`)}
|
onContextMenu={e => handleNoteContextMenu(e, note.key)}
|
||||||
onDragStart={e => handleDragStart(e, note)}
|
onDragStart={e => handleDragStart(e, note)}
|
||||||
draggable='true'
|
draggable='true'
|
||||||
>
|
>
|
||||||
@@ -100,7 +100,7 @@ const NoteItem = ({
|
|||||||
{note.isStarred
|
{note.isStarred
|
||||||
? <img styleName='item-star' src='../resources/icon/icon-starred.svg' /> : ''
|
? <img styleName='item-star' src='../resources/icon/icon-starred.svg' /> : ''
|
||||||
}
|
}
|
||||||
{note.isPinned && !pathname.match(/\/home|\/starred|\/trash/)
|
{note.isPinned && !pathname.match(/\/starred|\/trash/)
|
||||||
? <i styleName='item-pin' className='fa fa-thumb-tack' /> : ''
|
? <i styleName='item-pin' className='fa fa-thumb-tack' /> : ''
|
||||||
}
|
}
|
||||||
{note.type === 'MARKDOWN_NOTE'
|
{note.type === 'MARKDOWN_NOTE'
|
||||||
@@ -123,7 +123,11 @@ NoteItem.propTypes = {
|
|||||||
title: PropTypes.string.isrequired,
|
title: PropTypes.string.isrequired,
|
||||||
tags: PropTypes.array,
|
tags: PropTypes.array,
|
||||||
isStarred: PropTypes.bool.isRequired,
|
isStarred: PropTypes.bool.isRequired,
|
||||||
isTrashed: PropTypes.bool.isRequired
|
isTrashed: PropTypes.bool.isRequired,
|
||||||
|
blog: {
|
||||||
|
blogLink: PropTypes.string,
|
||||||
|
blogId: PropTypes.number
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
handleNoteClick: PropTypes.func.isRequired,
|
handleNoteClick: PropTypes.func.isRequired,
|
||||||
handleNoteContextMenu: PropTypes.func.isRequired,
|
handleNoteContextMenu: PropTypes.func.isRequired,
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ $control-height = 30px
|
|||||||
font-size 12px
|
font-size 12px
|
||||||
line-height 20px
|
line-height 20px
|
||||||
overflow ellipsis
|
overflow ellipsis
|
||||||
display flex
|
display block
|
||||||
|
|
||||||
.item-bottom-tagList
|
.item-bottom-tagList
|
||||||
flex 1
|
flex 1
|
||||||
@@ -144,18 +144,18 @@ $control-height = 30px
|
|||||||
padding-bottom 2px
|
padding-bottom 2px
|
||||||
|
|
||||||
.item-star
|
.item-star
|
||||||
position relative
|
position absolute
|
||||||
width 16px
|
right 2px
|
||||||
height 16px
|
top 5px
|
||||||
color alpha($ui-favorite-star-button-color, 60%)
|
color alpha($ui-favorite-star-button-color, 60%)
|
||||||
font-size 12px
|
font-size 12px
|
||||||
padding 0
|
padding 0
|
||||||
border-radius 17px
|
border-radius 17px
|
||||||
|
|
||||||
.item-pin
|
.item-pin
|
||||||
position relative
|
position absolute
|
||||||
width 34px
|
right 25px
|
||||||
height 34px
|
top 7px
|
||||||
color #E54D42
|
color #E54D42
|
||||||
font-size 14px
|
font-size 14px
|
||||||
padding 0
|
padding 0
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ const NoteItemSimple = ({
|
|||||||
? 'item-simple--active'
|
? 'item-simple--active'
|
||||||
: 'item-simple'
|
: 'item-simple'
|
||||||
}
|
}
|
||||||
key={`${note.storage}-${note.key}`}
|
key={note.key}
|
||||||
onClick={e => handleNoteClick(e, `${note.storage}-${note.key}`)}
|
onClick={e => handleNoteClick(e, note.key)}
|
||||||
onContextMenu={e => handleNoteContextMenu(e, `${note.storage}-${note.key}`)}
|
onContextMenu={e => handleNoteContextMenu(e, note.key)}
|
||||||
onDragStart={e => handleDragStart(e, note)}
|
onDragStart={e => handleDragStart(e, note)}
|
||||||
draggable='true'
|
draggable='true'
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import PropTypes from 'prop-types'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './SideNavFilter.styl'
|
import styles from './SideNavFilter.styl'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {boolean} isFolded
|
* @param {boolean} isFolded
|
||||||
@@ -31,7 +32,7 @@ const SideNavFilter = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span styleName='menu-button-label'>All Notes</span>
|
<span styleName='menu-button-label'>{i18n.__('All Notes')}</span>
|
||||||
<span styleName='counters'>{counterTotalNote}</span>
|
<span styleName='counters'>{counterTotalNote}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ const SideNavFilter = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span styleName='menu-button-label'>Starred</span>
|
<span styleName='menu-button-label'>{i18n.__('Starred')}</span>
|
||||||
<span styleName='counters'>{counterStarredNote}</span>
|
<span styleName='counters'>{counterStarredNote}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -59,7 +60,7 @@ const SideNavFilter = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span onContextMenu={handleFilterButtonContextMenu} styleName='menu-button-label'>Trash</span>
|
<span onContextMenu={handleFilterButtonContextMenu} styleName='menu-button-label'>{i18n.__('Trash')}</span>
|
||||||
<span styleName='counters'>{counterDelNote}</span>
|
<span styleName='counters'>{counterDelNote}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,18 @@ import React from 'react'
|
|||||||
import styles from './StorageItem.styl'
|
import styles from './StorageItem.styl'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import { SortableHandle } from 'react-sortable-hoc'
|
||||||
|
|
||||||
|
const DraggableIcon = SortableHandle(({ className }) => (
|
||||||
|
<i className={`fa ${className}`} />
|
||||||
|
))
|
||||||
|
|
||||||
|
const FolderIcon = ({ className, color, isActive }) => {
|
||||||
|
const iconStyle = isActive ? 'fa-folder-open-o' : 'fa-folder-o'
|
||||||
|
return (
|
||||||
|
<i className={`fa ${iconStyle} ${className}`} style={{ color: color }} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {boolean} isActive
|
* @param {boolean} isActive
|
||||||
@@ -21,34 +33,54 @@ import _ from 'lodash'
|
|||||||
* @return {React.Component}
|
* @return {React.Component}
|
||||||
*/
|
*/
|
||||||
const StorageItem = ({
|
const StorageItem = ({
|
||||||
isActive, handleButtonClick, handleContextMenu, folderName,
|
styles,
|
||||||
folderColor, isFolded, noteCount, handleDrop, handleDragEnter, handleDragLeave
|
isActive,
|
||||||
}) => (
|
handleButtonClick,
|
||||||
<button styleName={isActive
|
handleContextMenu,
|
||||||
? 'folderList-item--active'
|
folderName,
|
||||||
: 'folderList-item'
|
folderColor,
|
||||||
}
|
isFolded,
|
||||||
|
noteCount,
|
||||||
|
handleDrop,
|
||||||
|
handleDragEnter,
|
||||||
|
handleDragLeave
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
styleName={isActive ? 'folderList-item--active' : 'folderList-item'}
|
||||||
onClick={handleButtonClick}
|
onClick={handleButtonClick}
|
||||||
onContextMenu={handleContextMenu}
|
onContextMenu={handleContextMenu}
|
||||||
onDrop={handleDrop}
|
onDrop={handleDrop}
|
||||||
onDragEnter={handleDragEnter}
|
onDragEnter={handleDragEnter}
|
||||||
onDragLeave={handleDragLeave}
|
onDragLeave={handleDragLeave}
|
||||||
>
|
>
|
||||||
<span styleName={isFolded
|
{!isFolded && (
|
||||||
? 'folderList-item-name--folded' : 'folderList-item-name'
|
<DraggableIcon className={styles['folderList-item-reorder']} />
|
||||||
}>
|
)}
|
||||||
<text style={{color: folderColor, paddingRight: '10px'}}>{isActive ? <i className='fa fa-folder-open-o' /> : <i className='fa fa-folder-o' />}</text>{isFolded ? _.truncate(folderName, {length: 1, omission: ''}) : folderName}
|
<span
|
||||||
|
styleName={
|
||||||
|
isFolded ? 'folderList-item-name--folded' : 'folderList-item-name'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FolderIcon
|
||||||
|
styleName='folderList-item-icon'
|
||||||
|
color={folderColor}
|
||||||
|
isActive={isActive}
|
||||||
|
/>
|
||||||
|
{isFolded
|
||||||
|
? _.truncate(folderName, { length: 1, omission: '' })
|
||||||
|
: folderName}
|
||||||
</span>
|
</span>
|
||||||
{(!isFolded && _.isNumber(noteCount)) &&
|
{!isFolded &&
|
||||||
|
_.isNumber(noteCount) && (
|
||||||
<span styleName='folderList-item-noteCount'>{noteCount}</span>
|
<span styleName='folderList-item-noteCount'>{noteCount}</span>
|
||||||
}
|
)}
|
||||||
{isFolded &&
|
{isFolded && (
|
||||||
<span styleName='folderList-item-tooltip'>
|
<span styleName='folderList-item-tooltip'>{folderName}</span>
|
||||||
{folderName}
|
)}
|
||||||
</span>
|
|
||||||
}
|
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
StorageItem.propTypes = {
|
StorageItem.propTypes = {
|
||||||
isActive: PropTypes.bool.isRequired,
|
isActive: PropTypes.bool.isRequired,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
border none
|
border none
|
||||||
overflow ellipsis
|
overflow ellipsis
|
||||||
font-size 14px
|
font-size 14px
|
||||||
|
align-items: center
|
||||||
&:first-child
|
&:first-child
|
||||||
margin-top 0
|
margin-top 0
|
||||||
&:hover
|
&:hover
|
||||||
@@ -34,9 +35,7 @@
|
|||||||
.folderList-item-name
|
.folderList-item-name
|
||||||
display block
|
display block
|
||||||
flex 1
|
flex 1
|
||||||
padding 0 12px
|
padding-right: 10px
|
||||||
height 26px
|
|
||||||
line-height 26px
|
|
||||||
border-width 0 0 0 2px
|
border-width 0 0 0 2px
|
||||||
border-style solid
|
border-style solid
|
||||||
border-color transparent
|
border-color transparent
|
||||||
@@ -69,9 +68,20 @@
|
|||||||
.folderList-item-name--folded
|
.folderList-item-name--folded
|
||||||
@extend .folderList-item-name
|
@extend .folderList-item-name
|
||||||
padding-left 7px
|
padding-left 7px
|
||||||
text
|
.folderList-item-icon
|
||||||
font-size 9px
|
font-size 9px
|
||||||
|
|
||||||
|
.folderList-item-icon
|
||||||
|
padding-right: 10px
|
||||||
|
|
||||||
|
.folderList-item-reorder
|
||||||
|
font-size: 9px
|
||||||
|
padding: 10px 8px 10px 9px;
|
||||||
|
color: rgba(147, 147, 149, 0.3)
|
||||||
|
cursor: ns-resize
|
||||||
|
&:before
|
||||||
|
content: "\f142 \f142"
|
||||||
|
|
||||||
body[data-theme="white"]
|
body[data-theme="white"]
|
||||||
.folderList-item
|
.folderList-item
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
|
|||||||
8
browser/lib/i18n.js
Normal file
8
browser/lib/i18n.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// load package for localization
|
||||||
|
const i18n = new (require('i18n-2'))({
|
||||||
|
// setup some locales - other locales default to the first locale
|
||||||
|
locales: ['en', 'sq', 'zh-CN', 'zh-TW', 'da', 'fr', 'de', 'ja', 'ko', 'no', 'pl', 'pt', 'es'],
|
||||||
|
extension: '.json'
|
||||||
|
})
|
||||||
|
|
||||||
|
export default i18n
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
|
const uuidv4 = require('uuid/v4')
|
||||||
|
|
||||||
module.exports = function (length) {
|
module.exports = function (uuid) {
|
||||||
if (!_.isFinite(length)) length = 10
|
if (typeof uuid === typeof true && uuid) {
|
||||||
|
return uuidv4()
|
||||||
|
}
|
||||||
|
const length = 10
|
||||||
return crypto.randomBytes(length).toString('hex')
|
return crypto.randomBytes(length).toString('hex')
|
||||||
}
|
}
|
||||||
|
|||||||
23
browser/lib/markdown-it-sanitize-html.js
Normal file
23
browser/lib/markdown-it-sanitize-html.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
import sanitizeHtml from 'sanitize-html'
|
||||||
|
|
||||||
|
module.exports = function sanitizePlugin (md, options) {
|
||||||
|
options = options || {}
|
||||||
|
|
||||||
|
md.core.ruler.after('linkify', 'sanitize_inline', state => {
|
||||||
|
for (let tokenIdx = 0; tokenIdx < state.tokens.length; tokenIdx++) {
|
||||||
|
if (state.tokens[tokenIdx].type === 'html_block') {
|
||||||
|
state.tokens[tokenIdx].content = sanitizeHtml(state.tokens[tokenIdx].content, options)
|
||||||
|
}
|
||||||
|
if (state.tokens[tokenIdx].type === 'inline') {
|
||||||
|
const inlineTokens = state.tokens[tokenIdx].children
|
||||||
|
for (let childIdx = 0; childIdx < inlineTokens.length; childIdx++) {
|
||||||
|
if (inlineTokens[childIdx].type === 'html_inline') {
|
||||||
|
inlineTokens[childIdx].content = sanitizeHtml(inlineTokens[childIdx].content, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
import markdownit from 'markdown-it'
|
import markdownit from 'markdown-it'
|
||||||
|
import sanitize from './markdown-it-sanitize-html'
|
||||||
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 _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import ConfigManager from 'browser/main/lib/ConfigManager'
|
import ConfigManager from 'browser/main/lib/ConfigManager'
|
||||||
|
import katex from 'katex'
|
||||||
import {lastFindInArray} from './utils'
|
import {lastFindInArray} from './utils'
|
||||||
|
|
||||||
// FIXME We should not depend on global variable.
|
|
||||||
const katex = window.katex
|
|
||||||
const config = ConfigManager.get()
|
|
||||||
|
|
||||||
function createGutter (str, firstLineNumber) {
|
function createGutter (str, firstLineNumber) {
|
||||||
if (Number.isNaN(firstLineNumber)) firstLineNumber = 1
|
if (Number.isNaN(firstLineNumber)) firstLineNumber = 1
|
||||||
const lastLineNumber = (str.match(/\n/g) || []).length + firstLineNumber - 1
|
const lastLineNumber = (str.match(/\n/g) || []).length + firstLineNumber - 1
|
||||||
@@ -19,8 +17,11 @@ function createGutter (str, firstLineNumber) {
|
|||||||
return '<span class="lineNumber CodeMirror-gutters">' + lines.join('') + '</span>'
|
return '<span class="lineNumber CodeMirror-gutters">' + lines.join('') + '</span>'
|
||||||
}
|
}
|
||||||
|
|
||||||
var md = markdownit({
|
class Markdown {
|
||||||
typographer: true,
|
constructor (options = {}) {
|
||||||
|
const config = ConfigManager.get()
|
||||||
|
const defaultOptions = {
|
||||||
|
typographer: config.preview.smartQuotes,
|
||||||
linkify: true,
|
linkify: true,
|
||||||
html: true,
|
html: true,
|
||||||
xhtmlOut: true,
|
xhtmlOut: true,
|
||||||
@@ -38,18 +39,63 @@ var md = markdownit({
|
|||||||
if (langType === 'sequence') {
|
if (langType === 'sequence') {
|
||||||
return `<pre class="sequence">${str}</pre>`
|
return `<pre class="sequence">${str}</pre>`
|
||||||
}
|
}
|
||||||
return '<pre class="code">' +
|
return '<pre class="code CodeMirror">' +
|
||||||
'<span class="filename">' + fileName + '</span>' +
|
'<span class="filename">' + fileName + '</span>' +
|
||||||
createGutter(str, firstLineNumber) +
|
createGutter(str, firstLineNumber) +
|
||||||
'<code class="' + langType + '">' +
|
'<code class="' + langType + '">' +
|
||||||
str +
|
str +
|
||||||
'</code></pre>'
|
'</code></pre>'
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
md.use(emoji, {
|
|
||||||
|
const updatedOptions = Object.assign(defaultOptions, options)
|
||||||
|
this.md = markdownit(updatedOptions)
|
||||||
|
|
||||||
|
// Sanitize use rinput before other plugins
|
||||||
|
this.md.use(sanitize, {
|
||||||
|
allowedTags: ['iframe', 'input', 'b',
|
||||||
|
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8', 'br', 'b', 'i', 'strong', 'em', 'a', 'pre', 'code', 'img', 'tt',
|
||||||
|
'div', 'ins', 'del', 'sup', 'sub', 'p', 'ol', 'ul', 'table', 'thead', 'tbody', 'tfoot', 'blockquote',
|
||||||
|
'dl', 'dt', 'dd', 'kbd', 'q', 'samp', 'var', 'hr', 'ruby', 'rt', 'rp', 'li', 'tr', 'td', 'th', 's', 'strike', 'summary', 'details'
|
||||||
|
],
|
||||||
|
allowedAttributes: {
|
||||||
|
'*': [
|
||||||
|
'style',
|
||||||
|
'abbr', 'accept', 'accept-charset',
|
||||||
|
'accesskey', 'action', 'align', 'alt', 'axis',
|
||||||
|
'border', 'cellpadding', 'cellspacing', 'char',
|
||||||
|
'charoff', 'charset', 'checked',
|
||||||
|
'clear', 'cols', 'colspan', 'color',
|
||||||
|
'compact', 'coords', 'datetime', 'dir',
|
||||||
|
'disabled', 'enctype', 'for', 'frame',
|
||||||
|
'headers', 'height', 'hreflang',
|
||||||
|
'hspace', 'ismap', 'label', 'lang',
|
||||||
|
'maxlength', 'media', 'method',
|
||||||
|
'multiple', 'name', 'nohref', 'noshade',
|
||||||
|
'nowrap', 'open', 'prompt', 'readonly', 'rel', 'rev',
|
||||||
|
'rows', 'rowspan', 'rules', 'scope',
|
||||||
|
'selected', 'shape', 'size', 'span',
|
||||||
|
'start', 'summary', 'tabindex', 'target',
|
||||||
|
'title', 'type', 'usemap', 'valign', 'value',
|
||||||
|
'vspace', 'width', 'itemprop'
|
||||||
|
],
|
||||||
|
'a': ['href'],
|
||||||
|
'div': ['itemscope', 'itemtype'],
|
||||||
|
'blockquote': ['cite'],
|
||||||
|
'del': ['cite'],
|
||||||
|
'ins': ['cite'],
|
||||||
|
'q': ['cite'],
|
||||||
|
'img': ['src', 'width', 'height'],
|
||||||
|
'iframe': ['src', 'width', 'height', 'frameborder', 'allowfullscreen'],
|
||||||
|
'input': ['type', 'id', 'checked']
|
||||||
|
},
|
||||||
|
allowedIframeHostnames: ['www.youtube.com']
|
||||||
|
})
|
||||||
|
|
||||||
|
this.md.use(emoji, {
|
||||||
shortcuts: {}
|
shortcuts: {}
|
||||||
})
|
})
|
||||||
md.use(math, {
|
this.md.use(math, {
|
||||||
inlineOpen: config.preview.latexInlineOpen,
|
inlineOpen: config.preview.latexInlineOpen,
|
||||||
inlineClose: config.preview.latexInlineClose,
|
inlineClose: config.preview.latexInlineClose,
|
||||||
blockOpen: config.preview.latexBlockOpen,
|
blockOpen: config.preview.latexBlockOpen,
|
||||||
@@ -72,22 +118,22 @@ md.use(math, {
|
|||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
md.use(require('markdown-it-imsize'))
|
this.md.use(require('markdown-it-imsize'))
|
||||||
md.use(require('markdown-it-footnote'))
|
this.md.use(require('markdown-it-footnote'))
|
||||||
md.use(require('markdown-it-multimd-table'))
|
this.md.use(require('markdown-it-multimd-table'))
|
||||||
md.use(require('markdown-it-named-headers'), {
|
this.md.use(require('markdown-it-named-headers'), {
|
||||||
slugify: (header) => {
|
slugify: (header) => {
|
||||||
return encodeURI(header.trim()
|
return encodeURI(header.trim()
|
||||||
.replace(/[\]\[\!\"\#\$\%\&\'\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~]/g, '')
|
.replace(/[\]\[\!\"\#\$\%\&\'\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~]/g, '')
|
||||||
.replace(/\s+/g, '-'))
|
.replace(/\s+/g, '-'))
|
||||||
.replace(/\-+$/, '')
|
.replace(/\-+$/, '')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
md.use(require('markdown-it-kbd'))
|
this.md.use(require('markdown-it-kbd'))
|
||||||
|
|
||||||
const deflate = require('markdown-it-plantuml/lib/deflate')
|
const deflate = require('markdown-it-plantuml/lib/deflate')
|
||||||
md.use(require('markdown-it-plantuml'), '', {
|
this.md.use(require('markdown-it-plantuml'), '', {
|
||||||
generateSource: function (umlCode) {
|
generateSource: function (umlCode) {
|
||||||
const s = unescape(encodeURIComponent(umlCode))
|
const s = unescape(encodeURIComponent(umlCode))
|
||||||
const zippedCode = deflate.encode64(
|
const zippedCode = deflate.encode64(
|
||||||
@@ -95,10 +141,10 @@ md.use(require('markdown-it-plantuml'), '', {
|
|||||||
)
|
)
|
||||||
return `http://www.plantuml.com/plantuml/svg/${zippedCode}`
|
return `http://www.plantuml.com/plantuml/svg/${zippedCode}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Override task item
|
// Override task item
|
||||||
md.block.ruler.at('paragraph', function (state, startLine/*, endLine */) {
|
this.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
|
||||||
const terminatorRules = state.md.block.ruler.getRules('paragraph')
|
const terminatorRules = state.md.block.ruler.getRules('paragraph')
|
||||||
@@ -153,11 +199,11 @@ md.block.ruler.at('paragraph', function (state, startLine/*, endLine */) {
|
|||||||
token = state.push('paragraph_close', 'p', -1)
|
token = state.push('paragraph_close', 'p', -1)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
// Add line number attribute for scrolling
|
// Add line number attribute for scrolling
|
||||||
const originalRender = md.renderer.render
|
const originalRender = this.md.renderer.render
|
||||||
md.renderer.render = function render (tokens, options, env) {
|
this.md.renderer.render = (tokens, options, env) => {
|
||||||
tokens.forEach((token) => {
|
tokens.forEach((token) => {
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
case 'heading_open':
|
case 'heading_open':
|
||||||
@@ -167,23 +213,22 @@ md.renderer.render = function render (tokens, options, env) {
|
|||||||
token.attrPush(['data-line', token.map[0]])
|
token.attrPush(['data-line', token.map[0]])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const result = originalRender.call(md.renderer, tokens, options, env)
|
const result = originalRender.call(this.md.renderer, tokens, options, env)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
// FIXME We should not depend on global variable.
|
// FIXME We should not depend on global variable.
|
||||||
window.md = md
|
window.md = this.md
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeLinkText (linkText) {
|
render (content) {
|
||||||
return md.normalizeLinkText(linkText)
|
|
||||||
}
|
|
||||||
|
|
||||||
const markdown = {
|
|
||||||
render: function markdown (content) {
|
|
||||||
if (!_.isString(content)) content = ''
|
if (!_.isString(content)) content = ''
|
||||||
const renderedContent = md.render(content)
|
return this.md.render(content)
|
||||||
return renderedContent
|
}
|
||||||
},
|
|
||||||
normalizeLinkText
|
normalizeLinkText (linkText) {
|
||||||
|
return this.md.normalizeLinkText(linkText)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default markdown
|
export default Markdown
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import React from 'react'
|
|||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './InfoPanel.styl'
|
import styles from './InfoPanel.styl'
|
||||||
import copy from 'copy-to-clipboard'
|
import copy from 'copy-to-clipboard'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
class InfoPanel extends React.Component {
|
class InfoPanel extends React.Component {
|
||||||
copyNoteLink () {
|
copyNoteLink () {
|
||||||
@@ -19,7 +20,7 @@ class InfoPanel extends React.Component {
|
|||||||
<div className='infoPanel' styleName='control-infoButton-panel' style={{display: 'none'}}>
|
<div className='infoPanel' styleName='control-infoButton-panel' style={{display: 'none'}}>
|
||||||
<div>
|
<div>
|
||||||
<p styleName='modification-date'>{updatedAt}</p>
|
<p styleName='modification-date'>{updatedAt}</p>
|
||||||
<p styleName='modification-date-desc'>MODIFICATION DATE</p>
|
<p styleName='modification-date-desc'>{i18n.__('MODIFICATION DATE')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
@@ -29,11 +30,11 @@ class InfoPanel extends React.Component {
|
|||||||
: <div styleName='count-wrap'>
|
: <div styleName='count-wrap'>
|
||||||
<div styleName='count-number'>
|
<div styleName='count-number'>
|
||||||
<p styleName='infoPanel-defaul-count'>{wordCount}</p>
|
<p styleName='infoPanel-defaul-count'>{wordCount}</p>
|
||||||
<p styleName='infoPanel-sub-count'>Words</p>
|
<p styleName='infoPanel-sub-count'>{i18n.__('Words')}</p>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='count-number'>
|
<div styleName='count-number'>
|
||||||
<p styleName='infoPanel-defaul-count'>{letterCount}</p>
|
<p styleName='infoPanel-defaul-count'>{letterCount}</p>
|
||||||
<p styleName='infoPanel-sub-count'>Letters</p>
|
<p styleName='infoPanel-sub-count'>{i18n.__('Letters')}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -45,17 +46,17 @@ class InfoPanel extends React.Component {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p styleName='infoPanel-default'>{storageName}</p>
|
<p styleName='infoPanel-default'>{storageName}</p>
|
||||||
<p styleName='infoPanel-sub'>STORAGE</p>
|
<p styleName='infoPanel-sub'>{i18n.__('STORAGE')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p styleName='infoPanel-default'>{folderName}</p>
|
<p styleName='infoPanel-default'>{folderName}</p>
|
||||||
<p styleName='infoPanel-sub'>FOLDER</p>
|
<p styleName='infoPanel-sub'>{i18n.__('FOLDER')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p styleName='infoPanel-default'>{createdAt}</p>
|
<p styleName='infoPanel-default'>{createdAt}</p>
|
||||||
<p styleName='infoPanel-sub'>CREATION DATE</p>
|
<p styleName='infoPanel-sub'>{i18n.__('CREATION DATE')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@@ -63,7 +64,7 @@ class InfoPanel extends React.Component {
|
|||||||
<button onClick={() => this.copyNoteLink()} styleName='infoPanel-copyButton'>
|
<button onClick={() => this.copyNoteLink()} styleName='infoPanel-copyButton'>
|
||||||
<i className='fa fa-clipboard' />
|
<i className='fa fa-clipboard' />
|
||||||
</button>
|
</button>
|
||||||
<p styleName='infoPanel-sub'>NOTE LINK</p>
|
<p styleName='infoPanel-sub'>{i18n.__('NOTE LINK')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
@@ -71,22 +72,22 @@ class InfoPanel extends React.Component {
|
|||||||
<div id='export-wrap'>
|
<div id='export-wrap'>
|
||||||
<button styleName='export--enable' onClick={(e) => exportAsMd(e)}>
|
<button styleName='export--enable' onClick={(e) => exportAsMd(e)}>
|
||||||
<i className='fa fa-file-code-o' />
|
<i className='fa fa-file-code-o' />
|
||||||
<p>.md</p>
|
<p>{i18n.__('.md')}</p>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button styleName='export--enable' onClick={(e) => exportAsTxt(e)}>
|
<button styleName='export--enable' onClick={(e) => exportAsTxt(e)}>
|
||||||
<i className='fa fa-file-text-o' />
|
<i className='fa fa-file-text-o' />
|
||||||
<p>.txt</p>
|
<p>{i18n.__('.txt')}</p>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button styleName='export--enable' onClick={(e) => exportAsHtml(e)}>
|
<button styleName='export--enable' onClick={(e) => exportAsHtml(e)}>
|
||||||
<i className='fa fa-html5' />
|
<i className='fa fa-html5' />
|
||||||
<p>.html</p>
|
<p>{i18n.__('.html')}</p>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button styleName='export--enable' onClick={(e) => print(e)}>
|
<button styleName='export--enable' onClick={(e) => print(e)}>
|
||||||
<i className='fa fa-print' />
|
<i className='fa fa-print' />
|
||||||
<p>Print</p>
|
<p>{i18n.__('Print')}</p>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './InfoPanel.styl'
|
import styles from './InfoPanel.styl'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const InfoPanelTrashed = ({
|
const InfoPanelTrashed = ({
|
||||||
storageName, folderName, updatedAt, createdAt, exportAsMd, exportAsTxt, exportAsHtml
|
storageName, folderName, updatedAt, createdAt, exportAsMd, exportAsTxt, exportAsHtml
|
||||||
@@ -9,24 +10,24 @@ const InfoPanelTrashed = ({
|
|||||||
<div className='infoPanel' styleName='control-infoButton-panel-trash' style={{display: 'none'}}>
|
<div className='infoPanel' styleName='control-infoButton-panel-trash' style={{display: 'none'}}>
|
||||||
<div>
|
<div>
|
||||||
<p styleName='modification-date'>{updatedAt}</p>
|
<p styleName='modification-date'>{updatedAt}</p>
|
||||||
<p styleName='modification-date-desc'>MODIFICATION DATE</p>
|
<p styleName='modification-date-desc'>{i18n.__('MODIFICATION DATE')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p styleName='infoPanel-default'>{storageName}</p>
|
<p styleName='infoPanel-default'>{storageName}</p>
|
||||||
<p styleName='infoPanel-sub'>STORAGE</p>
|
<p styleName='infoPanel-sub'>{i18n.__('STORAGE')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p styleName='infoPanel-default'><text styleName='infoPanel-trash'>Trash</text>{folderName}</p>
|
<p styleName='infoPanel-default'><text styleName='infoPanel-trash'>Trash</text>{folderName}</p>
|
||||||
<p styleName='infoPanel-sub'>FOLDER</p>
|
<p styleName='infoPanel-sub'>{i18n.__('FOLDER')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p styleName='infoPanel-default'>{createdAt}</p>
|
<p styleName='infoPanel-default'>{createdAt}</p>
|
||||||
<p styleName='infoPanel-sub'>CREATION DATE</p>
|
<p styleName='infoPanel-sub'>{i18n.__('CREATION DATE')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id='export-wrap'>
|
<div id='export-wrap'>
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
hashHistory.replace({
|
hashHistory.replace({
|
||||||
pathname: location.pathname,
|
pathname: location.pathname,
|
||||||
query: {
|
query: {
|
||||||
key: newNote.storage + '-' + newNote.key
|
key: newNote.key
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -393,7 +393,7 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
<InfoPanel
|
<InfoPanel
|
||||||
storageName={currentOption.storage.name}
|
storageName={currentOption.storage.name}
|
||||||
folderName={currentOption.folder.name}
|
folderName={currentOption.folder.name}
|
||||||
noteLink={`[${note.title}](${location.query.key})`}
|
noteLink={`[${note.title}](:note:${location.query.key})`}
|
||||||
updatedAt={formatDate(note.updatedAt)}
|
updatedAt={formatDate(note.updatedAt)}
|
||||||
createdAt={formatDate(note.createdAt)}
|
createdAt={formatDate(note.createdAt)}
|
||||||
exportAsMd={this.exportAsMd}
|
exportAsMd={this.exportAsMd}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './TrashButton.styl'
|
import styles from './TrashButton.styl'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const PermanentDeleteButton = ({
|
const PermanentDeleteButton = ({
|
||||||
onClick
|
onClick
|
||||||
@@ -10,7 +11,7 @@ const PermanentDeleteButton = ({
|
|||||||
onClick={(e) => onClick(e)}
|
onClick={(e) => onClick(e)}
|
||||||
>
|
>
|
||||||
<img styleName='iconInfo' src='../resources/icon/icon-trash.svg' />
|
<img styleName='iconInfo' src='../resources/icon/icon-trash.svg' />
|
||||||
<span styleName='tooltip'>Permanent Delete</span>
|
<span styleName='tooltip'>{i18n.__('Permanent Delete')}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './RestoreButton.styl'
|
import styles from './RestoreButton.styl'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const RestoreButton = ({
|
const RestoreButton = ({
|
||||||
onClick
|
onClick
|
||||||
@@ -10,7 +11,7 @@ const RestoreButton = ({
|
|||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
<i className='fa fa-undo fa-fw' styleName='iconRestore' />
|
<i className='fa fa-undo fa-fw' styleName='iconRestore' />
|
||||||
<span styleName='tooltip'>Restore</span>
|
<span styleName='tooltip'>{i18n.__('Restore')}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ import PermanentDeleteButton from './PermanentDeleteButton'
|
|||||||
import InfoButton from './InfoButton'
|
import InfoButton from './InfoButton'
|
||||||
import InfoPanel from './InfoPanel'
|
import InfoPanel from './InfoPanel'
|
||||||
import InfoPanelTrashed from './InfoPanelTrashed'
|
import InfoPanelTrashed from './InfoPanelTrashed'
|
||||||
import {formatDate} from 'browser/lib/date-formatter'
|
import { formatDate } from 'browser/lib/date-formatter'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
function pass (name) {
|
function pass (name) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
@@ -166,7 +167,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
hashHistory.replace({
|
hashHistory.replace({
|
||||||
pathname: location.pathname,
|
pathname: location.pathname,
|
||||||
query: {
|
query: {
|
||||||
key: newNote.storage + '-' + newNote.key
|
key: newNote.key
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -328,9 +329,9 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
if (this.state.note.snippets[index].content.trim().length > 0) {
|
if (this.state.note.snippets[index].content.trim().length > 0) {
|
||||||
const dialogIndex = dialog.showMessageBox(remote.getCurrentWindow(), {
|
const dialogIndex = dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Delete a snippet',
|
message: i18n.__('Delete a snippet'),
|
||||||
detail: 'This work cannot be undone.',
|
detail: i18n.__('This work cannot be undone.'),
|
||||||
buttons: ['Confirm', 'Cancel']
|
buttons: [i18n.__('Confirm'), i18n.__('Cancel')]
|
||||||
})
|
})
|
||||||
if (dialogIndex === 0) {
|
if (dialogIndex === 0) {
|
||||||
this.deleteSnippetByIndex(index)
|
this.deleteSnippetByIndex(index)
|
||||||
@@ -422,6 +423,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
|
|
||||||
handleKeyDown (e) {
|
handleKeyDown (e) {
|
||||||
switch (e.keyCode) {
|
switch (e.keyCode) {
|
||||||
|
// tab key
|
||||||
case 9:
|
case 9:
|
||||||
if (e.ctrlKey && !e.shiftKey) {
|
if (e.ctrlKey && !e.shiftKey) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@@ -434,6 +436,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
this.focusEditor()
|
this.focusEditor()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
// L key
|
||||||
case 76:
|
case 76:
|
||||||
{
|
{
|
||||||
const isSuper = global.process.platform === 'darwin'
|
const isSuper = global.process.platform === 'darwin'
|
||||||
@@ -445,6 +448,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
// T key
|
||||||
case 84:
|
case 84:
|
||||||
{
|
{
|
||||||
const isSuper = global.process.platform === 'darwin'
|
const isSuper = global.process.platform === 'darwin'
|
||||||
@@ -634,8 +638,8 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
showWarning () {
|
showWarning () {
|
||||||
dialog.showMessageBox(remote.getCurrentWindow(), {
|
dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Sorry!',
|
message: i18n.__('Sorry!'),
|
||||||
detail: 'md/text import is available only a markdown note.',
|
detail: i18n.__('md/text import is available only a markdown note.'),
|
||||||
buttons: ['OK']
|
buttons: ['OK']
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -777,7 +781,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
<InfoPanel
|
<InfoPanel
|
||||||
storageName={currentOption.storage.name}
|
storageName={currentOption.storage.name}
|
||||||
folderName={currentOption.folder.name}
|
folderName={currentOption.folder.name}
|
||||||
noteLink={`[${note.title}](${location.query.key})`}
|
noteLink={`[${note.title}](:note:${location.query.key})`}
|
||||||
updatedAt={formatDate(note.updatedAt)}
|
updatedAt={formatDate(note.updatedAt)}
|
||||||
createdAt={formatDate(note.createdAt)}
|
createdAt={formatDate(note.createdAt)}
|
||||||
exportAsMd={this.showWarning}
|
exportAsMd={this.showWarning}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './ToggleModeButton.styl'
|
import styles from './ToggleModeButton.styl'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const ToggleModeButton = ({
|
const ToggleModeButton = ({
|
||||||
onClick, editorType
|
onClick, editorType
|
||||||
@@ -13,7 +14,7 @@ const ToggleModeButton = ({
|
|||||||
<div styleName={editorType === 'EDITOR_PREVIEW' ? 'active' : 'non-active'} onClick={() => onClick('EDITOR_PREVIEW')}>
|
<div styleName={editorType === 'EDITOR_PREVIEW' ? 'active' : 'non-active'} onClick={() => onClick('EDITOR_PREVIEW')}>
|
||||||
<img styleName='item-star' src={editorType === 'EDITOR_PREVIEW' ? '' : '../resources/icon/icon-mode-split-on-active.svg'} />
|
<img styleName='item-star' src={editorType === 'EDITOR_PREVIEW' ? '' : '../resources/icon/icon-mode-split-on-active.svg'} />
|
||||||
</div>
|
</div>
|
||||||
<span styleName='tooltip'>Toggle Mode</span>
|
<span styleName='tooltip'>{i18n.__('Toggle Mode')}</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './TrashButton.styl'
|
import styles from './TrashButton.styl'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const TrashButton = ({
|
const TrashButton = ({
|
||||||
onClick
|
onClick
|
||||||
@@ -10,7 +11,7 @@ const TrashButton = ({
|
|||||||
onClick={(e) => onClick(e)}
|
onClick={(e) => onClick(e)}
|
||||||
>
|
>
|
||||||
<img styleName='iconInfo' src='../resources/icon/icon-trash.svg' />
|
<img styleName='iconInfo' src='../resources/icon/icon-trash.svg' />
|
||||||
<span styleName='tooltip'>Trash</span>
|
<span styleName='tooltip'>{i18n.__('Trash')}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import MarkdownNoteDetail from './MarkdownNoteDetail'
|
|||||||
import SnippetNoteDetail from './SnippetNoteDetail'
|
import SnippetNoteDetail from './SnippetNoteDetail'
|
||||||
import ee from 'browser/main/lib/eventEmitter'
|
import ee from 'browser/main/lib/eventEmitter'
|
||||||
import StatusBar from '../StatusBar'
|
import StatusBar from '../StatusBar'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const OSX = global.process.platform === 'darwin'
|
const OSX = global.process.platform === 'darwin'
|
||||||
|
|
||||||
@@ -40,9 +41,9 @@ class Detail extends React.Component {
|
|||||||
|
|
||||||
const alertConfig = {
|
const alertConfig = {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Confirm note deletion',
|
message: i18n.__('Confirm note deletion'),
|
||||||
detail: 'This will permanently remove this note.',
|
detail: i18n.__('This will permanently remove this note.'),
|
||||||
buttons: ['Confirm', 'Cancel']
|
buttons: [i18n.__('Confirm'), i18n.__('Cancel')]
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), alertConfig)
|
const dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), alertConfig)
|
||||||
@@ -56,11 +57,8 @@ class Detail extends React.Component {
|
|||||||
const { location, data, config } = this.props
|
const { location, data, config } = this.props
|
||||||
let note = null
|
let note = null
|
||||||
if (location.query.key != null) {
|
if (location.query.key != null) {
|
||||||
const splitted = location.query.key.split('-')
|
const noteKey = location.query.key
|
||||||
const storageKey = splitted.shift()
|
note = data.noteMap.get(noteKey)
|
||||||
const noteKey = splitted.shift()
|
|
||||||
|
|
||||||
note = data.noteMap.get(storageKey + '-' + noteKey)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (note == null) {
|
if (note == null) {
|
||||||
@@ -70,7 +68,7 @@ class Detail extends React.Component {
|
|||||||
tabIndex='0'
|
tabIndex='0'
|
||||||
>
|
>
|
||||||
<div styleName='empty'>
|
<div styleName='empty'>
|
||||||
<div styleName='empty-message'>{OSX ? 'Command(⌘)' : 'Ctrl(^)'} + N<br />to create a new note</div>
|
<div styleName='empty-message'>{OSX ? i18n.__('Command(⌘)') : i18n.__('Ctrl(^)')} + N<br />{i18n.__('to create a new note')}</div>
|
||||||
</div>
|
</div>
|
||||||
<StatusBar
|
<StatusBar
|
||||||
{..._.pick(this.props, ['config', 'location', 'dispatch'])}
|
{..._.pick(this.props, ['config', 'location', 'dispatch'])}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import mobileAnalytics from 'browser/main/lib/AwsMobileAnalyticsConfig'
|
|||||||
import eventEmitter from 'browser/main/lib/eventEmitter'
|
import eventEmitter from 'browser/main/lib/eventEmitter'
|
||||||
import { hashHistory } from 'react-router'
|
import { hashHistory } from 'react-router'
|
||||||
import store from 'browser/main/store'
|
import store from 'browser/main/store'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const { remote } = electron
|
const { remote } = electron
|
||||||
@@ -148,6 +149,35 @@ class Main extends React.Component {
|
|||||||
} else {
|
} else {
|
||||||
document.body.setAttribute('data-theme', 'default')
|
document.body.setAttribute('data-theme', 'default')
|
||||||
}
|
}
|
||||||
|
if (config.ui.language === 'sq') {
|
||||||
|
i18n.setLocale('sq')
|
||||||
|
} else if (config.ui.language === 'zh-CN') {
|
||||||
|
i18n.setLocale('zh-CN')
|
||||||
|
} else if (config.ui.language === 'zh-TW') {
|
||||||
|
i18n.setLocale('zh-TW')
|
||||||
|
} else if (config.ui.language === 'da') {
|
||||||
|
i18n.setLocale('da')
|
||||||
|
} else if (config.ui.language === 'fr') {
|
||||||
|
i18n.setLocale('fr')
|
||||||
|
} else if (config.ui.language === 'de') {
|
||||||
|
i18n.setLocale('de')
|
||||||
|
} else if (config.ui.language === 'ja') {
|
||||||
|
i18n.setLocale('ja')
|
||||||
|
} else if (config.ui.language === 'ko') {
|
||||||
|
i18n.setLocale('ko')
|
||||||
|
} else if (config.ui.language === 'no') {
|
||||||
|
i18n.setLocale('no')
|
||||||
|
} else if (config.ui.language === 'pl') {
|
||||||
|
i18n.setLocale('pl')
|
||||||
|
} else if (config.ui.language === 'pt') {
|
||||||
|
i18n.setLocale('pt')
|
||||||
|
} else if (config.ui.language === 'ru') {
|
||||||
|
i18n.setLocale('ru')
|
||||||
|
} else if (config.ui.language === 'es') {
|
||||||
|
i18n.setLocale('es')
|
||||||
|
} else {
|
||||||
|
i18n.setLocale('en')
|
||||||
|
}
|
||||||
|
|
||||||
// Reload all data
|
// Reload all data
|
||||||
dataApi.init()
|
dataApi.init()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import _ from 'lodash'
|
|||||||
import modal from 'browser/main/lib/modal'
|
import modal from 'browser/main/lib/modal'
|
||||||
import NewNoteModal from 'browser/main/modals/NewNoteModal'
|
import NewNoteModal from 'browser/main/modals/NewNoteModal'
|
||||||
import eventEmitter from 'browser/main/lib/eventEmitter'
|
import eventEmitter from 'browser/main/lib/eventEmitter'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const { remote } = require('electron')
|
const { remote } = require('electron')
|
||||||
const { dialog } = remote
|
const { dialog } = remote
|
||||||
@@ -86,7 +87,7 @@ class NewNoteButton extends React.Component {
|
|||||||
onClick={(e) => this.handleNewNoteButtonClick(e)}>
|
onClick={(e) => this.handleNewNoteButtonClick(e)}>
|
||||||
<img styleName='iconTag' src='../resources/icon/icon-newnote.svg' />
|
<img styleName='iconTag' src='../resources/icon/icon-newnote.svg' />
|
||||||
<span styleName='control-newNoteButton-tooltip'>
|
<span styleName='control-newNoteButton-tooltip'>
|
||||||
Make a note {OSX ? '⌘' : 'Ctrl'} + N
|
{i18n.__('Make a note')} {OSX ? '⌘' : i18n.__('Ctrl')} + N
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* global electron */
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
@@ -13,10 +14,14 @@ import searchFromNotes from 'browser/lib/search'
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { hashHistory } from 'react-router'
|
import { hashHistory } from 'react-router'
|
||||||
|
import copy from 'copy-to-clipboard'
|
||||||
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
|
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
|
||||||
|
import Markdown from '../../lib/markdown'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const { remote } = require('electron')
|
const { remote } = require('electron')
|
||||||
const { Menu, MenuItem, dialog } = remote
|
const { Menu, MenuItem, dialog } = remote
|
||||||
|
const WP_POST_PATH = '/wp/v2/posts'
|
||||||
|
|
||||||
function sortByCreatedAt (a, b) {
|
function sortByCreatedAt (a, b) {
|
||||||
return new Date(b.createdAt) - new Date(a.createdAt)
|
return new Date(b.createdAt) - new Date(a.createdAt)
|
||||||
@@ -31,7 +36,7 @@ function sortByUpdatedAt (a, b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function findNoteByKey (notes, noteKey) {
|
function findNoteByKey (notes, noteKey) {
|
||||||
return notes.find((note) => `${note.storage}-${note.key}` === noteKey)
|
return notes.find((note) => note.key === noteKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
function findNotesByKeys (notes, noteKeys) {
|
function findNotesByKeys (notes, noteKeys) {
|
||||||
@@ -39,7 +44,7 @@ function findNotesByKeys (notes, noteKeys) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getNoteKey (note) {
|
function getNoteKey (note) {
|
||||||
return `${note.storage}-${note.key}`
|
return note.key
|
||||||
}
|
}
|
||||||
|
|
||||||
class NoteList extends React.Component {
|
class NoteList extends React.Component {
|
||||||
@@ -70,6 +75,7 @@ class NoteList extends React.Component {
|
|||||||
this.getNoteFolder = this.getNoteFolder.bind(this)
|
this.getNoteFolder = this.getNoteFolder.bind(this)
|
||||||
this.getViewType = this.getViewType.bind(this)
|
this.getViewType = this.getViewType.bind(this)
|
||||||
this.restoreNote = this.restoreNote.bind(this)
|
this.restoreNote = this.restoreNote.bind(this)
|
||||||
|
this.copyNoteLink = this.copyNoteLink.bind(this)
|
||||||
|
|
||||||
// TODO: not Selected noteKeys but SelectedNote(for reusing)
|
// TODO: not Selected noteKeys but SelectedNote(for reusing)
|
||||||
this.state = {
|
this.state = {
|
||||||
@@ -114,10 +120,10 @@ class NoteList extends React.Component {
|
|||||||
componentDidUpdate (prevProps) {
|
componentDidUpdate (prevProps) {
|
||||||
const { location } = this.props
|
const { location } = this.props
|
||||||
const { selectedNoteKeys } = this.state
|
const { selectedNoteKeys } = this.state
|
||||||
const visibleNoteKeys = this.notes.map(note => `${note.storage}-${note.key}`)
|
const visibleNoteKeys = this.notes.map(note => note.key)
|
||||||
const note = this.notes[0]
|
const note = this.notes[0]
|
||||||
const prevKey = prevProps.location.query.key
|
const prevKey = prevProps.location.query.key
|
||||||
const noteKey = visibleNoteKeys.includes(prevKey) ? prevKey : note && `${note.storage}-${note.key}`
|
const noteKey = visibleNoteKeys.includes(prevKey) ? prevKey : note && note.key
|
||||||
|
|
||||||
if (note && location.query.key == null) {
|
if (note && location.query.key == null) {
|
||||||
const { router } = this.context
|
const { router } = this.context
|
||||||
@@ -257,27 +263,38 @@ class NoteList extends React.Component {
|
|||||||
handleNoteListKeyDown (e) {
|
handleNoteListKeyDown (e) {
|
||||||
if (e.metaKey || e.ctrlKey) return true
|
if (e.metaKey || e.ctrlKey) return true
|
||||||
|
|
||||||
|
// A key
|
||||||
if (e.keyCode === 65 && !e.shiftKey) {
|
if (e.keyCode === 65 && !e.shiftKey) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
ee.emit('top:new-note')
|
ee.emit('top:new-note')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// D key
|
||||||
if (e.keyCode === 68) {
|
if (e.keyCode === 68) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.deleteNote()
|
this.deleteNote()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// E key
|
||||||
if (e.keyCode === 69) {
|
if (e.keyCode === 69) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
ee.emit('detail:focus')
|
ee.emit('detail:focus')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.keyCode === 38) {
|
// F or S key
|
||||||
|
if (e.keyCode === 70 || e.keyCode === 83) {
|
||||||
|
e.preventDefault()
|
||||||
|
ee.emit('top:focus-search')
|
||||||
|
}
|
||||||
|
|
||||||
|
// UP or K key
|
||||||
|
if (e.keyCode === 38 || e.keyCode === 75) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.selectPriorNote()
|
this.selectPriorNote()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.keyCode === 40) {
|
// DOWN or J key
|
||||||
|
if (e.keyCode === 40 || e.keyCode === 74) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.selectNextNote()
|
this.selectNextNote()
|
||||||
}
|
}
|
||||||
@@ -458,6 +475,10 @@ class NoteList extends React.Component {
|
|||||||
const deleteLabel = 'Delete Note'
|
const deleteLabel = 'Delete Note'
|
||||||
const cloneNote = 'Clone Note'
|
const cloneNote = 'Clone Note'
|
||||||
const restoreNote = 'Restore Note'
|
const restoreNote = 'Restore Note'
|
||||||
|
const copyNoteLink = 'Copy Note Link'
|
||||||
|
const publishLabel = 'Publish Blog'
|
||||||
|
const updateLabel = 'Update Blog'
|
||||||
|
const openBlogLabel = 'Open Blog'
|
||||||
|
|
||||||
const menu = new Menu()
|
const menu = new Menu()
|
||||||
if (!location.pathname.match(/\/starred|\/trash/)) {
|
if (!location.pathname.match(/\/starred|\/trash/)) {
|
||||||
@@ -482,6 +503,28 @@ class NoteList extends React.Component {
|
|||||||
label: cloneNote,
|
label: cloneNote,
|
||||||
click: this.cloneNote.bind(this)
|
click: this.cloneNote.bind(this)
|
||||||
}))
|
}))
|
||||||
|
menu.append(new MenuItem({
|
||||||
|
label: copyNoteLink,
|
||||||
|
click: this.copyNoteLink(note)
|
||||||
|
}))
|
||||||
|
if (note.type === 'MARKDOWN_NOTE') {
|
||||||
|
if (note.blog && note.blog.blogLink && note.blog.blogId) {
|
||||||
|
menu.append(new MenuItem({
|
||||||
|
label: updateLabel,
|
||||||
|
click: this.publishMarkdown.bind(this)
|
||||||
|
}))
|
||||||
|
menu.append(new MenuItem({
|
||||||
|
label: openBlogLabel,
|
||||||
|
click: () => this.openBlog.bind(this)(note)
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
menu.append(new MenuItem({
|
||||||
|
label: publishLabel,
|
||||||
|
click: this.publishMarkdown.bind(this)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
menu.popup()
|
menu.popup()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,11 +591,9 @@ class NoteList extends React.Component {
|
|||||||
})
|
})
|
||||||
if (dialogueButtonIndex === 1) return
|
if (dialogueButtonIndex === 1) return
|
||||||
Promise.all(
|
Promise.all(
|
||||||
selectedNoteKeys.map((uniqueKey) => {
|
selectedNotes.map((note) => {
|
||||||
const storageKey = uniqueKey.split('-')[0]
|
|
||||||
const noteKey = uniqueKey.split('-')[1]
|
|
||||||
return dataApi
|
return dataApi
|
||||||
.deleteNote(storageKey, noteKey)
|
.deleteNote(note.storage, note.key)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
@@ -613,23 +654,134 @@ class NoteList extends React.Component {
|
|||||||
content: firstNote.content
|
content: firstNote.content
|
||||||
})
|
})
|
||||||
.then((note) => {
|
.then((note) => {
|
||||||
const uniqueKey = note.storage + '-' + note.key
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'UPDATE_NOTE',
|
type: 'UPDATE_NOTE',
|
||||||
note: note
|
note: note
|
||||||
})
|
})
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
selectedNoteKeys: [uniqueKey]
|
selectedNoteKeys: [note.key]
|
||||||
})
|
})
|
||||||
|
|
||||||
hashHistory.push({
|
hashHistory.push({
|
||||||
pathname: location.pathname,
|
pathname: location.pathname,
|
||||||
query: {key: uniqueKey}
|
query: {key: note.key}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copyNoteLink (note) {
|
||||||
|
const noteLink = `[${note.title}](${note.key})`
|
||||||
|
return copy(noteLink)
|
||||||
|
}
|
||||||
|
|
||||||
|
save (note) {
|
||||||
|
const { dispatch } = this.props
|
||||||
|
dataApi
|
||||||
|
.updateNote(note.storage, note.key, note)
|
||||||
|
.then((note) => {
|
||||||
|
dispatch({
|
||||||
|
type: 'UPDATE_NOTE',
|
||||||
|
note: note
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
publishMarkdown () {
|
||||||
|
if (this.pendingPublish) {
|
||||||
|
clearTimeout(this.pendingPublish)
|
||||||
|
}
|
||||||
|
this.pendingPublish = setTimeout(() => {
|
||||||
|
this.publishMarkdownNow()
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
publishMarkdownNow () {
|
||||||
|
const {selectedNoteKeys} = this.state
|
||||||
|
const notes = this.notes.map((note) => Object.assign({}, note))
|
||||||
|
const selectedNotes = findNotesByKeys(notes, selectedNoteKeys)
|
||||||
|
const firstNote = selectedNotes[0]
|
||||||
|
const config = ConfigManager.get()
|
||||||
|
const {address, token, authMethod, username, password} = config.blog
|
||||||
|
let authToken = ''
|
||||||
|
if (authMethod === 'USER') {
|
||||||
|
authToken = `Basic ${window.btoa(`${username}:${password}`)}`
|
||||||
|
} else {
|
||||||
|
authToken = `Bearer ${token}`
|
||||||
|
}
|
||||||
|
const contentToRender = firstNote.content.replace(`# ${firstNote.title}`, '')
|
||||||
|
const markdown = new Markdown()
|
||||||
|
const data = {
|
||||||
|
title: firstNote.title,
|
||||||
|
content: markdown.render(contentToRender),
|
||||||
|
status: 'publish'
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = ''
|
||||||
|
let method = ''
|
||||||
|
if (firstNote.blog && firstNote.blog.blogId) {
|
||||||
|
url = `${address}${WP_POST_PATH}/${firstNote.blog.blogId}`
|
||||||
|
method = 'PUT'
|
||||||
|
} else {
|
||||||
|
url = `${address}${WP_POST_PATH}`
|
||||||
|
method = 'POST'
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
fetch(url, {
|
||||||
|
method: method,
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
headers: {
|
||||||
|
'Authorization': authToken,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
}).then(res => res.json())
|
||||||
|
.then(response => {
|
||||||
|
if (_.isNil(response.link) || _.isNil(response.id)) {
|
||||||
|
return Promise.reject()
|
||||||
|
}
|
||||||
|
firstNote.blog = {
|
||||||
|
blogLink: response.link,
|
||||||
|
blogId: response.id
|
||||||
|
}
|
||||||
|
this.save(firstNote)
|
||||||
|
this.confirmPublish(firstNote)
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error)
|
||||||
|
this.confirmPublishError()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmPublishError () {
|
||||||
|
const { remote } = electron
|
||||||
|
const { dialog } = remote
|
||||||
|
const alertError = {
|
||||||
|
type: 'warning',
|
||||||
|
message: 'Publish Failed',
|
||||||
|
detail: 'Check and update your blog setting and try again.',
|
||||||
|
buttons: ['Confirm']
|
||||||
|
}
|
||||||
|
dialog.showMessageBox(remote.getCurrentWindow(), alertError)
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmPublish (note) {
|
||||||
|
const buttonIndex = dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||||
|
type: 'warning',
|
||||||
|
message: 'Publish Succeeded',
|
||||||
|
detail: `${note.title} is published at ${note.blog.blogLink}`,
|
||||||
|
buttons: ['Confirm', 'Open Blog']
|
||||||
|
})
|
||||||
|
|
||||||
|
if (buttonIndex === 1) {
|
||||||
|
this.openBlog(note)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openBlog (note) {
|
||||||
|
const { shell } = electron
|
||||||
|
shell.openExternal(note.blog.blogLink)
|
||||||
|
}
|
||||||
|
|
||||||
importFromFile () {
|
importFromFile () {
|
||||||
const options = {
|
const options = {
|
||||||
filters: [
|
filters: [
|
||||||
@@ -844,13 +996,13 @@ class NoteList extends React.Component {
|
|||||||
value={config.sortBy}
|
value={config.sortBy}
|
||||||
onChange={(e) => this.handleSortByChange(e)}
|
onChange={(e) => this.handleSortByChange(e)}
|
||||||
>
|
>
|
||||||
<option title='Sort by update time' value='UPDATED_AT'>Updated</option>
|
<option title='Sort by update time' value='UPDATED_AT'>{i18n.__('Updated')}</option>
|
||||||
<option title='Sort by create time' value='CREATED_AT'>Created</option>
|
<option title='Sort by create time' value='CREATED_AT'>{i18n.__('Created')}</option>
|
||||||
<option title='Sort alphabetically' value='ALPHABETICAL'>Alphabetically</option>
|
<option title='Sort alphabetically' value='ALPHABETICAL'>{i18n.__('Alphabetically')}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='control-button-area'>
|
<div styleName='control-button-area'>
|
||||||
<button title='Default View' styleName={config.listStyle === 'DEFAULT'
|
<button title={i18n.__('Default View')} styleName={config.listStyle === 'DEFAULT'
|
||||||
? 'control-button--active'
|
? 'control-button--active'
|
||||||
: 'control-button'
|
: 'control-button'
|
||||||
}
|
}
|
||||||
@@ -858,7 +1010,7 @@ class NoteList extends React.Component {
|
|||||||
>
|
>
|
||||||
<img styleName='iconTag' src='../resources/icon/icon-column.svg' />
|
<img styleName='iconTag' src='../resources/icon/icon-column.svg' />
|
||||||
</button>
|
</button>
|
||||||
<button title='Compressed View' styleName={config.listStyle === 'SMALL'
|
<button title={i18n.__('Compressed View')} styleName={config.listStyle === 'SMALL'
|
||||||
? 'control-button--active'
|
? 'control-button--active'
|
||||||
: 'control-button'
|
: 'control-button'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './SwitchButton.styl'
|
import styles from './SwitchButton.styl'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const ListButton = ({
|
const ListButton = ({
|
||||||
onClick, isTagActive
|
onClick, isTagActive
|
||||||
@@ -12,7 +13,7 @@ const ListButton = ({
|
|||||||
: '../resources/icon/icon-list-active.svg'
|
: '../resources/icon/icon-list-active.svg'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<span styleName='tooltip'>Notes</span>
|
<span styleName='tooltip'>{i18n.__('Notes')}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,14 @@ import PropTypes from 'prop-types'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './PreferenceButton.styl'
|
import styles from './PreferenceButton.styl'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const PreferenceButton = ({
|
const PreferenceButton = ({
|
||||||
onClick
|
onClick
|
||||||
}) => (
|
}) => (
|
||||||
<button styleName='top-menu-preference' onClick={(e) => onClick(e)}>
|
<button styleName='top-menu-preference' onClick={(e) => onClick(e)}>
|
||||||
<img styleName='iconTag' src='../resources/icon/icon-setting.svg' />
|
<img styleName='iconTag' src='../resources/icon/icon-setting.svg' />
|
||||||
<span styleName='tooltip'>Preferences</span>
|
<span styleName='tooltip'>{i18n.__('Preferences')}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ 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'
|
import StorageItemChild from 'browser/components/StorageItem'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import { SortableElement } from 'react-sortable-hoc'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const { remote } = require('electron')
|
const { remote } = require('electron')
|
||||||
const { Menu, dialog } = remote
|
const { Menu, dialog } = remote
|
||||||
@@ -43,9 +45,9 @@ class StorageItem extends React.Component {
|
|||||||
handleUnlinkStorageClick (e) {
|
handleUnlinkStorageClick (e) {
|
||||||
const index = dialog.showMessageBox(remote.getCurrentWindow(), {
|
const index = dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Unlink Storage',
|
message: i18n.__('Unlink Storage'),
|
||||||
detail: 'This work will just detatches a storage from Boostnote. (Any data won\'t be deleted.)',
|
detail: i18n.__('This work will just detatches a storage from Boostnote. (Any data won\'t be deleted.)'),
|
||||||
buttons: ['Confirm', 'Cancel']
|
buttons: [i18n.__('Confirm'), i18n.__('Cancel')]
|
||||||
})
|
})
|
||||||
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
@@ -159,9 +161,9 @@ class StorageItem extends React.Component {
|
|||||||
handleFolderDeleteClick (e, folder) {
|
handleFolderDeleteClick (e, folder) {
|
||||||
const index = dialog.showMessageBox(remote.getCurrentWindow(), {
|
const index = dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Delete Folder',
|
message: i18n.__('Delete Folder'),
|
||||||
detail: 'This will delete all notes in the folder and can not be undone.',
|
detail: i18n.__('This will delete all notes in the folder and can not be undone.'),
|
||||||
buttons: ['Confirm', 'Cancel']
|
buttons: [i18n.__('Confirm'), i18n.__('Cancel')]
|
||||||
})
|
})
|
||||||
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
@@ -191,33 +193,16 @@ class StorageItem extends React.Component {
|
|||||||
dropNote (storage, folder, dispatch, location, noteData) {
|
dropNote (storage, folder, dispatch, location, noteData) {
|
||||||
noteData = noteData.filter((note) => folder.key !== note.folder)
|
noteData = noteData.filter((note) => folder.key !== note.folder)
|
||||||
if (noteData.length === 0) return
|
if (noteData.length === 0) return
|
||||||
const newNoteData = noteData.map((note) => Object.assign({}, note, {storage: storage, folder: folder.key}))
|
|
||||||
|
|
||||||
Promise.all(
|
Promise.all(
|
||||||
newNoteData.map((note) => dataApi.createNote(storage.key, note))
|
noteData.map((note) => dataApi.moveNote(note.storage, note.key, storage.key, folder.key))
|
||||||
)
|
)
|
||||||
.then((createdNoteData) => {
|
.then((createdNoteData) => {
|
||||||
createdNoteData.forEach((note) => {
|
createdNoteData.forEach((newNote) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'UPDATE_NOTE',
|
type: 'MOVE_NOTE',
|
||||||
note: note
|
originNote: noteData.find((note) => note.content === newNote.content),
|
||||||
})
|
note: newNote
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(`error on create notes: ${err}`)
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
return Promise.all(
|
|
||||||
noteData.map((note) => dataApi.deleteNote(note.storage, note.key))
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.then((deletedNoteData) => {
|
|
||||||
deletedNoteData.forEach((note) => {
|
|
||||||
dispatch({
|
|
||||||
type: 'DELETE_NOTE',
|
|
||||||
storageKey: note.storageKey,
|
|
||||||
noteKey: note.noteKey
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -236,7 +221,8 @@ class StorageItem extends React.Component {
|
|||||||
render () {
|
render () {
|
||||||
const { storage, location, isFolded, data, dispatch } = this.props
|
const { storage, location, isFolded, data, dispatch } = this.props
|
||||||
const { folderNoteMap, trashedSet } = data
|
const { folderNoteMap, trashedSet } = data
|
||||||
const folderList = storage.folders.map((folder) => {
|
const SortableStorageItemChild = SortableElement(StorageItemChild)
|
||||||
|
const folderList = storage.folders.map((folder, index) => {
|
||||||
const isActive = !!(location.pathname.match(new RegExp('\/storages\/' + storage.key + '\/folders\/' + folder.key)))
|
const isActive = !!(location.pathname.match(new RegExp('\/storages\/' + storage.key + '\/folders\/' + folder.key)))
|
||||||
const noteSet = folderNoteMap.get(storage.key + '-' + folder.key)
|
const noteSet = folderNoteMap.get(storage.key + '-' + folder.key)
|
||||||
|
|
||||||
@@ -250,8 +236,9 @@ class StorageItem extends React.Component {
|
|||||||
noteCount = noteSet.size - trashedNoteCount
|
noteCount = noteSet.size - trashedNoteCount
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<StorageItemChild
|
<SortableStorageItemChild
|
||||||
key={folder.key}
|
key={folder.key}
|
||||||
|
index={index}
|
||||||
isActive={isActive}
|
isActive={isActive}
|
||||||
handleButtonClick={(e) => this.handleFolderButtonClick(folder.key)(e)}
|
handleButtonClick={(e) => this.handleFolderButtonClick(folder.key)(e)}
|
||||||
handleContextMenu={(e) => this.handleFolderButtonContextMenu(e, folder)}
|
handleContextMenu={(e) => this.handleFolderButtonContextMenu(e, folder)}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './SwitchButton.styl'
|
import styles from './SwitchButton.styl'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const TagButton = ({
|
const TagButton = ({
|
||||||
onClick, isTagActive
|
onClick, isTagActive
|
||||||
@@ -12,7 +13,7 @@ const TagButton = ({
|
|||||||
: '../resources/icon/icon-tag.svg'
|
: '../resources/icon/icon-tag.svg'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<span styleName='tooltip'>Tags</span>
|
<span styleName='tooltip'>{i18n.__('Tags')}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import EventEmitter from 'browser/main/lib/eventEmitter'
|
|||||||
import PreferenceButton from './PreferenceButton'
|
import PreferenceButton from './PreferenceButton'
|
||||||
import ListButton from './ListButton'
|
import ListButton from './ListButton'
|
||||||
import TagButton from './TagButton'
|
import TagButton from './TagButton'
|
||||||
|
import {SortableContainer} from 'react-sortable-hoc'
|
||||||
|
|
||||||
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
|
||||||
@@ -68,6 +69,17 @@ class SideNav extends React.Component {
|
|||||||
router.push('/alltags')
|
router.push('/alltags')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSortEnd (storage) {
|
||||||
|
return ({oldIndex, newIndex}) => {
|
||||||
|
const { dispatch } = this.props
|
||||||
|
dataApi
|
||||||
|
.reorderFolder(storage.key, oldIndex, newIndex)
|
||||||
|
.then((data) => {
|
||||||
|
dispatch({ type: 'REORDER_FOLDER', storage: data.storage })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SideNavComponent (isFolded, storageList) {
|
SideNavComponent (isFolded, storageList) {
|
||||||
const { location, data } = this.props
|
const { location, data } = this.props
|
||||||
|
|
||||||
@@ -117,9 +129,9 @@ class SideNav extends React.Component {
|
|||||||
|
|
||||||
tagListComponent () {
|
tagListComponent () {
|
||||||
const { data, location } = this.props
|
const { data, location } = this.props
|
||||||
const tagList = data.tagNoteMap.map((tag, name) => {
|
const tagList = _.sortBy(data.tagNoteMap.map((tag, name) => {
|
||||||
return { name, size: tag.size }
|
return { name, size: tag.size }
|
||||||
})
|
}), ['name'])
|
||||||
return (
|
return (
|
||||||
tagList.map(tag => {
|
tagList.map(tag => {
|
||||||
return (
|
return (
|
||||||
@@ -148,10 +160,8 @@ class SideNav extends React.Component {
|
|||||||
|
|
||||||
emptyTrash (entries) {
|
emptyTrash (entries) {
|
||||||
const { dispatch } = this.props
|
const { dispatch } = this.props
|
||||||
const deletionPromises = entries.map((storageAndNoteKey) => {
|
const deletionPromises = entries.map((note) => {
|
||||||
const storageKey = storageAndNoteKey.split('-')[0]
|
return dataApi.deleteNote(note.storage, note.key)
|
||||||
const noteKey = storageAndNoteKey.split('-')[1]
|
|
||||||
return dataApi.deleteNote(storageKey, noteKey)
|
|
||||||
})
|
})
|
||||||
Promise.all(deletionPromises)
|
Promise.all(deletionPromises)
|
||||||
.then((arrayOfStorageAndNoteKeys) => {
|
.then((arrayOfStorageAndNoteKeys) => {
|
||||||
@@ -167,9 +177,9 @@ class SideNav extends React.Component {
|
|||||||
|
|
||||||
handleFilterButtonContextMenu (event) {
|
handleFilterButtonContextMenu (event) {
|
||||||
const { data } = this.props
|
const { data } = this.props
|
||||||
const entries = data.trashedSet.toJS()
|
const trashedNotes = data.trashedSet.toJS().map((uniqueKey) => data.noteMap.get(uniqueKey))
|
||||||
const menu = Menu.buildFromTemplate([
|
const menu = Menu.buildFromTemplate([
|
||||||
{ label: 'Empty Trash', click: () => this.emptyTrash(entries) }
|
{ label: 'Empty Trash', click: () => this.emptyTrash(trashedNotes) }
|
||||||
])
|
])
|
||||||
menu.popup()
|
menu.popup()
|
||||||
}
|
}
|
||||||
@@ -180,13 +190,16 @@ class SideNav extends React.Component {
|
|||||||
const isFolded = config.isSideNavFolded
|
const isFolded = config.isSideNavFolded
|
||||||
|
|
||||||
const storageList = data.storageMap.map((storage, key) => {
|
const storageList = data.storageMap.map((storage, key) => {
|
||||||
return <StorageItem
|
const SortableStorageItem = SortableContainer(StorageItem)
|
||||||
|
return <SortableStorageItem
|
||||||
key={storage.key}
|
key={storage.key}
|
||||||
storage={storage}
|
storage={storage}
|
||||||
data={data}
|
data={data}
|
||||||
location={location}
|
location={location}
|
||||||
isFolded={isFolded}
|
isFolded={isFolded}
|
||||||
dispatch={dispatch}
|
dispatch={dispatch}
|
||||||
|
onSortEnd={this.onSortEnd.bind(this)(storage)}
|
||||||
|
useDragHandle
|
||||||
/>
|
/>
|
||||||
})
|
})
|
||||||
const style = {}
|
const style = {}
|
||||||
|
|||||||
@@ -21,20 +21,19 @@
|
|||||||
color white
|
color white
|
||||||
|
|
||||||
.zoom
|
.zoom
|
||||||
display none
|
navButtonColor()
|
||||||
// navButtonColor()
|
color rgba(0,0,0,.54)
|
||||||
// color rgba(0,0,0,.54)
|
height 20px
|
||||||
// height 20px
|
display flex
|
||||||
// display flex
|
padding 0
|
||||||
// padding 0
|
align-items center
|
||||||
// align-items center
|
background-color transparent
|
||||||
// background-color transparent
|
&:hover
|
||||||
// &:hover
|
color $ui-active-color
|
||||||
// color $ui-active-color
|
&:active
|
||||||
// &:active
|
color $ui-active-color
|
||||||
// color $ui-active-color
|
span
|
||||||
// span
|
margin-left 5px
|
||||||
// margin-left 5px
|
|
||||||
|
|
||||||
.update
|
.update
|
||||||
navButtonColor()
|
navButtonColor()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import React 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 i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const { remote, ipcRenderer } = electron
|
const { remote, ipcRenderer } = electron
|
||||||
@@ -14,9 +15,9 @@ class StatusBar extends React.Component {
|
|||||||
updateApp () {
|
updateApp () {
|
||||||
const index = dialog.showMessageBox(remote.getCurrentWindow(), {
|
const index = dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Update Boostnote',
|
message: i18n.__('Update Boostnote'),
|
||||||
detail: 'New Boostnote is ready to be installed.',
|
detail: i18n.__('New Boostnote is ready to be installed.'),
|
||||||
buttons: ['Restart & Install', 'Not Now']
|
buttons: [i18n.__('Restart & Install'), i18n.__('Not Now')]
|
||||||
})
|
})
|
||||||
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
@@ -62,7 +63,7 @@ class StatusBar extends React.Component {
|
|||||||
|
|
||||||
{status.updateReady
|
{status.updateReady
|
||||||
? <button onClick={this.updateApp} styleName='update'>
|
? <button onClick={this.updateApp} styleName='update'>
|
||||||
<i styleName='update-icon' className='fa fa-cloud-download' /> Ready to Update!
|
<i styleName='update-icon' className='fa fa-cloud-download' /> {i18n.__('Ready to Update!')}
|
||||||
</button>
|
</button>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,32 @@ $control-height = 34px
|
|||||||
padding-bottom 2px
|
padding-bottom 2px
|
||||||
background-color $ui-noteList-backgroundColor
|
background-color $ui-noteList-backgroundColor
|
||||||
|
|
||||||
|
.control-search-input-clear
|
||||||
|
height 16px
|
||||||
|
width 16px
|
||||||
|
position absolute
|
||||||
|
right 40px
|
||||||
|
top 10px
|
||||||
|
z-index 300
|
||||||
|
border none
|
||||||
|
background-color transparent
|
||||||
|
color #999
|
||||||
|
&:hover .control-search-input-clear-tooltip
|
||||||
|
opacity 1
|
||||||
|
|
||||||
|
.control-search-input-clear-tooltip
|
||||||
|
tooltip()
|
||||||
|
position fixed
|
||||||
|
pointer-events none
|
||||||
|
top 50px
|
||||||
|
left 433px
|
||||||
|
z-index 200
|
||||||
|
padding 5px
|
||||||
|
line-height normal
|
||||||
|
border-radius 2px
|
||||||
|
opacity 0
|
||||||
|
transition 0.1s
|
||||||
|
|
||||||
.control-search-optionList
|
.control-search-optionList
|
||||||
position fixed
|
position fixed
|
||||||
z-index 200
|
z-index 200
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import styles from './TopBar.styl'
|
|||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import ee from 'browser/main/lib/eventEmitter'
|
import ee from 'browser/main/lib/eventEmitter'
|
||||||
import NewNoteButton from 'browser/main/NewNoteButton'
|
import NewNoteButton from 'browser/main/NewNoteButton'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
class TopBar extends React.Component {
|
class TopBar extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -36,6 +37,17 @@ class TopBar extends React.Component {
|
|||||||
ee.off('code:init', this.codeInitHandler)
|
ee.off('code:init', this.codeInitHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleSearchClearButton (e) {
|
||||||
|
const { router } = this.context
|
||||||
|
this.setState({
|
||||||
|
search: '',
|
||||||
|
isSearching: false
|
||||||
|
})
|
||||||
|
this.refs.search.childNodes[0].blur
|
||||||
|
router.push('/searched')
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
handleKeyDown (e) {
|
handleKeyDown (e) {
|
||||||
// reset states
|
// reset states
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -43,6 +55,23 @@ class TopBar extends React.Component {
|
|||||||
isIME: false
|
isIME: false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Clear search on ESC
|
||||||
|
if (e.keyCode === 27) {
|
||||||
|
return this.handleSearchClearButton(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next note on DOWN key
|
||||||
|
if (e.keyCode === 40) {
|
||||||
|
ee.emit('list:next')
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prev note on UP key
|
||||||
|
if (e.keyCode === 38) {
|
||||||
|
ee.emit('list:prior')
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
// When the key is an alphabet, del, enter or ctr
|
// When the key is an alphabet, del, enter or ctr
|
||||||
if (e.keyCode <= 90 || e.keyCode >= 186 && e.keyCode <= 222) {
|
if (e.keyCode <= 90 || e.keyCode >= 186 && e.keyCode <= 222) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -114,10 +143,12 @@ class TopBar extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleOnSearchFocus () {
|
handleOnSearchFocus () {
|
||||||
|
const el = this.refs.search.childNodes[0]
|
||||||
if (this.state.isSearching) {
|
if (this.state.isSearching) {
|
||||||
this.refs.search.childNodes[0].blur()
|
el.blur()
|
||||||
} else {
|
} else {
|
||||||
this.refs.search.childNodes[0].focus()
|
el.focus()
|
||||||
|
el.setSelectionRange(0, el.value.length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,19 +177,19 @@ class TopBar extends React.Component {
|
|||||||
onChange={(e) => this.handleSearchChange(e)}
|
onChange={(e) => this.handleSearchChange(e)}
|
||||||
onKeyDown={(e) => this.handleKeyDown(e)}
|
onKeyDown={(e) => this.handleKeyDown(e)}
|
||||||
onKeyUp={(e) => this.handleKeyUp(e)}
|
onKeyUp={(e) => this.handleKeyUp(e)}
|
||||||
placeholder='Search'
|
placeholder={i18n.__('Search')}
|
||||||
type='text'
|
type='text'
|
||||||
className='searchInput'
|
className='searchInput'
|
||||||
/>
|
/>
|
||||||
</div>
|
{this.state.search !== '' &&
|
||||||
{this.state.search > 0 &&
|
<button styleName='control-search-input-clear'
|
||||||
<button styleName='left-search-clearButton'
|
|
||||||
onClick={(e) => this.handleSearchClearButton(e)}
|
onClick={(e) => this.handleSearchClearButton(e)}
|
||||||
>
|
>
|
||||||
<i className='fa fa-times' />
|
<i className='fa fa-fw fa-times' />
|
||||||
|
<span styleName='control-search-input-clear-tooltip'>{i18n.__('Clear Search')}</span>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{location.pathname === '/trashed' ? ''
|
{location.pathname === '/trashed' ? ''
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { Router, Route, IndexRoute, IndexRedirect, hashHistory } from 'react-rou
|
|||||||
import { syncHistoryWithStore } from 'react-router-redux'
|
import { syncHistoryWithStore } from 'react-router-redux'
|
||||||
require('./lib/ipcClient')
|
require('./lib/ipcClient')
|
||||||
require('../lib/customMeta')
|
require('../lib/customMeta')
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
|
|
||||||
@@ -46,9 +47,9 @@ function notify (...args) {
|
|||||||
function updateApp () {
|
function updateApp () {
|
||||||
const index = dialog.showMessageBox(remote.getCurrentWindow(), {
|
const index = dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Update Boostnote',
|
message: i18n.__('Update Boostnote'),
|
||||||
detail: 'New Boostnote is ready to be installed.',
|
detail: i18n.__('New Boostnote is ready to be installed.'),
|
||||||
buttons: ['Restart & Install', 'Not Now']
|
buttons: [i18n.__('Restart & Install'), i18n.__('Not Now')]
|
||||||
})
|
})
|
||||||
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import RcParser from 'browser/lib/RcParser'
|
import RcParser from 'browser/lib/RcParser'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const OSX = global.process.platform === 'darwin'
|
const OSX = global.process.platform === 'darwin'
|
||||||
const win = global.process.platform === 'win32'
|
const win = global.process.platform === 'win32'
|
||||||
@@ -21,6 +22,7 @@ export const DEFAULT_CONFIG = {
|
|||||||
toggleMain: OSX ? 'Cmd + Alt + L' : 'Super + Alt + E'
|
toggleMain: OSX ? 'Cmd + Alt + L' : 'Super + Alt + E'
|
||||||
},
|
},
|
||||||
ui: {
|
ui: {
|
||||||
|
language: 'en',
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
showCopyNotification: true,
|
showCopyNotification: true,
|
||||||
disableDirectWrite: false,
|
disableDirectWrite: false,
|
||||||
@@ -48,7 +50,16 @@ export const DEFAULT_CONFIG = {
|
|||||||
latexInlineClose: '$',
|
latexInlineClose: '$',
|
||||||
latexBlockOpen: '$$',
|
latexBlockOpen: '$$',
|
||||||
latexBlockClose: '$$',
|
latexBlockClose: '$$',
|
||||||
scrollPastEnd: false
|
scrollPastEnd: false,
|
||||||
|
smartQuotes: true
|
||||||
|
},
|
||||||
|
blog: {
|
||||||
|
type: 'wordpress', // Available value: wordpress, add more types in the future plz
|
||||||
|
address: 'http://wordpress.com/wp-json',
|
||||||
|
authMethod: 'JWT', // Available value: JWT, USER
|
||||||
|
token: '',
|
||||||
|
username: '',
|
||||||
|
password: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +135,36 @@ function set (updates) {
|
|||||||
document.body.setAttribute('data-theme', 'default')
|
document.body.setAttribute('data-theme', 'default')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newConfig.ui.language === 'sq') {
|
||||||
|
i18n.setLocale('sq')
|
||||||
|
} else if (newConfig.ui.language === 'zh-CN') {
|
||||||
|
i18n.setLocale('zh-CN')
|
||||||
|
} else if (newConfig.ui.language === 'zh-TW') {
|
||||||
|
i18n.setLocale('zh-TW')
|
||||||
|
} else if (newConfig.ui.language === 'da') {
|
||||||
|
i18n.setLocale('da')
|
||||||
|
} else if (newConfig.ui.language === 'fr') {
|
||||||
|
i18n.setLocale('fr')
|
||||||
|
} else if (newConfig.ui.language === 'de') {
|
||||||
|
i18n.setLocale('de')
|
||||||
|
} else if (newConfig.ui.language === 'ja') {
|
||||||
|
i18n.setLocale('ja')
|
||||||
|
} else if (newConfig.ui.language === 'ko') {
|
||||||
|
i18n.setLocale('ko')
|
||||||
|
} else if (newConfig.ui.language === 'no') {
|
||||||
|
i18n.setLocale('no')
|
||||||
|
} else if (newConfig.ui.language === 'pl') {
|
||||||
|
i18n.setLocale('pl')
|
||||||
|
} else if (newConfig.ui.language === 'pt') {
|
||||||
|
i18n.setLocale('pt')
|
||||||
|
} else if (newConfig.ui.language === 'ru') {
|
||||||
|
i18n.setLocale('ru')
|
||||||
|
} else if (newConfig.ui.language === 'es') {
|
||||||
|
i18n.setLocale('es')
|
||||||
|
} else {
|
||||||
|
i18n.setLocale('en')
|
||||||
|
}
|
||||||
|
|
||||||
let editorTheme = document.getElementById('editorTheme')
|
let editorTheme = document.getElementById('editorTheme')
|
||||||
if (editorTheme == null) {
|
if (editorTheme == null) {
|
||||||
editorTheme = document.createElement('link')
|
editorTheme = document.createElement('link')
|
||||||
@@ -151,6 +192,7 @@ function set (updates) {
|
|||||||
function assignConfigValues (originalConfig, rcConfig) {
|
function assignConfigValues (originalConfig, rcConfig) {
|
||||||
const config = Object.assign({}, DEFAULT_CONFIG, originalConfig, rcConfig)
|
const config = Object.assign({}, DEFAULT_CONFIG, originalConfig, rcConfig)
|
||||||
config.hotkey = Object.assign({}, DEFAULT_CONFIG.hotkey, originalConfig.hotkey, rcConfig.hotkey)
|
config.hotkey = Object.assign({}, DEFAULT_CONFIG.hotkey, originalConfig.hotkey, rcConfig.hotkey)
|
||||||
|
config.blog = Object.assign({}, DEFAULT_CONFIG.blog, originalConfig.blog, rcConfig.blog)
|
||||||
config.ui = Object.assign({}, DEFAULT_CONFIG.ui, originalConfig.ui, rcConfig.ui)
|
config.ui = Object.assign({}, DEFAULT_CONFIG.ui, originalConfig.ui, rcConfig.ui)
|
||||||
config.editor = Object.assign({}, DEFAULT_CONFIG.editor, originalConfig.editor, rcConfig.editor)
|
config.editor = Object.assign({}, DEFAULT_CONFIG.editor, originalConfig.editor, rcConfig.editor)
|
||||||
config.preview = Object.assign({}, DEFAULT_CONFIG.preview, originalConfig.preview, rcConfig.preview)
|
config.preview = Object.assign({}, DEFAULT_CONFIG.preview, originalConfig.preview, rcConfig.preview)
|
||||||
|
|||||||
@@ -3,19 +3,20 @@ const path = require('path')
|
|||||||
const { findStorage } = require('browser/lib/findStorage')
|
const { findStorage } = require('browser/lib/findStorage')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description To copy an image and return the path.
|
* @description Copy an image and return the path.
|
||||||
* @param {String} filePath
|
* @param {String} filePath
|
||||||
* @param {String} storageKey
|
* @param {String} storageKey
|
||||||
* @return {String} an image path
|
* @param {Boolean} rename create new filename or leave the old one
|
||||||
|
* @return {Promise<any>} an image path
|
||||||
*/
|
*/
|
||||||
function copyImage (filePath, storageKey) {
|
function copyImage (filePath, storageKey, rename = true) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
const targetStorage = findStorage(storageKey)
|
const targetStorage = findStorage(storageKey)
|
||||||
|
|
||||||
const inputImage = fs.createReadStream(filePath)
|
const inputImage = fs.createReadStream(filePath)
|
||||||
const imageExt = path.extname(filePath)
|
const imageExt = path.extname(filePath)
|
||||||
const imageName = Math.random().toString(36).slice(-16)
|
const imageName = rename ? Math.random().toString(36).slice(-16) : path.basename(filePath, imageExt)
|
||||||
const basename = `${imageName}${imageExt}`
|
const basename = `${imageName}${imageExt}`
|
||||||
const imageDir = path.join(targetStorage.path, 'images')
|
const imageDir = path.join(targetStorage.path, 'images')
|
||||||
if (!fs.existsSync(imageDir)) fs.mkdirSync(imageDir)
|
if (!fs.existsSync(imageDir)) fs.mkdirSync(imageDir)
|
||||||
|
|||||||
@@ -52,12 +52,12 @@ function createNote (storageKey, input) {
|
|||||||
return storage
|
return storage
|
||||||
})
|
})
|
||||||
.then(function saveNote (storage) {
|
.then(function saveNote (storage) {
|
||||||
let key = keygen()
|
let key = keygen(true)
|
||||||
let isUnique = false
|
let isUnique = false
|
||||||
while (!isUnique) {
|
while (!isUnique) {
|
||||||
try {
|
try {
|
||||||
sander.statSync(path.join(storage.path, 'notes', key + '.cson'))
|
sander.statSync(path.join(storage.path, 'notes', key + '.cson'))
|
||||||
key = keygen()
|
key = keygen(true)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code === 'ENOENT') {
|
if (err.code === 'ENOENT') {
|
||||||
isUnique = true
|
isUnique = true
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {findStorage} from 'browser/lib/findStorage'
|
|||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
const LOCAL_STORED_REGEX = /!\[(.*?)\]\(\s*?\/:storage\/(.*\.\S*?)\)/gi
|
const LOCAL_STORED_REGEX = /!\[(.*?)]\(\s*?\/:storage\/(.*\.\S*?)\)/gi
|
||||||
const IMAGES_FOLDER_NAME = 'images'
|
const IMAGES_FOLDER_NAME = 'images'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
const resolveStorageData = require('./resolveStorageData')
|
const resolveStorageData = require('./resolveStorageData')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
const fs = require('fs')
|
||||||
const CSON = require('@rokt33r/season')
|
const CSON = require('@rokt33r/season')
|
||||||
const keygen = require('browser/lib/keygen')
|
const keygen = require('browser/lib/keygen')
|
||||||
const sander = require('sander')
|
const sander = require('sander')
|
||||||
const { findStorage } = require('browser/lib/findStorage')
|
const { findStorage } = require('browser/lib/findStorage')
|
||||||
|
const copyImage = require('./copyImage')
|
||||||
|
|
||||||
function moveNote (storageKey, noteKey, newStorageKey, newFolderKey) {
|
function moveNote (storageKey, noteKey, newStorageKey, newFolderKey) {
|
||||||
let oldStorage, newStorage
|
let oldStorage, newStorage
|
||||||
@@ -37,12 +39,12 @@ function moveNote (storageKey, noteKey, newStorageKey, newFolderKey) {
|
|||||||
return resolveStorageData(newStorage)
|
return resolveStorageData(newStorage)
|
||||||
.then(function findNewNoteKey (_newStorage) {
|
.then(function findNewNoteKey (_newStorage) {
|
||||||
newStorage = _newStorage
|
newStorage = _newStorage
|
||||||
newNoteKey = keygen()
|
newNoteKey = keygen(true)
|
||||||
let isUnique = false
|
let isUnique = false
|
||||||
while (!isUnique) {
|
while (!isUnique) {
|
||||||
try {
|
try {
|
||||||
sander.statSync(path.join(newStorage.path, 'notes', newNoteKey + '.cson'))
|
sander.statSync(path.join(newStorage.path, 'notes', newNoteKey + '.cson'))
|
||||||
newNoteKey = keygen()
|
newNoteKey = keygen(true)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code === 'ENOENT') {
|
if (err.code === 'ENOENT') {
|
||||||
isUnique = true
|
isUnique = true
|
||||||
@@ -65,6 +67,27 @@ function moveNote (storageKey, noteKey, newStorageKey, newFolderKey) {
|
|||||||
|
|
||||||
return noteData
|
return noteData
|
||||||
})
|
})
|
||||||
|
.then(function moveImages (noteData) {
|
||||||
|
const searchImagesRegex = /!\[.*?]\(\s*?\/:storage\/(.*\.\S*?)\)/gi
|
||||||
|
let match = searchImagesRegex.exec(noteData.content)
|
||||||
|
|
||||||
|
const moveTasks = []
|
||||||
|
while (match != null) {
|
||||||
|
const [, filename] = match
|
||||||
|
const oldPath = path.join(oldStorage.path, 'images', filename)
|
||||||
|
moveTasks.push(
|
||||||
|
copyImage(oldPath, noteData.storage, false)
|
||||||
|
.then(() => {
|
||||||
|
fs.unlinkSync(oldPath)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// find next occurence
|
||||||
|
match = searchImagesRegex.exec(noteData.content)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(moveTasks).then(() => noteData)
|
||||||
|
})
|
||||||
.then(function writeAndReturn (noteData) {
|
.then(function writeAndReturn (noteData) {
|
||||||
CSON.writeFileSync(path.join(newStorage.path, 'notes', noteData.key + '.cson'), _.omit(noteData, ['key', 'storage']))
|
CSON.writeFileSync(path.join(newStorage.path, 'notes', noteData.key + '.cson'), _.omit(noteData, ['key', 'storage']))
|
||||||
return noteData
|
return noteData
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ function validateInput (input) {
|
|||||||
validatedInput.isPinned = !!input.isPinned
|
validatedInput.isPinned = !!input.isPinned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_.isNil(input.blog)) {
|
||||||
|
validatedInput.blog = input.blog
|
||||||
|
}
|
||||||
validatedInput.type = input.type
|
validatedInput.type = input.type
|
||||||
switch (input.type) {
|
switch (input.type) {
|
||||||
case 'MARKDOWN_NOTE':
|
case 'MARKDOWN_NOTE':
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { hashHistory } from 'react-router'
|
|||||||
import ee from 'browser/main/lib/eventEmitter'
|
import ee from 'browser/main/lib/eventEmitter'
|
||||||
import ModalEscButton from 'browser/components/ModalEscButton'
|
import ModalEscButton from 'browser/components/ModalEscButton'
|
||||||
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
|
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
class NewNoteModal extends React.Component {
|
class NewNoteModal extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -35,7 +36,7 @@ class NewNoteModal extends React.Component {
|
|||||||
content: ''
|
content: ''
|
||||||
})
|
})
|
||||||
.then((note) => {
|
.then((note) => {
|
||||||
const noteHash = `${note.storage}-${note.key}`
|
const noteHash = note.key
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'UPDATE_NOTE',
|
type: 'UPDATE_NOTE',
|
||||||
note: note
|
note: note
|
||||||
@@ -75,7 +76,7 @@ class NewNoteModal extends React.Component {
|
|||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
.then((note) => {
|
.then((note) => {
|
||||||
const noteHash = `${note.storage}-${note.key}`
|
const noteHash = note.key
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'UPDATE_NOTE',
|
type: 'UPDATE_NOTE',
|
||||||
note: note
|
note: note
|
||||||
@@ -122,8 +123,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'>{i18n.__('Markdown Note')}</span><br />
|
||||||
<span styleName='control-button-description'>This format is for creating text documents. Checklists, code blocks and Latex blocks are available.</span>
|
<span styleName='control-button-description'>{i18n.__('This format is for creating text documents. Checklists, code blocks and Latex blocks are available.')}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button styleName='control-button'
|
<button styleName='control-button'
|
||||||
@@ -134,13 +135,13 @@ 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'>{i18n.__('Snippet Note')}</span><br />
|
||||||
<span styleName='control-button-description'>This format is for creating code snippets. Multiple snippets can be grouped into a single note.
|
<span styleName='control-button-description'>{i18n.__('This format is for creating code snippets. Multiple snippets can be grouped into a single 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' />{i18n.__('Tab to switch format')}</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
199
browser/main/modals/PreferencesModal/Blog.js
Normal file
199
browser/main/modals/PreferencesModal/Blog.js
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
import React 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'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import _ from 'lodash'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
|
const electron = require('electron')
|
||||||
|
const { shell } = electron
|
||||||
|
const ipc = electron.ipcRenderer
|
||||||
|
class Blog extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
config: props.config,
|
||||||
|
BlogAlert: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleLinkClick (e) {
|
||||||
|
shell.openExternal(e.currentTarget.href)
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
clearMessage () {
|
||||||
|
_.debounce(() => {
|
||||||
|
this.setState({
|
||||||
|
BlogAlert: null
|
||||||
|
})
|
||||||
|
}, 2000)()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
this.handleSettingDone = () => {
|
||||||
|
this.setState({BlogAlert: {
|
||||||
|
type: 'success',
|
||||||
|
message: i18n.__('Successfully applied!')
|
||||||
|
}})
|
||||||
|
}
|
||||||
|
this.handleSettingError = (err) => {
|
||||||
|
this.setState({BlogAlert: {
|
||||||
|
type: 'error',
|
||||||
|
message: err.message != null ? err.message : 'Error occurs!'
|
||||||
|
}})
|
||||||
|
}
|
||||||
|
this.oldBlog = this.state.config.blog
|
||||||
|
ipc.addListener('APP_SETTING_DONE', this.handleSettingDone)
|
||||||
|
ipc.addListener('APP_SETTING_ERROR', this.handleSettingError)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBlogChange (e) {
|
||||||
|
const { config } = this.state
|
||||||
|
config.blog = {
|
||||||
|
password: !_.isNil(this.refs.passwordInput) ? this.refs.passwordInput.value : config.blog.password,
|
||||||
|
username: !_.isNil(this.refs.usernameInput) ? this.refs.usernameInput.value : config.blog.username,
|
||||||
|
token: !_.isNil(this.refs.tokenInput) ? this.refs.tokenInput.value : config.blog.token,
|
||||||
|
authMethod: this.refs.authMethodDropdown.value,
|
||||||
|
address: this.refs.addressInput.value,
|
||||||
|
type: this.refs.typeDropdown.value
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
config
|
||||||
|
})
|
||||||
|
if (_.isEqual(this.oldBlog, config.blog)) {
|
||||||
|
this.props.haveToSave()
|
||||||
|
} else {
|
||||||
|
this.props.haveToSave({
|
||||||
|
tab: 'Blog',
|
||||||
|
type: 'warning',
|
||||||
|
message: 'You have to save!'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSaveButtonClick (e) {
|
||||||
|
const newConfig = {
|
||||||
|
blog: this.state.config.blog
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigManager.set(newConfig)
|
||||||
|
|
||||||
|
store.dispatch({
|
||||||
|
type: 'SET_UI',
|
||||||
|
config: newConfig
|
||||||
|
})
|
||||||
|
this.clearMessage()
|
||||||
|
this.props.haveToSave()
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const {config, BlogAlert} = this.state
|
||||||
|
const blogAlertElement = BlogAlert != null
|
||||||
|
? <p className={`alert ${BlogAlert.type}`}>
|
||||||
|
{BlogAlert.message}
|
||||||
|
</p>
|
||||||
|
: null
|
||||||
|
return (
|
||||||
|
<div styleName='root'>
|
||||||
|
<div styleName='group'>
|
||||||
|
<div styleName='group-header'>{i18n.__('Blog')}</div>
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>
|
||||||
|
{i18n.__('Blog Type')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<select
|
||||||
|
value={config.blog.type}
|
||||||
|
ref='typeDropdown'
|
||||||
|
onChange={(e) => this.handleBlogChange(e)}
|
||||||
|
>
|
||||||
|
<option value='wordpress' key='wordpress'>wordpress</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>{i18n.__('Blog Address')}</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input styleName='group-section-control-input'
|
||||||
|
onChange={(e) => this.handleBlogChange(e)}
|
||||||
|
ref='addressInput'
|
||||||
|
value={config.blog.address}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div styleName='group-control'>
|
||||||
|
<button styleName='group-control-rightButton'
|
||||||
|
onClick={(e) => this.handleSaveButtonClick(e)}>{i18n.__('Save')}
|
||||||
|
</button>
|
||||||
|
{blogAlertElement}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div styleName='group-header2'>{i18n.__('Auth')}</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>
|
||||||
|
{i18n.__('Authentication Method')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<select
|
||||||
|
value={config.blog.authMethod}
|
||||||
|
ref='authMethodDropdown'
|
||||||
|
onChange={(e) => this.handleBlogChange(e)}
|
||||||
|
>
|
||||||
|
<option value='JWT' key='JWT'>{i18n.__('JWT')}</option>
|
||||||
|
<option value='USER' key='USER'>{i18n.__('USER')}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{ config.blog.authMethod === 'JWT' &&
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>{i18n.__('Token')}</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input styleName='group-section-control-input'
|
||||||
|
onChange={(e) => this.handleBlogChange(e)}
|
||||||
|
ref='tokenInput'
|
||||||
|
value={config.blog.token}
|
||||||
|
type='text' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{ config.blog.authMethod === 'USER' &&
|
||||||
|
<div>
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>{i18n.__('UserName')}</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input styleName='group-section-control-input'
|
||||||
|
onChange={(e) => this.handleBlogChange(e)}
|
||||||
|
ref='usernameInput'
|
||||||
|
value={config.blog.username}
|
||||||
|
type='text' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>{i18n.__('Password')}</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input styleName='group-section-control-input'
|
||||||
|
onChange={(e) => this.handleBlogChange(e)}
|
||||||
|
ref='passwordInput'
|
||||||
|
value={config.blog.password}
|
||||||
|
type='password' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Blog.propTypes = {
|
||||||
|
dispatch: PropTypes.func,
|
||||||
|
haveToSave: PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(Blog, styles)
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './Crowdfunding.styl'
|
import styles from './Crowdfunding.styl'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const { shell } = electron
|
const { shell } = electron
|
||||||
@@ -21,22 +22,22 @@ class Crowdfunding extends React.Component {
|
|||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div styleName='root'>
|
<div styleName='root'>
|
||||||
<div styleName='header'>Crowdfunding</div>
|
<div styleName='header'>{i18n.__('Crowdfunding')}</div>
|
||||||
<p>Dear everyone,</p>
|
<p>{i18n.__('Dear everyone,')}</p>
|
||||||
<br />
|
<br />
|
||||||
<p>Thank you for using Boostnote!</p>
|
<p>{i18n.__('Thank you for using Boostnote!')}</p>
|
||||||
<p>Boostnote is used in about 200 different countries and regions by an awesome community of developers.</p>
|
<p>{i18n.__('Boostnote is used in about 200 different countries and regions by an awesome community of developers.')}</p>
|
||||||
<br />
|
<br />
|
||||||
<p>To continue supporting this growth, and to satisfy community expectations,</p>
|
<p>{i18n.__('To continue supporting this growth, and to satisfy community expectations,')}</p>
|
||||||
<p>we would like to invest more time and resources in this project.</p>
|
<p>{i18n.__('we would like to invest more time and resources in this project.')}</p>
|
||||||
<br />
|
<br />
|
||||||
<p>If you like this project and see its potential, you can help by supporting us on OpenCollective!</p>
|
<p>{i18n.__('If you like this project and see its potential, you can help by supporting us on OpenCollective!')}</p>
|
||||||
<br />
|
<br />
|
||||||
<p>Thanks,</p>
|
<p>{i18n.__('Thanks,')}</p>
|
||||||
<p>Boostnote maintainers</p>
|
<p>{i18n.__('Boostnote maintainers')}</p>
|
||||||
<br />
|
<br />
|
||||||
<button styleName='cf-link'>
|
<button styleName='cf-link'>
|
||||||
<a href='https://opencollective.com/boostnoteio' onClick={(e) => this.handleLinkClick(e)}>Support via OpenCollective</a>
|
<a href='https://opencollective.com/boostnoteio' onClick={(e) => this.handleLinkClick(e)}>{i18n.__('Support via OpenCollective')}</a>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import dataApi from 'browser/main/lib/dataApi'
|
|||||||
import store from 'browser/main/store'
|
import store from 'browser/main/store'
|
||||||
import { SketchPicker } from 'react-color'
|
import { SketchPicker } from 'react-color'
|
||||||
import { SortableElement, SortableHandle } from 'react-sortable-hoc'
|
import { SortableElement, SortableHandle } from 'react-sortable-hoc'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
class FolderItem extends React.Component {
|
class FolderItem extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -179,18 +180,18 @@ class FolderItem extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div styleName='folderItem'>
|
<div styleName='folderItem'>
|
||||||
<div styleName='folderItem-left'>
|
<div styleName='folderItem-left'>
|
||||||
Are you sure to <span styleName='folderItem-left-danger'>delete</span> this folder?
|
{i18n.__('Are you sure to ')} <span styleName='folderItem-left-danger'>{i18n.__(' delete')}</span> {i18n.__('this folder?')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='folderItem-right'>
|
<div styleName='folderItem-right'>
|
||||||
<button styleName='folderItem-right-dangerButton'
|
<button styleName='folderItem-right-dangerButton'
|
||||||
onClick={(e) => this.handleDeleteConfirmButtonClick(e)}
|
onClick={(e) => this.handleDeleteConfirmButtonClick(e)}
|
||||||
>
|
>
|
||||||
Confirm
|
{i18n.__('Confirm')}
|
||||||
</button>
|
</button>
|
||||||
<button styleName='folderItem-right-button'
|
<button styleName='folderItem-right-button'
|
||||||
onClick={(e) => this.handleCancelButtonClick(e)}
|
onClick={(e) => this.handleCancelButtonClick(e)}
|
||||||
>
|
>
|
||||||
Cancel
|
{i18n.__('Cancel')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -231,12 +232,12 @@ class FolderItem extends React.Component {
|
|||||||
<button styleName='folderItem-right-button'
|
<button styleName='folderItem-right-button'
|
||||||
onClick={(e) => this.handleEditButtonClick(e)}
|
onClick={(e) => this.handleEditButtonClick(e)}
|
||||||
>
|
>
|
||||||
Edit
|
{i18n.__('Edit')}
|
||||||
</button>
|
</button>
|
||||||
<button styleName='folderItem-right-button'
|
<button styleName='folderItem-right-button'
|
||||||
onClick={(e) => this.handleDeleteButtonClick(e)}
|
onClick={(e) => this.handleDeleteButtonClick(e)}
|
||||||
>
|
>
|
||||||
Delete
|
{i18n.__('Delete')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import styles from './ConfigTab.styl'
|
|||||||
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 _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const ipc = electron.ipcRenderer
|
const ipc = electron.ipcRenderer
|
||||||
@@ -23,7 +24,7 @@ class HotkeyTab extends React.Component {
|
|||||||
this.handleSettingDone = () => {
|
this.handleSettingDone = () => {
|
||||||
this.setState({keymapAlert: {
|
this.setState({keymapAlert: {
|
||||||
type: 'success',
|
type: 'success',
|
||||||
message: 'Successfully applied!'
|
message: i18n.__('Successfully applied!')
|
||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
this.handleSettingError = (err) => {
|
this.handleSettingError = (err) => {
|
||||||
@@ -77,7 +78,7 @@ class HotkeyTab extends React.Component {
|
|||||||
this.props.haveToSave({
|
this.props.haveToSave({
|
||||||
tab: 'Hotkey',
|
tab: 'Hotkey',
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'You have to save!'
|
message: i18n.__('You have to save!')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,9 +103,9 @@ class HotkeyTab extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div styleName='root'>
|
<div styleName='root'>
|
||||||
<div styleName='group'>
|
<div styleName='group'>
|
||||||
<div styleName='group-header'>Hotkeys</div>
|
<div styleName='group-header'>{i18n.__('Hotkeys')}</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>Show/Hide Boostnote</div>
|
<div styleName='group-section-label'>{i18n.__('Show/Hide Boostnote')}</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<input styleName='group-section-control-input'
|
<input styleName='group-section-control-input'
|
||||||
onChange={(e) => this.handleHotkeyChange(e)}
|
onChange={(e) => this.handleHotkeyChange(e)}
|
||||||
@@ -124,7 +125,7 @@ class HotkeyTab extends React.Component {
|
|||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
<button styleName='group-control-rightButton'
|
<button styleName='group-control-rightButton'
|
||||||
onClick={(e) => this.handleSaveButtonClick(e)}>Save
|
onClick={(e) => this.handleSaveButtonClick(e)}>{i18n.__('Save')}
|
||||||
</button>
|
</button>
|
||||||
{keymapAlertElement}
|
{keymapAlertElement}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import ConfigManager from 'browser/main/lib/ConfigManager'
|
|||||||
import store from 'browser/main/store'
|
import store from 'browser/main/store'
|
||||||
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
|
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const { shell, remote } = electron
|
const { shell, remote } = electron
|
||||||
@@ -38,11 +39,11 @@ class InfoTab extends React.Component {
|
|||||||
if (!newConfig.amaEnabled) {
|
if (!newConfig.amaEnabled) {
|
||||||
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('DISABLE_AMA')
|
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('DISABLE_AMA')
|
||||||
this.setState({
|
this.setState({
|
||||||
amaMessage: 'We hope we will gain your trust'
|
amaMessage: i18n.__('We hope we will gain your trust')
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
amaMessage: 'Thank\'s for trust us'
|
amaMessage: i18n.__('Thank\'s for trusting us')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,48 +70,48 @@ class InfoTab extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div styleName='root'>
|
<div styleName='root'>
|
||||||
|
|
||||||
<div styleName='header--sub'>Community</div>
|
<div styleName='header--sub'>{i18n.__('Community')}</div>
|
||||||
<div styleName='top'>
|
<div styleName='top'>
|
||||||
<ul styleName='list'>
|
<ul styleName='list'>
|
||||||
<li>
|
<li>
|
||||||
<a href='https://boostnote.io/#subscribe'
|
<a href='https://boostnote.io/#subscribe'
|
||||||
onClick={(e) => this.handleLinkClick(e)}
|
onClick={(e) => this.handleLinkClick(e)}
|
||||||
>Subscribe to Newsletter</a>
|
>{i18n.__('Subscribe to Newsletter')}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='https://github.com/BoostIO/Boostnote/issues'
|
<a href='https://github.com/BoostIO/Boostnote/issues'
|
||||||
onClick={(e) => this.handleLinkClick(e)}
|
onClick={(e) => this.handleLinkClick(e)}
|
||||||
>GitHub</a>
|
>{i18n.__('GitHub')}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='https://boostlog.io/@junp1234'
|
<a href='https://boostlog.io/@junp1234'
|
||||||
onClick={(e) => this.handleLinkClick(e)}
|
onClick={(e) => this.handleLinkClick(e)}
|
||||||
>Blog</a>
|
>{i18n.__('Blog')}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='https://www.facebook.com/groups/boostnote'
|
<a href='https://www.facebook.com/groups/boostnote'
|
||||||
onClick={(e) => this.handleLinkClick(e)}
|
onClick={(e) => this.handleLinkClick(e)}
|
||||||
>Facebook Group</a>
|
>{i18n.__('Facebook Group')}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='https://twitter.com/boostnoteapp'
|
<a href='https://twitter.com/boostnoteapp'
|
||||||
onClick={(e) => this.handleLinkClick(e)}
|
onClick={(e) => this.handleLinkClick(e)}
|
||||||
>Twitter</a>
|
>{i18n.__('Twitter')}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div styleName='header--sub'>About</div>
|
<div styleName='header--sub'>{i18n.__('About')}</div>
|
||||||
|
|
||||||
<div styleName='top'>
|
<div styleName='top'>
|
||||||
<div styleName='icon-space'>
|
<div styleName='icon-space'>
|
||||||
<img styleName='icon' src='../resources/app.png' width='92' height='92' />
|
<img styleName='icon' src='../resources/app.png' width='92' height='92' />
|
||||||
<div styleName='icon-right'>
|
<div styleName='icon-right'>
|
||||||
<div styleName='appId'>Boostnote {appVersion}</div>
|
<div styleName='appId'>{i18n.__('Boostnote')} {appVersion}</div>
|
||||||
<div styleName='description'>
|
<div styleName='description'>
|
||||||
An open source note-taking app made for programmers just like you.
|
{i18n.__('An open source note-taking app made for programmers just like you.')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -120,35 +121,35 @@ class InfoTab extends React.Component {
|
|||||||
<li>
|
<li>
|
||||||
<a href='https://boostnote.io'
|
<a href='https://boostnote.io'
|
||||||
onClick={(e) => this.handleLinkClick(e)}
|
onClick={(e) => this.handleLinkClick(e)}
|
||||||
>Website</a>
|
>{i18n.__('Website')}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='https://github.com/BoostIO/Boostnote/blob/master/docs/build.md'
|
<a href='https://github.com/BoostIO/Boostnote/blob/master/docs/build.md'
|
||||||
onClick={(e) => this.handleLinkClick(e)}
|
onClick={(e) => this.handleLinkClick(e)}
|
||||||
>Development</a> : Development configurations for Boostnote.
|
>{i18n.__('Development')}</a>{i18n.__(' : Development configurations for Boostnote.')}
|
||||||
</li>
|
</li>
|
||||||
<li styleName='cc'>
|
<li styleName='cc'>
|
||||||
Copyright (C) 2017 - 2018 BoostIO
|
{i18n.__('Copyright (C) 2017 - 2018 BoostIO')}
|
||||||
</li>
|
</li>
|
||||||
<li styleName='cc'>
|
<li styleName='cc'>
|
||||||
License: GPL v3
|
{i18n.__('License: GPL v3')}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<hr styleName='separate-line' />
|
<hr styleName='separate-line' />
|
||||||
|
|
||||||
<div styleName='policy'>Analytics</div>
|
<div styleName='policy'>{i18n.__('Analytics')}</div>
|
||||||
<div>Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.</div>
|
<div>{i18n.__('Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.')}</div>
|
||||||
<div>You can see how it works on <a href='https://github.com/BoostIO/Boostnote' onClick={(e) => this.handleLinkClick(e)}>GitHub</a>.</div>
|
<div>{i18n.__('You can see how it works on ')}<a href='https://github.com/BoostIO/Boostnote' onClick={(e) => this.handleLinkClick(e)}>GitHub</a>.</div>
|
||||||
<br />
|
<br />
|
||||||
<div>You can choose to enable or disable this option.</div>
|
<div>{i18n.__('You can choose to enable or disable this option.')}</div>
|
||||||
<input onChange={(e) => this.handleConfigChange(e)}
|
<input onChange={(e) => this.handleConfigChange(e)}
|
||||||
checked={this.state.config.amaEnabled}
|
checked={this.state.config.amaEnabled}
|
||||||
ref='amaEnabled'
|
ref='amaEnabled'
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
/>
|
/>
|
||||||
Enable analytics to help improve Boostnote<br />
|
{i18n.__('Enable analytics to help improve Boostnote')}<br />
|
||||||
<button styleName='policy-submit' onClick={(e) => this.handleSaveButtonClick(e)}>Save</button>
|
<button styleName='policy-submit' onClick={(e) => this.handleSaveButtonClick(e)}>{i18n.__('Save')}</button>
|
||||||
<br />
|
<br />
|
||||||
{this.infoMessage()}
|
{this.infoMessage()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import consts from 'browser/lib/consts'
|
|||||||
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 FolderList from './FolderList'
|
import FolderList from './FolderList'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const { shell, remote } = require('electron')
|
const { shell, remote } = require('electron')
|
||||||
const { dialog } = remote
|
const { dialog } = remote
|
||||||
@@ -46,9 +47,9 @@ class StorageItem extends React.Component {
|
|||||||
handleUnlinkButtonClick (e) {
|
handleUnlinkButtonClick (e) {
|
||||||
const index = dialog.showMessageBox(remote.getCurrentWindow(), {
|
const index = dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Unlink Storage',
|
message: i18n.__('Unlink Storage'),
|
||||||
detail: 'Unlinking removes this linked storage from Boostnote. No data is removed, please manually delete the folder from your hard drive if needed.',
|
detail: i18n.__('Unlinking removes this linked storage from Boostnote. No data is removed, please manually delete the folder from your hard drive if needed.'),
|
||||||
buttons: ['Unlink', 'Cancel']
|
buttons: [i18n.__('Unlink'), i18n.__('Cancel')]
|
||||||
})
|
})
|
||||||
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
@@ -127,7 +128,7 @@ class StorageItem extends React.Component {
|
|||||||
<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>
|
>{i18n.__('Add Folder')}</span>
|
||||||
</button>
|
</button>
|
||||||
<button styleName='header-control-button'
|
<button styleName='header-control-button'
|
||||||
onClick={(e) => this.handleExternalButtonClick(e)}
|
onClick={(e) => this.handleExternalButtonClick(e)}
|
||||||
@@ -135,7 +136,7 @@ class StorageItem extends React.Component {
|
|||||||
<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>
|
>{i18n.__('Open Storage folder')}</span>
|
||||||
</button>
|
</button>
|
||||||
<button styleName='header-control-button'
|
<button styleName='header-control-button'
|
||||||
onClick={(e) => this.handleUnlinkButtonClick(e)}
|
onClick={(e) => this.handleUnlinkButtonClick(e)}
|
||||||
@@ -143,7 +144,7 @@ class StorageItem extends React.Component {
|
|||||||
<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>
|
>{i18n.__('Unlink')}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import CSSModules from 'browser/lib/CSSModules'
|
|||||||
import styles from './StoragesTab.styl'
|
import styles from './StoragesTab.styl'
|
||||||
import dataApi from 'browser/main/lib/dataApi'
|
import dataApi from 'browser/main/lib/dataApi'
|
||||||
import StorageItem from './StorageItem'
|
import StorageItem from './StorageItem'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const { shell, remote } = electron
|
const { shell, remote } = electron
|
||||||
@@ -69,16 +70,16 @@ class StoragesTab extends React.Component {
|
|||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
<div styleName='list'>
|
<div styleName='list'>
|
||||||
<div styleName='header'>Storages</div>
|
<div styleName='header'>{i18n.__('Storages')}</div>
|
||||||
{storageList.length > 0
|
{storageList.length > 0
|
||||||
? storageList
|
? storageList
|
||||||
: <div styleName='list-empty'>No storage found.</div>
|
: <div styleName='list-empty'>{i18n.__('No storage found.')}</div>
|
||||||
}
|
}
|
||||||
<div styleName='list-control'>
|
<div styleName='list-control'>
|
||||||
<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 Location
|
<i className='fa fa-plus' /> {i18n.__('Add Storage Location')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -140,13 +141,13 @@ class StoragesTab extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div styleName='addStorage'>
|
<div styleName='addStorage'>
|
||||||
|
|
||||||
<div styleName='addStorage-header'>Add Storage</div>
|
<div styleName='addStorage-header'>{i18n.__('Add Storage')}</div>
|
||||||
|
|
||||||
<div styleName='addStorage-body'>
|
<div styleName='addStorage-body'>
|
||||||
|
|
||||||
<div styleName='addStorage-body-section'>
|
<div styleName='addStorage-body-section'>
|
||||||
<div styleName='addStorage-body-section-label'>
|
<div styleName='addStorage-body-section-label'>
|
||||||
Name
|
{i18n.__('Name')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='addStorage-body-section-name'>
|
<div styleName='addStorage-body-section-name'>
|
||||||
<input styleName='addStorage-body-section-name-input'
|
<input styleName='addStorage-body-section-name-input'
|
||||||
@@ -158,25 +159,25 @@ class StoragesTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div styleName='addStorage-body-section'>
|
<div styleName='addStorage-body-section'>
|
||||||
<div styleName='addStorage-body-section-label'>Type</div>
|
<div styleName='addStorage-body-section-label'>{i18n.__('Type')}</div>
|
||||||
<div styleName='addStorage-body-section-type'>
|
<div styleName='addStorage-body-section-type'>
|
||||||
<select styleName='addStorage-body-section-type-select'
|
<select styleName='addStorage-body-section-type-select'
|
||||||
value={this.state.newStorage.type}
|
value={this.state.newStorage.type}
|
||||||
readOnly
|
readOnly
|
||||||
>
|
>
|
||||||
<option value='FILESYSTEM'>File System</option>
|
<option value='FILESYSTEM'>{i18n.__('File System')}</option>
|
||||||
</select>
|
</select>
|
||||||
<div styleName='addStorage-body-section-type-description'>
|
<div styleName='addStorage-body-section-type-description'>
|
||||||
Setting up 3rd-party cloud storage integration:{' '}
|
{i18n.__('Setting up 3rd-party cloud storage integration:')}{' '}
|
||||||
<a href='https://github.com/BoostIO/Boostnote/wiki/Cloud-Syncing-and-Backup'
|
<a href='https://github.com/BoostIO/Boostnote/wiki/Cloud-Syncing-and-Backup'
|
||||||
onClick={(e) => this.handleLinkClick(e)}
|
onClick={(e) => this.handleLinkClick(e)}
|
||||||
>Cloud-Syncing-and-Backup</a>
|
>{i18n.__('Cloud-Syncing-and-Backup')}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div styleName='addStorage-body-section'>
|
<div styleName='addStorage-body-section'>
|
||||||
<div styleName='addStorage-body-section-label'>Location
|
<div styleName='addStorage-body-section-label'>{i18n.__('Location')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='addStorage-body-section-path'>
|
<div styleName='addStorage-body-section-path'>
|
||||||
<input styleName='addStorage-body-section-path-input'
|
<input styleName='addStorage-body-section-path-input'
|
||||||
@@ -196,10 +197,10 @@ class StoragesTab extends React.Component {
|
|||||||
<div styleName='addStorage-body-control'>
|
<div styleName='addStorage-body-control'>
|
||||||
<button styleName='addStorage-body-control-createButton'
|
<button styleName='addStorage-body-control-createButton'
|
||||||
onClick={(e) => this.handleAddStorageCreateButton(e)}
|
onClick={(e) => this.handleAddStorageCreateButton(e)}
|
||||||
>Add</button>
|
>{i18n.__('Add')}</button>
|
||||||
<button styleName='addStorage-body-control-cancelButton'
|
<button styleName='addStorage-body-control-cancelButton'
|
||||||
onClick={(e) => this.handleAddStorageCancelButton(e)}
|
onClick={(e) => this.handleAddStorageCancelButton(e)}
|
||||||
>Cancel</button>
|
>{i18n.__('Cancel')}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import ReactCodeMirror from 'react-codemirror'
|
|||||||
import CodeMirror from 'codemirror'
|
import CodeMirror from 'codemirror'
|
||||||
import 'codemirror-mode-elixir'
|
import 'codemirror-mode-elixir'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
const OSX = global.process.platform === 'darwin'
|
const OSX = global.process.platform === 'darwin'
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ class UiTab extends React.Component {
|
|||||||
this.handleSettingDone = () => {
|
this.handleSettingDone = () => {
|
||||||
this.setState({UiAlert: {
|
this.setState({UiAlert: {
|
||||||
type: 'success',
|
type: 'success',
|
||||||
message: 'Successfully applied!'
|
message: i18n.__('Successfully applied!')
|
||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
this.handleSettingError = (err) => {
|
this.handleSettingError = (err) => {
|
||||||
@@ -61,6 +62,7 @@ class UiTab extends React.Component {
|
|||||||
const newConfig = {
|
const newConfig = {
|
||||||
ui: {
|
ui: {
|
||||||
theme: this.refs.uiTheme.value,
|
theme: this.refs.uiTheme.value,
|
||||||
|
language: this.refs.uiLanguage.value,
|
||||||
showCopyNotification: this.refs.showCopyNotification.checked,
|
showCopyNotification: this.refs.showCopyNotification.checked,
|
||||||
confirmDeletion: this.refs.confirmDeletion.checked,
|
confirmDeletion: this.refs.confirmDeletion.checked,
|
||||||
disableDirectWrite: this.refs.uiD2w != null
|
disableDirectWrite: this.refs.uiD2w != null
|
||||||
@@ -88,7 +90,8 @@ class UiTab extends React.Component {
|
|||||||
latexInlineClose: this.refs.previewLatexInlineClose.value,
|
latexInlineClose: this.refs.previewLatexInlineClose.value,
|
||||||
latexBlockOpen: this.refs.previewLatexBlockOpen.value,
|
latexBlockOpen: this.refs.previewLatexBlockOpen.value,
|
||||||
latexBlockClose: this.refs.previewLatexBlockClose.value,
|
latexBlockClose: this.refs.previewLatexBlockClose.value,
|
||||||
scrollPastEnd: this.refs.previewScrollPastEnd.checked
|
scrollPastEnd: this.refs.previewScrollPastEnd.checked,
|
||||||
|
smartQuotes: this.refs.previewSmartQuotes.checked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +109,7 @@ class UiTab extends React.Component {
|
|||||||
this.props.haveToSave({
|
this.props.haveToSave({
|
||||||
tab: 'UI',
|
tab: 'UI',
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'You have to save!'
|
message: i18n.__('You have to save!')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -151,22 +154,48 @@ class UiTab extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div styleName='root'>
|
<div styleName='root'>
|
||||||
<div styleName='group'>
|
<div styleName='group'>
|
||||||
<div styleName='group-header'>Interface</div>
|
<div styleName='group-header'>{i18n.__('Interface')}</div>
|
||||||
|
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
Interface Theme
|
{i18n.__('Interface Theme')}
|
||||||
<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)}
|
||||||
ref='uiTheme'
|
ref='uiTheme'
|
||||||
>
|
>
|
||||||
<option value='default'>Default</option>
|
<option value='default'>{i18n.__('Default')}</option>
|
||||||
<option value='white'>White</option>
|
<option value='white'>{i18n.__('White')}</option>
|
||||||
<option value='solarized-dark'>Solarized Dark</option>
|
<option value='solarized-dark'>{i18n.__('Solarized Dark')}</option>
|
||||||
<option value='dark'>Dark</option>
|
<option value='dark'>{i18n.__('Dark')}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
{i18n.__('Language')}
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<select value={config.ui.language}
|
||||||
|
onChange={(e) => this.handleUIChange(e)}
|
||||||
|
ref='uiLanguage'
|
||||||
|
>
|
||||||
|
<option value='sq'>{i18n.__('Albanian')}</option>
|
||||||
|
<option value='zh-CN'>{i18n.__('Chinese (zh-CN)')}</option>
|
||||||
|
<option value='zh-TW'>{i18n.__('Chinese (zh-TW)')}</option>
|
||||||
|
<option value='da'>{i18n.__('Danish')}</option>
|
||||||
|
<option value='en'>{i18n.__('English')}</option>
|
||||||
|
<option value='fr'>{i18n.__('French')}</option>
|
||||||
|
<option value='de'>{i18n.__('German')}</option>
|
||||||
|
<option value='ja'>{i18n.__('Japanese')}</option>
|
||||||
|
<option value='ko'>{i18n.__('Korean')}</option>
|
||||||
|
<option value='no'>{i18n.__('Norwegian')}</option>
|
||||||
|
<option value='pl'>{i18n.__('Polish')}</option>
|
||||||
|
<option value='pt'>{i18n.__('Portuguese')}</option>
|
||||||
|
<option value='ru'>{i18n.__('Russian')}</option>
|
||||||
|
<option value='es'>{i18n.__('Spanish')}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div styleName='group-checkBoxSection'>
|
<div styleName='group-checkBoxSection'>
|
||||||
<label>
|
<label>
|
||||||
<input onChange={(e) => this.handleUIChange(e)}
|
<input onChange={(e) => this.handleUIChange(e)}
|
||||||
@@ -174,7 +203,7 @@ class UiTab extends React.Component {
|
|||||||
ref='showCopyNotification'
|
ref='showCopyNotification'
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
/>
|
/>
|
||||||
Show "Saved to Clipboard" notification when copying
|
{i18n.__('Show "Saved to Clipboard" notification when copying')}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-checkBoxSection'>
|
<div styleName='group-checkBoxSection'>
|
||||||
@@ -184,7 +213,7 @@ class UiTab extends React.Component {
|
|||||||
ref='confirmDeletion'
|
ref='confirmDeletion'
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
/>
|
/>
|
||||||
Show a confirmation dialog when deleting notes
|
{i18n.__('Show a confirmation dialog when deleting notes')}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
@@ -206,7 +235,7 @@ class UiTab extends React.Component {
|
|||||||
|
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
Editor Theme
|
{i18n.__('Editor Theme')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<select value={config.editor.theme}
|
<select value={config.editor.theme}
|
||||||
@@ -226,7 +255,7 @@ class UiTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
Editor Font Size
|
{i18n.__('Editor Font Size')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<input styleName='group-section-control-input'
|
<input styleName='group-section-control-input'
|
||||||
@@ -239,7 +268,7 @@ class UiTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
Editor Font Family
|
{i18n.__('Editor Font Family')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<input styleName='group-section-control-input'
|
<input styleName='group-section-control-input'
|
||||||
@@ -252,7 +281,7 @@ class UiTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
Editor Indent Style
|
{i18n.__('Editor Indent Style')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<select value={config.editor.indentSize}
|
<select value={config.editor.indentSize}
|
||||||
@@ -268,42 +297,42 @@ class UiTab extends React.Component {
|
|||||||
ref='editorIndentType'
|
ref='editorIndentType'
|
||||||
onChange={(e) => this.handleUIChange(e)}
|
onChange={(e) => this.handleUIChange(e)}
|
||||||
>
|
>
|
||||||
<option value='space'>Spaces</option>
|
<option value='space'>{i18n.__('Spaces')}</option>
|
||||||
<option value='tab'>Tabs</option>
|
<option value='tab'>{i18n.__('Tabs')}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
Switch to Preview
|
{i18n.__('Switch to Preview')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<select value={config.editor.switchPreview}
|
<select value={config.editor.switchPreview}
|
||||||
ref='editorSwitchPreview'
|
ref='editorSwitchPreview'
|
||||||
onChange={(e) => this.handleUIChange(e)}
|
onChange={(e) => this.handleUIChange(e)}
|
||||||
>
|
>
|
||||||
<option value='BLUR'>When Editor Blurred</option>
|
<option value='BLUR'>{i18n.__('When Editor Blurred')}</option>
|
||||||
<option value='DBL_CLICK'>When Editor Blurred, Edit On Double Click</option>
|
<option value='DBL_CLICK'>{i18n.__('When Editor Blurred, Edit On Double Click')}</option>
|
||||||
<option value='RIGHTCLICK'>On Right Click</option>
|
<option value='RIGHTCLICK'>{i18n.__('On Right Click')}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
Editor Keymap
|
{i18n.__('Editor Keymap')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<select value={config.editor.keyMap}
|
<select value={config.editor.keyMap}
|
||||||
ref='editorKeyMap'
|
ref='editorKeyMap'
|
||||||
onChange={(e) => this.handleUIChange(e)}
|
onChange={(e) => this.handleUIChange(e)}
|
||||||
>
|
>
|
||||||
<option value='sublime'>default</option>
|
<option value='sublime'>{i18n.__('default')}</option>
|
||||||
<option value='vim'>vim</option>
|
<option value='vim'>{i18n.__('vim')}</option>
|
||||||
<option value='emacs'>emacs</option>
|
<option value='emacs'>{i18n.__('emacs')}</option>
|
||||||
</select>
|
</select>
|
||||||
<p styleName='note-for-keymap'>⚠️ Please restart boostnote after you change the keymap</p>
|
<p styleName='note-for-keymap'>{i18n.__('⚠️ Please restart boostnote after you change the keymap')}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -314,7 +343,7 @@ class UiTab extends React.Component {
|
|||||||
ref='editorDisplayLineNumbers'
|
ref='editorDisplayLineNumbers'
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
/>
|
/>
|
||||||
Show line numbers in the editor
|
{i18n.__('Show line numbers in the editor')}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -325,7 +354,7 @@ class UiTab extends React.Component {
|
|||||||
ref='scrollPastEnd'
|
ref='scrollPastEnd'
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
/>
|
/>
|
||||||
Allow editor to scroll past the last line
|
{i18n.__('Allow editor to scroll past the last line')}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -336,14 +365,14 @@ class UiTab extends React.Component {
|
|||||||
ref='editorFetchUrlTitle'
|
ref='editorFetchUrlTitle'
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
/>
|
/>
|
||||||
Bring in web page title when pasting URL on editor
|
{i18n.__('Bring in web page title when pasting URL on editor')}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div styleName='group-header2'>Preview</div>
|
<div styleName='group-header2'>{i18n.__('Preview')}</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
Preview Font Size
|
{i18n.__('Preview Font Size')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<input styleName='group-section-control-input'
|
<input styleName='group-section-control-input'
|
||||||
@@ -356,7 +385,7 @@ class UiTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
Preview Font Family
|
{i18n.__('Preview Font Family')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<input styleName='group-section-control-input'
|
<input styleName='group-section-control-input'
|
||||||
@@ -368,7 +397,7 @@ class UiTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>Code block Theme</div>
|
<div styleName='group-section-label'>{i18n.__('Code block Theme')}</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<select value={config.preview.codeBlockTheme}
|
<select value={config.preview.codeBlockTheme}
|
||||||
ref='previewCodeBlockTheme'
|
ref='previewCodeBlockTheme'
|
||||||
@@ -389,7 +418,7 @@ class UiTab extends React.Component {
|
|||||||
ref='previewScrollPastEnd'
|
ref='previewScrollPastEnd'
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
/>
|
/>
|
||||||
Allow preview to scroll past the last line
|
{i18n.__('Allow preview to scroll past the last line')}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-checkBoxSection'>
|
<div styleName='group-checkBoxSection'>
|
||||||
@@ -399,12 +428,22 @@ class UiTab extends React.Component {
|
|||||||
ref='previewLineNumber'
|
ref='previewLineNumber'
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
/>
|
/>
|
||||||
Show line numbers for preview code blocks
|
{i18n.__('Show line numbers for preview code blocks')}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div styleName='group-checkBoxSection'>
|
||||||
|
<label>
|
||||||
|
<input onChange={(e) => this.handleUIChange(e)}
|
||||||
|
checked={this.state.config.preview.smartQuotes}
|
||||||
|
ref='previewSmartQuotes'
|
||||||
|
type='checkbox'
|
||||||
|
/>
|
||||||
|
Enable smart quotes
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
LaTeX Inline Open Delimiter
|
{i18n.__('LaTeX Inline Open Delimiter')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<input styleName='group-section-control-input'
|
<input styleName='group-section-control-input'
|
||||||
@@ -417,7 +456,7 @@ class UiTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
LaTeX Inline Close Delimiter
|
{i18n.__('LaTeX Inline Close Delimiter')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<input styleName='group-section-control-input'
|
<input styleName='group-section-control-input'
|
||||||
@@ -430,7 +469,7 @@ class UiTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
LaTeX Block Open Delimiter
|
{i18n.__('LaTeX Block Open Delimiter')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<input styleName='group-section-control-input'
|
<input styleName='group-section-control-input'
|
||||||
@@ -443,7 +482,7 @@ class UiTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
LaTeX Block Close Delimiter
|
{i18n.__('LaTeX Block Close Delimiter')}
|
||||||
</div>
|
</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
<input styleName='group-section-control-input'
|
<input styleName='group-section-control-input'
|
||||||
@@ -457,7 +496,7 @@ class UiTab extends React.Component {
|
|||||||
|
|
||||||
<div styleName='group-control'>
|
<div styleName='group-control'>
|
||||||
<button styleName='group-control-rightButton'
|
<button styleName='group-control-rightButton'
|
||||||
onClick={(e) => this.handleSaveUIClick(e)}>Save
|
onClick={(e) => this.handleSaveUIClick(e)}>{i18n.__('Save')}
|
||||||
</button>
|
</button>
|
||||||
{UiAlertElement}
|
{UiAlertElement}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import UiTab from './UiTab'
|
|||||||
import InfoTab from './InfoTab'
|
import InfoTab from './InfoTab'
|
||||||
import Crowdfunding from './Crowdfunding'
|
import Crowdfunding from './Crowdfunding'
|
||||||
import StoragesTab from './StoragesTab'
|
import StoragesTab from './StoragesTab'
|
||||||
|
import Blog from './Blog'
|
||||||
import ModalEscButton from 'browser/components/ModalEscButton'
|
import ModalEscButton from 'browser/components/ModalEscButton'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './PreferencesModal.styl'
|
import styles from './PreferencesModal.styl'
|
||||||
import RealtimeNotification from 'browser/components/RealtimeNotification'
|
import RealtimeNotification from 'browser/components/RealtimeNotification'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
class Preferences extends React.Component {
|
class Preferences extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -19,7 +21,8 @@ class Preferences extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
currentTab: 'STORAGES',
|
currentTab: 'STORAGES',
|
||||||
UIAlert: '',
|
UIAlert: '',
|
||||||
HotkeyAlert: ''
|
HotkeyAlert: '',
|
||||||
|
BlogAlert: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +78,14 @@ class Preferences extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<Crowdfunding />
|
<Crowdfunding />
|
||||||
)
|
)
|
||||||
|
case 'BLOG':
|
||||||
|
return (
|
||||||
|
<Blog
|
||||||
|
dispatch={dispatch}
|
||||||
|
config={config}
|
||||||
|
haveToSave={alert => this.setState({BlogAlert: alert})}
|
||||||
|
/>
|
||||||
|
)
|
||||||
case 'STORAGES':
|
case 'STORAGES':
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
@@ -107,11 +118,12 @@ class Preferences extends React.Component {
|
|||||||
const content = this.renderContent()
|
const content = this.renderContent()
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{target: 'STORAGES', label: 'Storage'},
|
{target: 'STORAGES', label: i18n.__('Storage')},
|
||||||
{target: 'HOTKEY', label: 'Hotkeys', Hotkey: this.state.HotkeyAlert},
|
{target: 'HOTKEY', label: i18n.__('Hotkeys'), Hotkey: this.state.HotkeyAlert},
|
||||||
{target: 'UI', label: 'Interface', UI: this.state.UIAlert},
|
{target: 'UI', label: i18n.__('Interface'), UI: this.state.UIAlert},
|
||||||
{target: 'INFO', label: 'About'},
|
{target: 'INFO', label: i18n.__('About')},
|
||||||
{target: 'CROWDFUNDING', label: 'Crowdfunding'}
|
{target: 'CROWDFUNDING', label: i18n.__('Crowdfunding')},
|
||||||
|
{target: 'BLOG', label: i18n.__('Blog'), Blog: this.state.BlogAlert}
|
||||||
]
|
]
|
||||||
|
|
||||||
const navButtons = tabs.map((tab) => {
|
const navButtons = tabs.map((tab) => {
|
||||||
@@ -140,7 +152,7 @@ class Preferences extends React.Component {
|
|||||||
onKeyDown={(e) => this.handleKeyDown(e)}
|
onKeyDown={(e) => this.handleKeyDown(e)}
|
||||||
>
|
>
|
||||||
<div styleName='top-bar'>
|
<div styleName='top-bar'>
|
||||||
<p>Your preferences for Boostnote</p>
|
<p>{i18n.__('Your preferences for Boostnote')}</p>
|
||||||
</div>
|
</div>
|
||||||
<ModalEscButton handleEscButtonClick={(e) => this.handleEscButtonClick(e)} />
|
<ModalEscButton handleEscButtonClick={(e) => this.handleEscButtonClick(e)} />
|
||||||
<div styleName='nav'>
|
<div styleName='nav'>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import styles from './RenameFolderModal.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 ModalEscButton from 'browser/components/ModalEscButton'
|
import ModalEscButton from 'browser/components/ModalEscButton'
|
||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
|
||||||
class RenameFolderModal extends React.Component {
|
class RenameFolderModal extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -72,7 +73,7 @@ class RenameFolderModal extends React.Component {
|
|||||||
onKeyDown={(e) => this.handleKeyDown(e)}
|
onKeyDown={(e) => this.handleKeyDown(e)}
|
||||||
>
|
>
|
||||||
<div styleName='header'>
|
<div styleName='header'>
|
||||||
<div styleName='title'>Rename Folder</div>
|
<div styleName='title'>{i18n.__('Rename Folder')}</div>
|
||||||
</div>
|
</div>
|
||||||
<ModalEscButton handleEscButtonClick={(e) => this.handleCloseButtonClick(e)} />
|
<ModalEscButton handleEscButtonClick={(e) => this.handleCloseButtonClick(e)} />
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ function data (state = defaultDataMap(), action) {
|
|||||||
|
|
||||||
action.notes.some((note) => {
|
action.notes.some((note) => {
|
||||||
if (note === undefined) return true
|
if (note === undefined) return true
|
||||||
const uniqueKey = note.storage + '-' + note.key
|
const uniqueKey = note.key
|
||||||
const folderKey = note.storage + '-' + note.folder
|
const folderKey = note.storage + '-' + note.folder
|
||||||
state.noteMap.set(uniqueKey, note)
|
state.noteMap.set(uniqueKey, note)
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ function data (state = defaultDataMap(), action) {
|
|||||||
case 'UPDATE_NOTE':
|
case 'UPDATE_NOTE':
|
||||||
{
|
{
|
||||||
const note = action.note
|
const note = action.note
|
||||||
const uniqueKey = note.storage + '-' + note.key
|
const uniqueKey = note.key
|
||||||
const folderKey = note.storage + '-' + note.folder
|
const folderKey = note.storage + '-' + note.folder
|
||||||
const oldNote = state.noteMap.get(uniqueKey)
|
const oldNote = state.noteMap.get(uniqueKey)
|
||||||
|
|
||||||
@@ -162,9 +162,9 @@ function data (state = defaultDataMap(), action) {
|
|||||||
case 'MOVE_NOTE':
|
case 'MOVE_NOTE':
|
||||||
{
|
{
|
||||||
const originNote = action.originNote
|
const originNote = action.originNote
|
||||||
const originKey = originNote.storage + '-' + originNote.key
|
const originKey = originNote.key
|
||||||
const note = action.note
|
const note = action.note
|
||||||
const uniqueKey = note.storage + '-' + note.key
|
const uniqueKey = note.key
|
||||||
const folderKey = note.storage + '-' + note.folder
|
const folderKey = note.storage + '-' + note.folder
|
||||||
const oldNote = state.noteMap.get(uniqueKey)
|
const oldNote = state.noteMap.get(uniqueKey)
|
||||||
|
|
||||||
@@ -297,7 +297,7 @@ function data (state = defaultDataMap(), action) {
|
|||||||
}
|
}
|
||||||
case 'DELETE_NOTE':
|
case 'DELETE_NOTE':
|
||||||
{
|
{
|
||||||
const uniqueKey = action.storageKey + '-' + action.noteKey
|
const uniqueKey = action.noteKey
|
||||||
const targetNote = state.noteMap.get(uniqueKey)
|
const targetNote = state.noteMap.get(uniqueKey)
|
||||||
|
|
||||||
state = Object.assign({}, state)
|
state = Object.assign({}, state)
|
||||||
@@ -423,7 +423,7 @@ function data (state = defaultDataMap(), action) {
|
|||||||
state.folderNoteMap = new Map(state.folderNoteMap)
|
state.folderNoteMap = new Map(state.folderNoteMap)
|
||||||
state.tagNoteMap = new Map(state.tagNoteMap)
|
state.tagNoteMap = new Map(state.tagNoteMap)
|
||||||
action.notes.forEach((note) => {
|
action.notes.forEach((note) => {
|
||||||
const uniqueKey = note.storage + '-' + note.key
|
const uniqueKey = note.key
|
||||||
const folderKey = note.storage + '-' + note.folder
|
const folderKey = note.storage + '-' + note.folder
|
||||||
state.noteMap.set(uniqueKey, note)
|
state.noteMap.set(uniqueKey, note)
|
||||||
|
|
||||||
@@ -483,7 +483,7 @@ function data (state = defaultDataMap(), action) {
|
|||||||
state.tagNoteMap = new Map(state.tagNoteMap)
|
state.tagNoteMap = new Map(state.tagNoteMap)
|
||||||
state.starredSet = new Set(state.starredSet)
|
state.starredSet = new Set(state.starredSet)
|
||||||
notes.forEach((note) => {
|
notes.forEach((note) => {
|
||||||
const noteKey = storage.key + '-' + note.key
|
const noteKey = note.key
|
||||||
state.noteMap.delete(noteKey)
|
state.noteMap.delete(noteKey)
|
||||||
state.starredSet.delete(noteKey)
|
state.starredSet.delete(noteKey)
|
||||||
note.tags.forEach((tag) => {
|
note.tags.forEach((tag) => {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ $danger-color = #c9302c
|
|||||||
$danger-lighten-color = lighten(#c9302c, 5%)
|
$danger-lighten-color = lighten(#c9302c, 5%)
|
||||||
|
|
||||||
// Layouts
|
// Layouts
|
||||||
$statusBar-height = 0px
|
$statusBar-height = 22px
|
||||||
$sideNav-width = 200px
|
$sideNav-width = 200px
|
||||||
$sideNav--folded-width = 44px
|
$sideNav--folded-width = 44px
|
||||||
$topBar-height = 60px
|
$topBar-height = 60px
|
||||||
|
|||||||
86
docs/zh_TW/build.md
Normal file
86
docs/zh_TW/build.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# 編譯
|
||||||
|
此文件還提供下列的語言 [日文](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [韓文](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [俄文](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), [簡體中文](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md), [法文](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/build.md) and [德文](https://github.com/BoostIO/Boostnote/blob/master/docs/de/build.md).
|
||||||
|
|
||||||
|
## 環境
|
||||||
|
* npm: 4.x
|
||||||
|
* node: 7.x
|
||||||
|
|
||||||
|
`$ grunt pre-build` 在 `npm v5.x` 有問題,所以只能用 `npm v4.x` 。
|
||||||
|
|
||||||
|
## 開發
|
||||||
|
|
||||||
|
我們使用 Webpack HMR 來開發 Boostnote。
|
||||||
|
|
||||||
|
在專案根目錄底下執行下列指令,將會以原始設置啟動 Boostnote。
|
||||||
|
|
||||||
|
**用 yarn 來安裝必要 packages**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ yarn
|
||||||
|
```
|
||||||
|
|
||||||
|
**開始開發**
|
||||||
|
|
||||||
|
```
|
||||||
|
$ yarn run dev-start
|
||||||
|
```
|
||||||
|
|
||||||
|
上述指令同時運行了 `yarn run webpack` 及 `yarn run hot`,相當於將這兩個指令在不同的 terminal 中運行。
|
||||||
|
|
||||||
|
`webpack` 會同時監控修改過的程式碼,並
|
||||||
|
The `webpack` will watch for code changes and then apply them automatically.
|
||||||
|
|
||||||
|
If the following error occurs: `Failed to load resource: net::ERR_CONNECTION_REFUSED`, please reload Boostnote.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> ### Notice
|
||||||
|
> There are some cases where you have to refresh the app manually.
|
||||||
|
> 1. When editing a constructor method of a component
|
||||||
|
> 2. When adding a new css class (similar to 1: the CSS class is re-written by each component. This process occurs at the Constructor method.)
|
||||||
|
|
||||||
|
## Deploy
|
||||||
|
|
||||||
|
We use Grunt to automate deployment.
|
||||||
|
You can build the program by using `grunt`. However, we don't recommend this because the default task includes codesign and authenticode.
|
||||||
|
|
||||||
|
So, we've prepared a separate script which just makes an executable file.
|
||||||
|
|
||||||
|
This build doesn't work on npm v5.3.0. So you need to use v5.2.0 when you build it.
|
||||||
|
|
||||||
|
```
|
||||||
|
grunt pre-build
|
||||||
|
```
|
||||||
|
|
||||||
|
You will find the executable in the `dist` directory. Note, the auto updater won't work because the app isn't signed.
|
||||||
|
|
||||||
|
If you find it necessary, you can use codesign or authenticode with this executable.
|
||||||
|
|
||||||
|
## Make own distribution packages (deb, rpm)
|
||||||
|
|
||||||
|
Distribution packages are created by exec `grunt build` on Linux platform (e.g. Ubuntu, Fedora).
|
||||||
|
|
||||||
|
> Note: You can create both `.deb` and `.rpm` in a single environment.
|
||||||
|
|
||||||
|
After installing the supported version of `node` and `npm`, install build dependency packages.
|
||||||
|
|
||||||
|
|
||||||
|
Ubuntu/Debian:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt-get install -y rpm fakeroot
|
||||||
|
```
|
||||||
|
|
||||||
|
Fedora:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo dnf install -y dpkg dpkg-dev rpm-build fakeroot
|
||||||
|
```
|
||||||
|
|
||||||
|
Then execute `grunt build`.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ grunt build
|
||||||
|
```
|
||||||
|
|
||||||
|
You will find `.deb` and `.rpm` in the `dist` directory.
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
(function (mod) {
|
||||||
|
if (typeof exports === 'object' && typeof module === 'object') { // Common JS
|
||||||
|
mod(require('../codemirror/lib/codemirror'))
|
||||||
|
} else if (typeof define === 'function' && define.amd) { // AMD
|
||||||
|
define(['../codemirror/lib/codemirror'], mod)
|
||||||
|
} else { // Plain browser env
|
||||||
|
mod(CodeMirror)
|
||||||
|
}
|
||||||
|
})(function (CodeMirror) {
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/
|
||||||
|
var emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/
|
||||||
|
var unorderedListRE = /[*+-]\s/
|
||||||
|
|
||||||
|
CodeMirror.commands.boostNewLineAndIndentContinueMarkdownList = function (cm) {
|
||||||
|
if (cm.getOption('disableInput')) return CodeMirror.Pass
|
||||||
|
var ranges = cm.listSelections()
|
||||||
|
var replacements = []
|
||||||
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
|
var pos = ranges[i].head
|
||||||
|
var eolState = cm.getStateAfter(pos.line)
|
||||||
|
var inList = eolState.list !== false
|
||||||
|
var inQuote = eolState.quote !== 0
|
||||||
|
var line = cm.getLine(pos.line)
|
||||||
|
var match = listRE.exec(line)
|
||||||
|
if (!ranges[i].empty() || (!inList && !inQuote) || !match || pos.ch < match[2].length - 1) {
|
||||||
|
cm.execCommand('newlineAndIndent')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (emptyListRE.test(line)) {
|
||||||
|
if (!/>\s*$/.test(line)) {
|
||||||
|
cm.replaceRange('', {
|
||||||
|
line: pos.line, ch: 0
|
||||||
|
}, {
|
||||||
|
line: pos.line, ch: pos.ch + 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
replacements[i] = '\n'
|
||||||
|
} else {
|
||||||
|
var indent = match[1]
|
||||||
|
var after = match[5]
|
||||||
|
var bullet = unorderedListRE.test(match[2]) || match[2].indexOf('>') >= 0
|
||||||
|
? match[2].replace('x', ' ')
|
||||||
|
: (parseInt(match[3], 10) + 1) + match[4]
|
||||||
|
replacements[i] = '\n' + indent + bullet + after
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cm.replaceSelections(replacements)
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const BrowserWindow = electron.BrowserWindow
|
const BrowserWindow = electron.BrowserWindow
|
||||||
const shell = electron.shell
|
const shell = electron.shell
|
||||||
|
const ipc = electron.ipcMain
|
||||||
const mainWindow = require('./main-window')
|
const mainWindow = require('./main-window')
|
||||||
|
|
||||||
const macOS = process.platform === 'darwin'
|
const macOS = process.platform === 'darwin'
|
||||||
@@ -259,6 +260,23 @@ const view = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let editorFocused
|
||||||
|
|
||||||
|
// Define extra shortcut keys
|
||||||
|
mainWindow.webContents.on('before-input-event', (event, input) => {
|
||||||
|
// Synonyms for Search (Find)
|
||||||
|
if (input.control && input.key === 'f' && input.type === 'keyDown') {
|
||||||
|
if (!editorFocused) {
|
||||||
|
mainWindow.webContents.send('top:focus-search')
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ipc.on('editor:focused', (event, isFocused) => {
|
||||||
|
editorFocused = isFocused
|
||||||
|
})
|
||||||
|
|
||||||
const window = {
|
const window = {
|
||||||
label: 'Window',
|
label: 'Window',
|
||||||
submenu: [
|
submenu: [
|
||||||
@@ -267,6 +285,11 @@ const window = {
|
|||||||
accelerator: 'Command+M',
|
accelerator: 'Command+M',
|
||||||
selector: 'performMiniaturize:'
|
selector: 'performMiniaturize:'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Toggle Full Screen',
|
||||||
|
accelerator: 'Command+Control+F',
|
||||||
|
selector: 'toggleFullScreen:'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'Close',
|
label: 'Close',
|
||||||
accelerator: 'Command+W',
|
accelerator: 'Command+W',
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
<script src="../node_modules/codemirror/keymap/emacs.js"></script>
|
<script src="../node_modules/codemirror/keymap/emacs.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/boost/boostNewLineIndentContinueMarkdownList.js"></script>
|
<script src="../extra_scripts/boost/boostNewLineIndentContinueMarkdownList.js"></script>
|
||||||
|
|
||||||
<script src="../node_modules/codemirror/addon/edit/closebrackets.js"></script>
|
<script src="../node_modules/codemirror/addon/edit/closebrackets.js"></script>
|
||||||
|
|
||||||
@@ -97,7 +97,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="../node_modules/js-sequence-diagrams/fucknpm/sequence-diagram-min.js"></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/dist/react.min.js"></script>
|
||||||
<script src="../node_modules/react-dom/dist/react-dom.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/redux/dist/redux.min.js"></script>
|
||||||
|
|||||||
145
locales/da.json
Normal file
145
locales/da.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
147
locales/de.json
Normal file
147
locales/de.json
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notizen",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Einstellungen",
|
||||||
|
"Make a note": "Notiz erstellen",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "um eine neue Notiz zu erstellen",
|
||||||
|
"Toggle Mode": "Modus umschalten",
|
||||||
|
"Trash": "Papierkorb",
|
||||||
|
"MODIFICATION DATE": "ÄNDERUNGSDATUM",
|
||||||
|
"Words": "Wörter",
|
||||||
|
"Letters": "Buchstaben",
|
||||||
|
"STORAGE": "SPEICHERORT",
|
||||||
|
"FOLDER": "ORDNER",
|
||||||
|
"CREATION DATE": "ERSTELLUNGSDATUM",
|
||||||
|
"NOTE LINK": "NOTIZ LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Deine Boostnote Einstellungen",
|
||||||
|
"Storages": "Speicherorte",
|
||||||
|
"Add Storage Location": "Speicherort Hinzufügen",
|
||||||
|
"Add Folder": "Ordner Hinzufügen",
|
||||||
|
"Open Storage folder": "Speicherort Öffnen",
|
||||||
|
"Unlink": "Verknüpfung aufheben",
|
||||||
|
"Edit": "Bearbeiten",
|
||||||
|
"Delete": "Löschen",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface-Thema",
|
||||||
|
"Default": "Standard",
|
||||||
|
"White": "Weiß",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Bestätigungsdialog beim Löschen von Notizen anzeigen",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Schriftgröße",
|
||||||
|
"Editor Font Family": "Editor Schriftart",
|
||||||
|
"Editor Indent Style": "Editor Einrückestil",
|
||||||
|
"Spaces": "Leerzeichen",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Zur Vorschau wechseln",
|
||||||
|
"When Editor Blurred": "Wenn Editor verschwommen ist",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "Mit Doppelklick bearbeiten, wenn Editor verschwommen ist",
|
||||||
|
"On Right Click": "Mit Rechtsklcik",
|
||||||
|
"Editor Keymap": "Editor Tastenbelegung",
|
||||||
|
"default": "standard",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Boostnote nach Änderung der Tastenbelegung neu starten",
|
||||||
|
"Show line numbers in the editor": "Zeilennummern im Editor anzeigen",
|
||||||
|
"Allow editor to scroll past the last line": "Editor das Scrollen über das Ende hinaus erlauben",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Websitetitel beim Einfügen in den Editor anzeigen",
|
||||||
|
"Preview": "Vorschau",
|
||||||
|
"Preview Font Size": "Vorschau Schriftgröße",
|
||||||
|
"Preview Font Family": "Vorschau Schriftart",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Vorschau das Scrollen über das Ende hinaus erlauben",
|
||||||
|
"Show line numbers for preview code blocks": "Zeilennummern in Vorschau-Code-Blöcken anzeigen",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Newsletter abonnieren",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "Eine OpenSource-Notizapp für Programmierer wie du und ich.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Entwicklung",
|
||||||
|
" : Development configurations for Boostnote.": " : Entwicklungseinstellungen für Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote sammelt anonyme Daten, um die App zu verbessern und nicht persönliche Informationen, wie z.B. der Inhalt deiner Notizen.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "Du kannst wählen, ob du diese Option aktivierst oder daektivierst.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Datenerhebung zur Verbesserung von Boostnote aktivieren",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote Betreuer",
|
||||||
|
"Support via OpenCollective": "Support per OpenCollective",
|
||||||
|
"Language": "Sprache",
|
||||||
|
"English": "Englisch",
|
||||||
|
"German": "Deutsch",
|
||||||
|
"French": "Französisch",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "\"Auf Clipboard gespeichert\" Benachrichtigungen beim kopieren anzeigen",
|
||||||
|
"All Notes": "Alle Notizen",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Sind sie sicher ",
|
||||||
|
" delete": " zu löschen",
|
||||||
|
"this folder?": "diesen Ordner?",
|
||||||
|
"Confirm": "Bestätigen",
|
||||||
|
"Cancel": "Abbrechen",
|
||||||
|
"Markdown Note": "Markdown Notiz",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "Dieses Format dient der Erstellung von Text Dokumenten. Checklisten, Code-Blöcke und Latex-Blöcke sind verfügbar.",
|
||||||
|
"Snippet Note": "Snippet Notiz",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "Dieses Format dient der Erstellung von Code-Schnipslen. Mehrere snippets können zu einer Notiz zusammengefasst werden.",
|
||||||
|
"Tab to switch format": "Tab drücken, um das Format zu wechseln",
|
||||||
|
"Updated": "Bearbeitet",
|
||||||
|
"Created": "Erstellt",
|
||||||
|
"Alphabetically": "Alphabetisch",
|
||||||
|
"Default View": "Standardansicht",
|
||||||
|
"Compressed View": "Komprimierte Ansicht",
|
||||||
|
"Search": "Suchen",
|
||||||
|
"Blog Type": "Blog-Typ",
|
||||||
|
"Blog Address": "Blog Adresse",
|
||||||
|
"Save": "Speichern",
|
||||||
|
"Auth": "Authentifizierung",
|
||||||
|
"Authentication Method": "Authentifizierungsmethode",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "BENUTZER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Speicherorte",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Boostnote anzeigen/verstecken",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Dauerhaft Löschen",
|
||||||
|
"Confirm note deletion": "Löschen bestätigen",
|
||||||
|
"This will permanently remove this note.": "Notiz wird dauerhaft gelöscht",
|
||||||
|
"You have to save!": "Es muss gespeichert werden",
|
||||||
|
"Albanian": "Albanisch",
|
||||||
|
"Danish": "Dänisch",
|
||||||
|
"Japanese": "Japanisch",
|
||||||
|
"Korean": "Koreanisch",
|
||||||
|
"Norwegian": "Norwegisch",
|
||||||
|
"Polish": "Polnish",
|
||||||
|
"Portuguese": "Portugiesisch",
|
||||||
|
"Spanish": "Spanisch",
|
||||||
|
"Chinese (zh-CN)": "Chinesisch (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinesisch (zh-TW)",
|
||||||
|
"Successfully applied!": "Erfolgreich angewendet!",
|
||||||
|
"UserName": "UserName",
|
||||||
|
"Password": "Password",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
147
locales/en.json
Normal file
147
locales/en.json
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"UserName": "UserName",
|
||||||
|
"Password": "Password",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
145
locales/es.json
Normal file
145
locales/es.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
143
locales/fr.json
Normal file
143
locales/fr.json
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Préférences",
|
||||||
|
"Make a note": "Créer une note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "pour créer une nouvelle note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Poubelle",
|
||||||
|
"MODIFICATION DATE": "DATE DE MODIFICATION",
|
||||||
|
"Words": "Mots",
|
||||||
|
"Letters": "Lettres",
|
||||||
|
"STORAGE": "STOCKAGE",
|
||||||
|
"FOLDER": "DOSSIER",
|
||||||
|
"CREATION DATE": "DATE DE CREATION",
|
||||||
|
"NOTE LINK": "LIEN DE LA NOTE",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Imprimer",
|
||||||
|
"Your preferences for Boostnote": "Vos préférences pour Boostnote",
|
||||||
|
"Storages": "Stockages",
|
||||||
|
"Add Storage Location": "Ajouter un espace de stockage",
|
||||||
|
"Add Folder": "Ajouter un dossier",
|
||||||
|
"Open Storage folder": "Ouvrir un dossier de stockage",
|
||||||
|
"Unlink": "Délier",
|
||||||
|
"Edit": "Editer",
|
||||||
|
"Delete": "Supprimer",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Thème d'interface",
|
||||||
|
"Default": "Effacer",
|
||||||
|
"White": "Blanc",
|
||||||
|
"Solarized Dark": "Foncé solarisé",
|
||||||
|
"Dark": "Foncé",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Montrer une alerte de confirmation lors de la suppression de notes",
|
||||||
|
"Editor Theme": "Theme d'éditeur",
|
||||||
|
"Editor Font Size": "Taille de police de l'éditeur",
|
||||||
|
"Editor Font Family": "Police de l'éditeur",
|
||||||
|
"Editor Indent Style": "Style d'indentation de l'éditeur",
|
||||||
|
"Spaces": "Espaces",
|
||||||
|
"Tabs": "Tabulations",
|
||||||
|
"Switch to Preview": "Switcher vers l'aperçu",
|
||||||
|
"When Editor Blurred": "Quand l'éditeur n'est pas sélectionné",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "Quand l'éditeur n'est pas sélectionné, éditer avec un double clic",
|
||||||
|
"On Right Click": "Avec un clic droit",
|
||||||
|
"Editor Keymap": "Keymap de l'éditeur",
|
||||||
|
"default": "Par défaut",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Redémarrez Boostnote après avoir changé la keymap",
|
||||||
|
"Show line numbers in the editor": "Montrer les numéros de lignes dans l'éditeur",
|
||||||
|
"Allow editor to scroll past the last line": "Contrôle si l'éditeur défile au-delà de la dernière ligne",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Mettre le titre de la page lors d'un collé d'une URL dans l'éditeur",
|
||||||
|
"Preview": "Aperçu",
|
||||||
|
"Preview Font Size": "Taille de police de l'aperçu",
|
||||||
|
"Preview Font Family": "Police de l'aperçu",
|
||||||
|
"Code block Theme": "Thème des blocs de code",
|
||||||
|
"Show line numbers for preview code blocks": "Montrer les numéros de lignes dans les blocs de code dans l'aperçu",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Communauté",
|
||||||
|
"Subscribe to Newsletter": "Souscrire à la newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Groupe Facebook",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "A propos",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "Une appli de prise de notes open-source faite pour les développeurs comme vous.",
|
||||||
|
"Website": "Site web",
|
||||||
|
"Development": "Développement",
|
||||||
|
" : Development configurations for Boostnote.": " : Configurations de développement pour Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collecte des données anonymisées dans le seul but d'améliorer l'application, et ne collecte aucune donnée personnelle telle que le contenu de vos notes.",
|
||||||
|
"You can see how it works on ": "Vous pouvez voir comment ça marche sur",
|
||||||
|
"You can choose to enable or disable this option.": "Vous pouvez choisir d'activer/désactiver cette option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Activer la collecte de données anonymisées pour améliorer Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Cher utilisateur,",
|
||||||
|
"Thank you for using Boostnote!": "Merci d'utiliser Boostnote !",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote est utilisé dans plus de 200 pays et régions par une impressionnante communauté de développeurs.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "Afin de continuer à grandir, et de satisfaire les attentes de la communauté,",
|
||||||
|
"we would like to invest more time and resources in this project.": "nous aimerions investir d'avantage de temps et de ressources dans ce proje.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "Si vous aimez ce projet et que vous en voyez tout le potentiel, vous pouvez aider par un support sur OpenCollective !",
|
||||||
|
"Thanks,": "Merci,",
|
||||||
|
"Boostnote maintainers": "Les mainteneurs de Boostnote",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Langues",
|
||||||
|
"English": "Anglais",
|
||||||
|
"German": "Allemand",
|
||||||
|
"French": "Français",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Montrer la notification \"Sauvegardé dans le presse-papiers\" lors de la copie",
|
||||||
|
"All Notes": "Toutes les notes",
|
||||||
|
"Starred": "Favoris",
|
||||||
|
"Are you sure to ": "Etes-vous sûr de ",
|
||||||
|
" delete": " supprimer",
|
||||||
|
"this folder?": "ce dossier ?",
|
||||||
|
"Confirm": "Confimer",
|
||||||
|
"Cancel": "Annuler",
|
||||||
|
"Markdown Note": "Note Markdown",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "Ce format est pour créer des documents texte. Checklists, blocks de code et blocks Latex sont disponibles.",
|
||||||
|
"Snippet Note": "Note Snippet",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "Ce format est pour créer des snippets de code. Plusieurs snippets peuvent être groupés en une seule note.",
|
||||||
|
"Tab to switch format": "Tab pour changer de format",
|
||||||
|
"Updated": "Mis à jour",
|
||||||
|
"Created": "Créé",
|
||||||
|
"Alphabetically": "De manière alphabétique",
|
||||||
|
"Default View": "Vue par défaut",
|
||||||
|
"Compressed View": "Vue compressée",
|
||||||
|
"Search": "Chercher",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Sauvegarder",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Méthode d'Authentification",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Stockage",
|
||||||
|
"Hotkeys": "Raccourcis",
|
||||||
|
"Show/Hide Boostnote": "Montrer/Cacher Boostnote",
|
||||||
|
"Restore": "Restaurer",
|
||||||
|
"Permanent Delete": "Supprimer définivitement",
|
||||||
|
"Confirm note deletion": "Confirmer la suppression de la note",
|
||||||
|
"This will permanently remove this note.": "Cela va supprimer cette note définitivement.",
|
||||||
|
"Successfully applied!": " Succès !",
|
||||||
|
"Albanian": "Albanais",
|
||||||
|
"Chinese (zh-CN)": "Chinois (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinois (zh-TW)",
|
||||||
|
"Danish": "Danois",
|
||||||
|
"Japanese": "Japonais",
|
||||||
|
"Korean": "Coréen",
|
||||||
|
"Norwegian": "Norvégien",
|
||||||
|
"Polish": "Polonais",
|
||||||
|
"Portuguese": "Portugais",
|
||||||
|
"Spanish": "Espagnol",
|
||||||
|
"You have to save!": "Il faut sauvegarder !"
|
||||||
|
}
|
||||||
145
locales/ja.json
Normal file
145
locales/ja.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
145
locales/ko.json
Normal file
145
locales/ko.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
145
locales/no.json
Normal file
145
locales/no.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
145
locales/pl.json
Normal file
145
locales/pl.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
145
locales/pt.json
Normal file
145
locales/pt.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
147
locales/ru.json
Normal file
147
locales/ru.json
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Записи",
|
||||||
|
"Tags": "Теги",
|
||||||
|
"Preferences": "Настройки",
|
||||||
|
"Make a note": "Добавить запись",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "создать новую запись",
|
||||||
|
"Toggle Mode": "Переключить режим",
|
||||||
|
"Trash": "Корзина",
|
||||||
|
"MODIFICATION DATE": "Дата изменения",
|
||||||
|
"Words": "Слова",
|
||||||
|
"Letters": "Буквы",
|
||||||
|
"STORAGE": "Хранилище",
|
||||||
|
"FOLDER": "Папка",
|
||||||
|
"CREATION DATE": "Дата создания",
|
||||||
|
"NOTE LINK": "Ссылка на запись",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Настройки Boostnote",
|
||||||
|
"Storages": "Хранилища",
|
||||||
|
"Add Storage Location": "Добавить хранилище",
|
||||||
|
"Add Folder": "Добавить папку",
|
||||||
|
"Open Storage folder": "Открыть хранилище",
|
||||||
|
"Unlink": "Удалить",
|
||||||
|
"Edit": "Редактировать",
|
||||||
|
"Delete": "Удалить",
|
||||||
|
"Interface": "Интерфейс",
|
||||||
|
"Interface Theme": "Тема оформления",
|
||||||
|
"Default": "По умолчанию",
|
||||||
|
"White": "Светлая",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Темная",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Спрашивать подтверждение перед удалением записей?",
|
||||||
|
"Editor Theme": "Тема",
|
||||||
|
"Editor Font Size": "Размер шрифта",
|
||||||
|
"Editor Font Family": "Шрифт",
|
||||||
|
"Editor Indent Style": "Отступы",
|
||||||
|
"Spaces": "Пробелы",
|
||||||
|
"Tabs": "Табуляция",
|
||||||
|
"Switch to Preview": "Переключать на превью",
|
||||||
|
"When Editor Blurred": "При снятии фокуса с редактора",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "При снятии фокуса, редактировать двойным кликом",
|
||||||
|
"On Right Click": "По правому клику",
|
||||||
|
"Editor Keymap": "Горячие клавиши",
|
||||||
|
"default": "по умолчанию",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Перезапустите Boostnote, чтобы применить изменения",
|
||||||
|
"Show line numbers in the editor": "Показывать номера строк в редакторе",
|
||||||
|
"Allow editor to scroll past the last line": "Разрешить прокрутку дальше последней строки в редакторе",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Копировать заголовок страницы при вставке URL-ссылки в редакторе",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Размер шрифта",
|
||||||
|
"Preview Font Family": "Шрифт",
|
||||||
|
"Code block Theme": "Тема оформления кода",
|
||||||
|
"Allow preview to scroll past the last line": "Разрешить прокрутку дальше последней строки в превью",
|
||||||
|
"Show line numbers for preview code blocks": "Показывать номера строк в блоках кода",
|
||||||
|
"LaTeX Inline Open Delimiter": "Символ начала inline записи в LaTeX",
|
||||||
|
"LaTeX Inline Close Delimiter": "Символ окончания inline записи в LaTeX",
|
||||||
|
"LaTeX Block Open Delimiter": "Символ начала блока LaTeX",
|
||||||
|
"LaTeX Block Close Delimiter": "Символ окончания блока LaTeX",
|
||||||
|
"Community": "Сообщество",
|
||||||
|
"Subscribe to Newsletter": "Подпишитесь на рассылку",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Блог",
|
||||||
|
"Facebook Group": "Группа в Фейсбуке",
|
||||||
|
"Twitter": "Твиттер",
|
||||||
|
"About": "О нас",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "Приложение для программерских и научных заметок с открытым кодом",
|
||||||
|
"Website": "Сайт",
|
||||||
|
"Development": "Разработка",
|
||||||
|
" : Development configurations for Boostnote.": " : Разработческие конфигурации для Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Аналитика",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote собирает анонимные данные о пользовании приложением для того, чтобы улучшать пользовательский опыт. Мы не собираем личную информацию и содержание ваших записей.",
|
||||||
|
"You can see how it works on ": "Посмотрите исходный код на ",
|
||||||
|
"You can choose to enable or disable this option.": "Вы можете отказаться от передачи анонимной информации разработчикам.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Отправлять анонимные данные, чтобы сделать Boostnote еще лучше",
|
||||||
|
"Crowdfunding": "Краудфандинг",
|
||||||
|
"Dear everyone,": "Привет,",
|
||||||
|
"Thank you for using Boostnote!": "Спасибо за использование Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote используется в 200 странах и регионов дружным сообществом разработчиков.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "Чтобы продукт развивался и удовлетворял ожиданиям пользователей,",
|
||||||
|
"we would like to invest more time and resources in this project.": "мы хотим выделять больше времени и ресурсов проекту.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "Если вам нравится Boostnote и его сообщество, вы можете профинансировать проект на OpenCollective!",
|
||||||
|
"Thanks,": "Спасибо,",
|
||||||
|
"Boostnote maintainers": "разработчики Boostnote",
|
||||||
|
"Support via OpenCollective": "Старница проекта на OpenCollective",
|
||||||
|
"Language": "Язык",
|
||||||
|
"English": "Английский",
|
||||||
|
"German": "Немецкий",
|
||||||
|
"French": "Французский",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Показывать уведомление \"Скопировано в буфер\" при копировании?",
|
||||||
|
"All Notes": "Все записи",
|
||||||
|
"Starred": "Избранное",
|
||||||
|
"Are you sure to ": "Вы уверены, что хотите ",
|
||||||
|
" delete": " удалить",
|
||||||
|
"this folder?": "эту папку?",
|
||||||
|
"Confirm": "Да",
|
||||||
|
"Cancel": "Отмена",
|
||||||
|
"Markdown Note": "Markdown",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "Этот формат подходит для создания текстовых документов. Сюда вы можете добавлять чек-листы, блоки кода и блоки в LaTeX.",
|
||||||
|
"Snippet Note": "Snippet",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "Этот формат подходит для хранения кусков кода. Внутри одной записи можно создать несколько сниппетов.",
|
||||||
|
"Tab to switch format": "Tab для переключения формата",
|
||||||
|
"Updated": "По дате изменения",
|
||||||
|
"Created": "По дате создания",
|
||||||
|
"Alphabetically": "По алфавиту",
|
||||||
|
"Default View": "Стандартный вид",
|
||||||
|
"Compressed View": "Сокращенный вид",
|
||||||
|
"Search": "Поиск",
|
||||||
|
"Blog Type": "Тип блога",
|
||||||
|
"Blog Address": "Адрес блога",
|
||||||
|
"Save": "Сохранить",
|
||||||
|
"Auth": "Авторизоваться",
|
||||||
|
"Authentication Method": "Метод авторизации",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Хранилище",
|
||||||
|
"Hotkeys": "Горячие клавиши",
|
||||||
|
"Show/Hide Boostnote": "Показать/скрыть Boostnote",
|
||||||
|
"Restore": "Восстановить",
|
||||||
|
"Permanent Delete": "Удалить без восстановления",
|
||||||
|
"Confirm note deletion": "Подтвердите удаление",
|
||||||
|
"This will permanently remove this note.": "Это действие приведет к полному удалению записи. Восстановить запись будет невозможно.",
|
||||||
|
"Successfully applied!": "Успешно!",
|
||||||
|
"Albanian": "Албанский",
|
||||||
|
"Chinese (zh-CN)": "Китайский (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Китайский (zh-TW)",
|
||||||
|
"Danish": "Датский",
|
||||||
|
"Japanese": "Японский",
|
||||||
|
"Korean": "Корейский",
|
||||||
|
"Norwegian": "Норвежский",
|
||||||
|
"Polish": "Польский",
|
||||||
|
"Portuguese": "Португальский",
|
||||||
|
"Spanish": "Испанский",
|
||||||
|
"You have to save!": "Нужно сохранить!",
|
||||||
|
"UserName": "Имя пользователя",
|
||||||
|
"Password": "Пароль",
|
||||||
|
"Russian": "Русский"
|
||||||
|
}
|
||||||
145
locales/sq.json
Normal file
145
locales/sq.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
145
locales/zh-CN.json
Normal file
145
locales/zh-CN.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
145
locales/zh-TW.json
Normal file
145
locales/zh-TW.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Make a note": "Make a note",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Ctrl(^)": "Ctrl",
|
||||||
|
"to create a new note": "to create a new note",
|
||||||
|
"Toggle Mode": "Toggle Mode",
|
||||||
|
"Trash": "Trash",
|
||||||
|
"MODIFICATION DATE": "MODIFICATION DATE",
|
||||||
|
"Words": "Words",
|
||||||
|
"Letters": "Letters",
|
||||||
|
"STORAGE": "STORAGE",
|
||||||
|
"FOLDER": "FOLDER",
|
||||||
|
"CREATION DATE": "CREATION DATE",
|
||||||
|
"NOTE LINK": "NOTE LINK",
|
||||||
|
".md": ".md",
|
||||||
|
".txt": ".txt",
|
||||||
|
".html": ".html",
|
||||||
|
"Print": "Print",
|
||||||
|
"Your preferences for Boostnote": "Your preferences for Boostnote",
|
||||||
|
"Storages": "Storages",
|
||||||
|
"Add Storage Location": "Add Storage Location",
|
||||||
|
"Add Folder": "Add Folder",
|
||||||
|
"Open Storage folder": "Open Storage folder",
|
||||||
|
"Unlink": "Unlink",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"Interface Theme": "Interface Theme",
|
||||||
|
"Default": "Delete",
|
||||||
|
"White": "White",
|
||||||
|
"Solarized Dark": "Solarized Dark",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Show a confirmation dialog when deleting notes": "Show a confirmation dialog when deleting notes",
|
||||||
|
"Editor Theme": "Editor Theme",
|
||||||
|
"Editor Font Size": "Editor Font Size",
|
||||||
|
"Editor Font Family": "Editor Font Family",
|
||||||
|
"Editor Indent Style": "Editor Indent Style",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Tabs": "Tabs",
|
||||||
|
"Switch to Preview": "Switch to Preview",
|
||||||
|
"When Editor Blurred": "When Editor Blurred",
|
||||||
|
"When Editor Blurred, Edit On Double Click": "When Editor Blurred, Edit On Double Click",
|
||||||
|
"On Right Click": "On Right Click",
|
||||||
|
"Editor Keymap": "Editor Keymap",
|
||||||
|
"default": "default",
|
||||||
|
"vim": "vim",
|
||||||
|
"emacs": "emacs",
|
||||||
|
"⚠️ Please restart boostnote after you change the keymap": "⚠️ Please restart boostnote after you change the keymap",
|
||||||
|
"Show line numbers in the editor": "Show line numbers in the editor",
|
||||||
|
"Allow editor to scroll past the last line": "Allow editor to scroll past the last line",
|
||||||
|
"Bring in web page title when pasting URL on editor": "Bring in web page title when pasting URL on editor",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Preview Font Size": "Preview Font Size",
|
||||||
|
"Preview Font Family": "Preview Font Family",
|
||||||
|
"Code block Theme": "Code block Theme",
|
||||||
|
"Allow preview to scroll past the last line": "Allow preview to scroll past the last line",
|
||||||
|
"Show line numbers for preview code blocks": "Show line numbers for preview code blocks",
|
||||||
|
"LaTeX Inline Open Delimiter": "LaTeX Inline Open Delimiter",
|
||||||
|
"LaTeX Inline Close Delimiter": "LaTeX Inline Close Delimiter",
|
||||||
|
"LaTeX Block Open Delimiter": "LaTeX Block Open Delimiter",
|
||||||
|
"LaTeX Block Close Delimiter": "LaTeX Block Close Delimiter",
|
||||||
|
"Community": "Community",
|
||||||
|
"Subscribe to Newsletter": "Subscribe to Newsletter",
|
||||||
|
"GitHub": "GitHub",
|
||||||
|
"Blog": "Blog",
|
||||||
|
"Facebook Group": "Facebook Group",
|
||||||
|
"Twitter": "Twitter",
|
||||||
|
"About": "About",
|
||||||
|
"Boostnote": "Boostnote",
|
||||||
|
"An open source note-taking app made for programmers just like you.": "An open source note-taking app made for programmers just like you.",
|
||||||
|
"Website": "Website",
|
||||||
|
"Development": "Development",
|
||||||
|
" : Development configurations for Boostnote.": " : Development configurations for Boostnote.",
|
||||||
|
"Copyright (C) 2017 - 2018 BoostIO": "Copyright (C) 2017 - 2018 BoostIO",
|
||||||
|
"License: GPL v3": "License: GPL v3",
|
||||||
|
"Analytics": "Analytics",
|
||||||
|
"Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.",
|
||||||
|
"You can see how it works on ": "You can see how it works on ",
|
||||||
|
"You can choose to enable or disable this option.": "You can choose to enable or disable this option.",
|
||||||
|
"Enable analytics to help improve Boostnote": "Enable analytics to help improve Boostnote",
|
||||||
|
"Crowdfunding": "Crowdfunding",
|
||||||
|
"Dear everyone,": "Dear everyone,",
|
||||||
|
"Thank you for using Boostnote!": "Thank you for using Boostnote!",
|
||||||
|
"Boostnote is used in about 200 different countries and regions by an awesome community of developers.": "Boostnote is used in about 200 different countries and regions by an awesome community of developers.",
|
||||||
|
"To continue supporting this growth, and to satisfy community expectations,": "To continue supporting this growth, and to satisfy community expectations,",
|
||||||
|
"we would like to invest more time and resources in this project.": "we would like to invest more time and resources in this project.",
|
||||||
|
"If you like this project and see its potential, you can help by supporting us on OpenCollective!": "If you like this project and see its potential, you can help by supporting us on OpenCollective!",
|
||||||
|
"Thanks,": "Thanks,",
|
||||||
|
"Boostnote maintainers": "Boostnote maintainers",
|
||||||
|
"Support via OpenCollective": "Support via OpenCollective",
|
||||||
|
"Language": "Language",
|
||||||
|
"English": "English",
|
||||||
|
"German": "German",
|
||||||
|
"French": "French",
|
||||||
|
"Show \"Saved to Clipboard\" notification when copying": "Show \"Saved to Clipboard\" notification when copying",
|
||||||
|
"All Notes": "All Notes",
|
||||||
|
"Starred": "Starred",
|
||||||
|
"Are you sure to ": "Are you sure to ",
|
||||||
|
" delete": " delete",
|
||||||
|
"this folder?": "this folder?",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Markdown Note": "Markdown Note",
|
||||||
|
"This format is for creating text documents. Checklists, code blocks and Latex blocks are available.": "This format is for creating text documents. Checklists, code blocks and Latex blocks are available.",
|
||||||
|
"Snippet Note": "Snippet Note",
|
||||||
|
"This format is for creating code snippets. Multiple snippets can be grouped into a single note.": "This format is for creating code snippets. Multiple snippets can be grouped into a single note.",
|
||||||
|
"Tab to switch format": "Tab to switch format",
|
||||||
|
"Updated": "Updated",
|
||||||
|
"Created": "Created",
|
||||||
|
"Alphabetically": "Alphabetically",
|
||||||
|
"Default View": "Default View",
|
||||||
|
"Compressed View": "Compressed View",
|
||||||
|
"Search": "Search",
|
||||||
|
"Blog Type": "Blog Type",
|
||||||
|
"Blog Address": "Blog Address",
|
||||||
|
"Save": "Save",
|
||||||
|
"Auth": "Auth",
|
||||||
|
"Authentication Method": "Authentication Method",
|
||||||
|
"JWT": "JWT",
|
||||||
|
"USER": "USER",
|
||||||
|
"Token": "Token",
|
||||||
|
"Storage": "Storage",
|
||||||
|
"Hotkeys": "Hotkeys",
|
||||||
|
"Show/Hide Boostnote": "Show/Hide Boostnote",
|
||||||
|
"Restore": "Restore",
|
||||||
|
"Permanent Delete": "Permanent Delete",
|
||||||
|
"Confirm note deletion": "Confirm note deletion",
|
||||||
|
"This will permanently remove this note.": "This will permanently remove this note.",
|
||||||
|
"Successfully applied!": "Successfully applied!",
|
||||||
|
"Albanian": "Albanian",
|
||||||
|
"Chinese (zh-CN)": "Chinese (zh-CN)",
|
||||||
|
"Chinese (zh-TW)": "Chinese (zh-TW)",
|
||||||
|
"Danish": "Danish",
|
||||||
|
"Japanese": "Japanese",
|
||||||
|
"Korean": "Korean",
|
||||||
|
"Norwegian": "Norwegian",
|
||||||
|
"Polish": "Polish",
|
||||||
|
"Portuguese": "Portuguese",
|
||||||
|
"Spanish": "Spanish",
|
||||||
|
"You have to save!": "You have to save!",
|
||||||
|
"Russian": "Russian"
|
||||||
|
}
|
||||||
46
node_modules/boost/boostNewLineIndentContinueMarkdownList.js
generated
vendored
46
node_modules/boost/boostNewLineIndentContinueMarkdownList.js
generated
vendored
@@ -1,46 +0,0 @@
|
|||||||
(function(mod) {
|
|
||||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
||||||
mod(require("../codemirror/lib/codemirror"));
|
|
||||||
else if (typeof define == "function" && define.amd) // AMD
|
|
||||||
define(["../codemirror/lib/codemirror"], mod);
|
|
||||||
else // Plain browser env
|
|
||||||
mod(CodeMirror);
|
|
||||||
})(function(CodeMirror) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
|
|
||||||
emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
|
|
||||||
unorderedListRE = /[*+-]\s/;
|
|
||||||
|
|
||||||
CodeMirror.commands.boostNewLineAndIndentContinueMarkdownList = function(cm) {
|
|
||||||
if (cm.getOption("disableInput")) return CodeMirror.Pass;
|
|
||||||
var ranges = cm.listSelections(), replacements = [];
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
var pos = ranges[i].head;
|
|
||||||
var eolState = cm.getStateAfter(pos.line);
|
|
||||||
var inList = eolState.list !== false;
|
|
||||||
var inQuote = eolState.quote !== 0;
|
|
||||||
var line = cm.getLine(pos.line), match = listRE.exec(line);
|
|
||||||
if (!ranges[i].empty() || (!inList && !inQuote) || !match || pos.ch < match[2].length - 1) {
|
|
||||||
cm.execCommand("newlineAndIndent");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (emptyListRE.test(line)) {
|
|
||||||
if (!/>\s*$/.test(line)) cm.replaceRange("", {
|
|
||||||
line: pos.line, ch: 0
|
|
||||||
}, {
|
|
||||||
line: pos.line, ch: pos.ch + 1
|
|
||||||
});
|
|
||||||
replacements[i] = "\n";
|
|
||||||
} else {
|
|
||||||
var indent = match[1], after = match[5];
|
|
||||||
var bullet = unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0
|
|
||||||
? match[2].replace("x", " ")
|
|
||||||
: (parseInt(match[3], 10) + 1) + match[4];
|
|
||||||
replacements[i] = "\n" + indent + bullet + after;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cm.replaceSelections(replacements);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
35
package-lock.json
generated
Normal file
35
package-lock.json
generated
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "boost",
|
||||||
|
"version": "0.10.0",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"i18n-2": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18n-2/-/i18n-2-0.7.2.tgz",
|
||||||
|
"integrity": "sha512-Rdh6vfpNhL7q61cNf27x7QGULTi1TcGLVdFb5OJ6dOiJo+EkOTqEg0+3xgyeEMgYhopUBsh2IiSkFkjM+EhEmA==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "3.1.0",
|
||||||
|
"sprintf": "0.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
|
},
|
||||||
|
"sprintf": {
|
||||||
|
"version": "0.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/sprintf/-/sprintf-0.1.5.tgz",
|
||||||
|
"integrity": "sha1-j4PjmpMXwaUCy324BQ5Rxnn27c8="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
package.json
18
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "boost",
|
"name": "boost",
|
||||||
"productName": "Boostnote",
|
"productName": "Boostnote",
|
||||||
"version": "0.10.0",
|
"version": "0.11.2",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"description": "Boostnote",
|
"description": "Boostnote",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
@@ -58,9 +58,11 @@
|
|||||||
"electron-gh-releases": "^2.0.2",
|
"electron-gh-releases": "^2.0.2",
|
||||||
"flowchart.js": "^1.6.5",
|
"flowchart.js": "^1.6.5",
|
||||||
"font-awesome": "^4.3.0",
|
"font-awesome": "^4.3.0",
|
||||||
|
"i18n-2": "^0.7.2",
|
||||||
|
"iconv-lite": "^0.4.19",
|
||||||
"immutable": "^3.8.1",
|
"immutable": "^3.8.1",
|
||||||
"js-sequence-diagrams": "^1000000.0.6",
|
"js-sequence-diagrams": "^1000000.0.6",
|
||||||
"katex": "^0.8.3",
|
"katex": "^0.9.0",
|
||||||
"lodash": "^4.11.1",
|
"lodash": "^4.11.1",
|
||||||
"lodash-move": "^1.1.1",
|
"lodash-move": "^1.1.1",
|
||||||
"markdown-it": "^6.0.1",
|
"markdown-it": "^6.0.1",
|
||||||
@@ -84,12 +86,14 @@
|
|||||||
"react-sortable-hoc": "^0.6.7",
|
"react-sortable-hoc": "^0.6.7",
|
||||||
"redux": "^3.5.2",
|
"redux": "^3.5.2",
|
||||||
"sander": "^0.5.1",
|
"sander": "^0.5.1",
|
||||||
|
"sanitize-html": "^1.18.2",
|
||||||
"striptags": "^2.2.1",
|
"striptags": "^2.2.1",
|
||||||
"superagent": "^1.2.0",
|
"superagent": "^1.2.0",
|
||||||
"superagent-promise": "^1.0.3"
|
"superagent-promise": "^1.0.3",
|
||||||
|
"uuid": "^3.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ava": "^0.16.0",
|
"ava": "^0.25.0",
|
||||||
"babel-core": "^6.14.0",
|
"babel-core": "^6.14.0",
|
||||||
"babel-loader": "^6.2.0",
|
"babel-loader": "^6.2.0",
|
||||||
"babel-plugin-react-transform": "^2.0.0",
|
"babel-plugin-react-transform": "^2.0.0",
|
||||||
@@ -98,6 +102,7 @@
|
|||||||
"babel-preset-react": "^6.3.13",
|
"babel-preset-react": "^6.3.13",
|
||||||
"babel-preset-react-hmre": "^1.0.1",
|
"babel-preset-react-hmre": "^1.0.1",
|
||||||
"babel-register": "^6.11.6",
|
"babel-register": "^6.11.6",
|
||||||
|
"browser-env": "^3.2.5",
|
||||||
"concurrently": "^3.4.0",
|
"concurrently": "^3.4.0",
|
||||||
"copy-to-clipboard": "^3.0.6",
|
"copy-to-clipboard": "^3.0.6",
|
||||||
"css-loader": "^0.19.0",
|
"css-loader": "^0.19.0",
|
||||||
@@ -117,6 +122,7 @@
|
|||||||
"jsdom": "^9.4.2",
|
"jsdom": "^9.4.2",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"merge-stream": "^1.0.0",
|
"merge-stream": "^1.0.0",
|
||||||
|
"mock-require": "^3.0.1",
|
||||||
"nib": "^1.1.0",
|
"nib": "^1.1.0",
|
||||||
"react-color": "^2.2.2",
|
"react-color": "^2.2.2",
|
||||||
"react-css-modules": "^3.7.6",
|
"react-css-modules": "^3.7.6",
|
||||||
@@ -140,7 +146,9 @@
|
|||||||
"tests/**/*-test.js"
|
"tests/**/*-test.js"
|
||||||
],
|
],
|
||||||
"require": [
|
"require": [
|
||||||
"babel-register"
|
"babel-register",
|
||||||
|
"./tests/helpers/setup-browser-env.js",
|
||||||
|
"./tests/helpers/setup-electron-mock.js"
|
||||||
],
|
],
|
||||||
"babel": "inherit"
|
"babel": "inherit"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
:mega: Open sourcing our [Android and iOS apps](https://github.com/BoostIO/Boostnote-mobile)!
|
:mega: We've launched a blogging platform with markdown called **[Boostlog](https://boostlog.io/)**.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -25,8 +25,8 @@ Boostnote is an open source project. It's an independent project with its ongoin
|
|||||||
## Community
|
## Community
|
||||||
- [Facebook Group](https://www.facebook.com/groups/boostnote/)
|
- [Facebook Group](https://www.facebook.com/groups/boostnote/)
|
||||||
- [Twitter](https://twitter.com/boostnoteapp)
|
- [Twitter](https://twitter.com/boostnoteapp)
|
||||||
- [Slack Group](https://join.slack.com/t/boostnote-group/shared_invite/enQtMzAzMjI1MTIyNTQ3LTc2MjNiYWU3NTc1YjZlMTk3NzFmOWE1ZWU1MGRhMzBkMGIwMWFjOWMxMDRiM2I2NzkzYzc4OGZhNmVhZjYzZTM)
|
- [Slack Group](https://join.slack.com/t/boostnote-group/shared_invite/enQtMzI3NTIxMTQzMTQzLTUyYWZmZWM1YzcwYzQ5OWQ5YzA3Y2M2NzUzNmIwNzYzMjg5NmQyOGJlNzcyZDJhMGY0ZDc0ZjdlZDFhMDdiMWE)
|
||||||
- [Blog](https://boostlog.io/@junp1234)
|
- [Blog](https://boostlog.io/tags/boostnote)
|
||||||
- [Reddit](https://www.reddit.com/r/Boostnote/)
|
- [Reddit](https://www.reddit.com/r/Boostnote/)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
12
tests/fixtures/TestDummy.js
vendored
12
tests/fixtures/TestDummy.js
vendored
@@ -22,7 +22,7 @@ function dummyBoostnoteJSONData (override = {}, isLegacy = false) {
|
|||||||
if (override.folders == null) {
|
if (override.folders == null) {
|
||||||
data.folders = []
|
data.folders = []
|
||||||
|
|
||||||
var folderCount = Math.floor((Math.random() * 5)) + 1
|
var folderCount = Math.floor((Math.random() * 5)) + 2
|
||||||
for (var i = 0; i < folderCount; i++) {
|
for (var i = 0; i < folderCount; i++) {
|
||||||
var key = keygen()
|
var key = keygen()
|
||||||
while (data.folders.some((folder) => folder.key === key)) {
|
while (data.folders.some((folder) => folder.key === key)) {
|
||||||
@@ -105,11 +105,11 @@ function dummyStorage (storagePath, override = {}) {
|
|||||||
|
|
||||||
sander.writeFileSync(path.join(storagePath, 'boostnote.json'), JSON.stringify(jsonData))
|
sander.writeFileSync(path.join(storagePath, 'boostnote.json'), JSON.stringify(jsonData))
|
||||||
var notesData = []
|
var notesData = []
|
||||||
var noteCount = Math.floor((Math.random() * 15)) + 1
|
var noteCount = Math.floor((Math.random() * 15)) + 2
|
||||||
for (var i = 0; i < noteCount; i++) {
|
for (var i = 0; i < noteCount; i++) {
|
||||||
var key = keygen()
|
var key = keygen(true)
|
||||||
while (notesData.some((note) => note.key === key)) {
|
while (notesData.some((note) => note.key === key)) {
|
||||||
key = keygen()
|
key = keygen(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
var noteData = dummyNote({
|
var noteData = dummyNote({
|
||||||
@@ -149,9 +149,9 @@ function dummyLegacyStorage (storagePath, override = {}) {
|
|||||||
var folderNotes = []
|
var folderNotes = []
|
||||||
var noteCount = Math.floor((Math.random() * 5)) + 1
|
var noteCount = Math.floor((Math.random() * 5)) + 1
|
||||||
for (var i = 0; i < noteCount; i++) {
|
for (var i = 0; i < noteCount; i++) {
|
||||||
var key = keygen(6)
|
var key = keygen(true)
|
||||||
while (folderNotes.some((note) => note.key === key)) {
|
while (folderNotes.some((note) => note.key === key)) {
|
||||||
key = keygen(6)
|
key = keygen(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
var noteData = dummyNote({
|
var noteData = dummyNote({
|
||||||
|
|||||||
57
tests/fixtures/markdowns.js
vendored
Normal file
57
tests/fixtures/markdowns.js
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
const basic = `
|
||||||
|
# Welcome to Boostnote!
|
||||||
|
## Click here to edit markdown :wave:
|
||||||
|
|
||||||
|
<iframe width="560" height="315" src="https://www.youtube.com/embed/L0qNPLsvmyM" frameborder="0" allowfullscreen></iframe>
|
||||||
|
|
||||||
|
## Docs :memo:
|
||||||
|
- [Boostnote | Boost your happiness, productivity and creativity.](https://hackernoon.com/boostnote-boost-your-happiness-productivity-and-creativity-315034efeebe)
|
||||||
|
- [Cloud Syncing & Backups](https://github.com/BoostIO/Boostnote/wiki/Cloud-Syncing-and-Backup)
|
||||||
|
- [How to sync your data across Desktop and Mobile apps](https://github.com/BoostIO/Boostnote/wiki/Sync-Data-Across-Desktop-and-Mobile-apps)
|
||||||
|
- [Convert data from **Evernote** to Boostnote.](https://github.com/BoostIO/Boostnote/wiki/Evernote)
|
||||||
|
- [Keyboard Shortcuts](https://github.com/BoostIO/Boostnote/wiki/Keyboard-Shortcuts)
|
||||||
|
- [Keymaps in Editor mode](https://github.com/BoostIO/Boostnote/wiki/Keymaps-in-Editor-mode)
|
||||||
|
- [How to set syntax highlight in Snippet note](https://github.com/BoostIO/Boostnote/wiki/Syntax-Highlighting)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Article Archive :books:
|
||||||
|
- [Reddit English](http://bit.ly/2mOJPu7)
|
||||||
|
- [Reddit Spanish](https://www.reddit.com/r/boostnote_es/)
|
||||||
|
- [Reddit Chinese](https://www.reddit.com/r/boostnote_cn/)
|
||||||
|
- [Reddit Japanese](https://www.reddit.com/r/boostnote_jp/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community :beers:
|
||||||
|
- [GitHub](http://bit.ly/2AWWzkD)
|
||||||
|
- [Twitter](http://bit.ly/2z8BUJZ)
|
||||||
|
- [Facebook Group](http://bit.ly/2jcca8t)
|
||||||
|
`
|
||||||
|
|
||||||
|
const codeblock = `
|
||||||
|
\`\`\`js:filename.js:2
|
||||||
|
var project = 'boostnote';
|
||||||
|
\`\`\`
|
||||||
|
`
|
||||||
|
|
||||||
|
const katex = `
|
||||||
|
$$
|
||||||
|
c = \pm\sqrt{a^2 + b^2}
|
||||||
|
$$
|
||||||
|
`
|
||||||
|
|
||||||
|
const checkboxes = `
|
||||||
|
- [ ] Unchecked
|
||||||
|
- [x] Checked
|
||||||
|
`
|
||||||
|
|
||||||
|
const smartQuotes = 'This is a "QUOTE".'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
basic,
|
||||||
|
codeblock,
|
||||||
|
katex,
|
||||||
|
checkboxes,
|
||||||
|
smartQuotes
|
||||||
|
}
|
||||||
9
tests/helpers/setup-browser-env.js
Normal file
9
tests/helpers/setup-browser-env.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import browserEnv from 'browser-env'
|
||||||
|
browserEnv(['window', 'document'])
|
||||||
|
|
||||||
|
window.localStorage = {
|
||||||
|
// polyfill
|
||||||
|
getItem () {
|
||||||
|
return '{}'
|
||||||
|
}
|
||||||
|
}
|
||||||
11
tests/helpers/setup-electron-mock.js
Normal file
11
tests/helpers/setup-electron-mock.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import mock from 'mock-require'
|
||||||
|
|
||||||
|
const noop = () => {}
|
||||||
|
|
||||||
|
mock('electron', {
|
||||||
|
remote: {
|
||||||
|
app: {
|
||||||
|
getAppPath: noop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
36
tests/lib/markdown-test.js
Normal file
36
tests/lib/markdown-test.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import test from 'ava'
|
||||||
|
import Markdown from 'browser/lib/markdown'
|
||||||
|
import markdownFixtures from '../fixtures/markdowns'
|
||||||
|
|
||||||
|
// basic markdown instance which meant to be used in every test cases.
|
||||||
|
// To test markdown options, initialize a new instance in your test case
|
||||||
|
const md = new Markdown()
|
||||||
|
|
||||||
|
test('Markdown.render() should renders markdown correctly', t => {
|
||||||
|
const rendered = md.render(markdownFixtures.basic)
|
||||||
|
t.snapshot(rendered)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Markdown.render() should renders codeblock correctly', t => {
|
||||||
|
const rendered = md.render(markdownFixtures.codeblock)
|
||||||
|
t.snapshot(rendered)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Markdown.render() should renders KaTeX correctly', t => {
|
||||||
|
const rendered = md.render(markdownFixtures.katex)
|
||||||
|
t.snapshot(rendered)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Markdown.render() should renders checkboxes', t => {
|
||||||
|
const rendered = md.render(markdownFixtures.checkboxes)
|
||||||
|
t.snapshot(rendered)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Markdown.render() should text with quotes correctly', t => {
|
||||||
|
const renderedSmartQuotes = md.render(markdownFixtures.smartQuotes)
|
||||||
|
t.snapshot(renderedSmartQuotes)
|
||||||
|
|
||||||
|
const newmd = new Markdown({ typographer: false })
|
||||||
|
const renderedNonSmartQuotes = newmd.render(markdownFixtures.smartQuotes)
|
||||||
|
t.snapshot(renderedNonSmartQuotes)
|
||||||
|
})
|
||||||
@@ -29,5 +29,5 @@ test('RcParser should return a json object', t => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function filePath (filename) {
|
function filePath (filename) {
|
||||||
return path.join('boostnoterc', filename)
|
return path.join(`${__dirname}/boostnoterc`, filename)
|
||||||
}
|
}
|
||||||
|
|||||||
76
tests/lib/snapshots/markdown-test.js.md
Normal file
76
tests/lib/snapshots/markdown-test.js.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# Snapshot report for `tests/lib/markdown-test.js`
|
||||||
|
|
||||||
|
The actual snapshot is saved in `markdown-test.js.snap`.
|
||||||
|
|
||||||
|
Generated by [AVA](https://ava.li).
|
||||||
|
|
||||||
|
## Markdown.render() should renders KaTeX correctly
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
`<span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>c</mi><mo>=</mo><mi>p</mi><mi>m</mi><mi>s</mi><mi>q</mi><mi>r</mi><mi>t</mi><mrow><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><msup><mi>b</mi><mn>2</mn></msup></mrow></mrow><annotation encoding="application/x-tex">c = pmsqrt{a^2 + b^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.8641079999999999em;"></span><span class="strut bottom" style="height:1.0585479999999998em;vertical-align:-0.19444em;"></span><span class="base"><span class="mord mathit">c</span><span class="mord rule" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mord rule" style="margin-right:0.2777777777777778em;"></span><span class="mord mathit">p</span><span class="mord mathit">m</span><span class="mord mathit">s</span><span class="mord mathit" style="margin-right:0.03588em;">q</span><span class="mord mathit" style="margin-right:0.02778em;">r</span><span class="mord mathit">t</span><span class="mord"><span class="mord"><span class="mord mathit">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord rule" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mord rule" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathit">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span></span>␊
|
||||||
|
`
|
||||||
|
|
||||||
|
## Markdown.render() should renders checkboxes
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
`<ul>␊
|
||||||
|
<li class="taskListItem"><input type="checkbox" id="checkbox-2" /> Unchecked</li>␊
|
||||||
|
<li class="taskListItem"><input type="checkbox" checked id="checkbox-3" /> Checked</li>␊
|
||||||
|
</ul>␊
|
||||||
|
`
|
||||||
|
|
||||||
|
## Markdown.render() should renders codeblock correctly
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
`<pre class="code CodeMirror"><span class="filename">filename.js</span><span class="lineNumber CodeMirror-gutters"><span class="CodeMirror-linenumber">2</span></span><code class="js">var project = 'boostnote';␊
|
||||||
|
</code></pre>␊
|
||||||
|
`
|
||||||
|
|
||||||
|
## Markdown.render() should renders markdown correctly
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
`<h1 data-line="1" id="Welcome-to-Boostnote">Welcome to Boostnote!</h1>␊
|
||||||
|
<h2 data-line="2" id="Click-here-to-edit-markdown-%F0%9F%91%8B">Click here to edit markdown 👋</h2>␊
|
||||||
|
<iframe width="560" height="315" src="https://www.youtube.com/embed/L0qNPLsvmyM" frameborder="0" allowfullscreen></iframe>␊
|
||||||
|
<h2 data-line="6" id="Docs-%F0%9F%93%9D">Docs 📝</h2>␊
|
||||||
|
<ul>␊
|
||||||
|
<li><a href="https://hackernoon.com/boostnote-boost-your-happiness-productivity-and-creativity-315034efeebe">Boostnote | Boost your happiness, productivity and creativity.</a></li>␊
|
||||||
|
<li><a href="https://github.com/BoostIO/Boostnote/wiki/Cloud-Syncing-and-Backup">Cloud Syncing & Backups</a></li>␊
|
||||||
|
<li><a href="https://github.com/BoostIO/Boostnote/wiki/Sync-Data-Across-Desktop-and-Mobile-apps">How to sync your data across Desktop and Mobile apps</a></li>␊
|
||||||
|
<li><a href="https://github.com/BoostIO/Boostnote/wiki/Evernote">Convert data from <strong>Evernote</strong> to Boostnote.</a></li>␊
|
||||||
|
<li><a href="https://github.com/BoostIO/Boostnote/wiki/Keyboard-Shortcuts">Keyboard Shortcuts</a></li>␊
|
||||||
|
<li><a href="https://github.com/BoostIO/Boostnote/wiki/Keymaps-in-Editor-mode">Keymaps in Editor mode</a></li>␊
|
||||||
|
<li><a href="https://github.com/BoostIO/Boostnote/wiki/Syntax-Highlighting">How to set syntax highlight in Snippet note</a></li>␊
|
||||||
|
</ul>␊
|
||||||
|
<hr />␊
|
||||||
|
<h2 data-line="17" id="Article-Archive-%F0%9F%93%9A">Article Archive 📚</h2>␊
|
||||||
|
<ul>␊
|
||||||
|
<li><a href="http://bit.ly/2mOJPu7">Reddit English</a></li>␊
|
||||||
|
<li><a href="https://www.reddit.com/r/boostnote_es/">Reddit Spanish</a></li>␊
|
||||||
|
<li><a href="https://www.reddit.com/r/boostnote_cn/">Reddit Chinese</a></li>␊
|
||||||
|
<li><a href="https://www.reddit.com/r/boostnote_jp/">Reddit Japanese</a></li>␊
|
||||||
|
</ul>␊
|
||||||
|
<hr />␊
|
||||||
|
<h2 data-line="25" id="Community-%F0%9F%8D%BB">Community 🍻</h2>␊
|
||||||
|
<ul>␊
|
||||||
|
<li><a href="http://bit.ly/2AWWzkD">GitHub</a></li>␊
|
||||||
|
<li><a href="http://bit.ly/2z8BUJZ">Twitter</a></li>␊
|
||||||
|
<li><a href="http://bit.ly/2jcca8t">Facebook Group</a></li>␊
|
||||||
|
</ul>␊
|
||||||
|
`
|
||||||
|
|
||||||
|
## Markdown.render() should text with quotes correctly
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
`<p data-line="0">This is a “QUOTE”.</p>␊
|
||||||
|
`
|
||||||
|
|
||||||
|
> Snapshot 2
|
||||||
|
|
||||||
|
`<p data-line="0">This is a "QUOTE".</p>␊
|
||||||
|
`
|
||||||
BIN
tests/lib/snapshots/markdown-test.js.snap
Normal file
BIN
tests/lib/snapshots/markdown-test.js.snap
Normal file
Binary file not shown.
Reference in New Issue
Block a user