mirror of
https://github.com/BoostIo/Boostnote
synced 2026-02-05 03:57:18 +00:00
Merge branch 'master' into theme-nord
This commit is contained in:
@@ -3,7 +3,7 @@ import React from 'react'
|
||||
import CSSModules from 'browser/lib/CSSModules'
|
||||
import styles from './CreateFolderModal.styl'
|
||||
import dataApi from 'browser/main/lib/dataApi'
|
||||
import store from 'browser/main/store'
|
||||
import { store } from 'browser/main/store'
|
||||
import consts from 'browser/lib/consts'
|
||||
import ModalEscButton from 'browser/components/ModalEscButton'
|
||||
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
|
||||
|
||||
118
browser/main/modals/CreateMarkdownFromURLModal.js
Normal file
118
browser/main/modals/CreateMarkdownFromURLModal.js
Normal file
@@ -0,0 +1,118 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
import CSSModules from 'browser/lib/CSSModules'
|
||||
import styles from './CreateMarkdownFromURLModal.styl'
|
||||
import dataApi from 'browser/main/lib/dataApi'
|
||||
import ModalEscButton from 'browser/components/ModalEscButton'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
|
||||
class CreateMarkdownFromURLModal extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
name: '',
|
||||
showerror: false,
|
||||
errormessage: ''
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.refs.name.focus()
|
||||
this.refs.name.select()
|
||||
}
|
||||
|
||||
handleCloseButtonClick (e) {
|
||||
this.props.close()
|
||||
}
|
||||
|
||||
handleChange (e) {
|
||||
this.setState({
|
||||
name: this.refs.name.value
|
||||
})
|
||||
}
|
||||
|
||||
handleKeyDown (e) {
|
||||
if (e.keyCode === 27) {
|
||||
this.props.close()
|
||||
}
|
||||
}
|
||||
|
||||
handleInputKeyDown (e) {
|
||||
switch (e.keyCode) {
|
||||
case 13:
|
||||
this.confirm()
|
||||
}
|
||||
}
|
||||
|
||||
handleConfirmButtonClick (e) {
|
||||
this.confirm()
|
||||
}
|
||||
|
||||
showError (message) {
|
||||
this.setState({
|
||||
showerror: true,
|
||||
errormessage: message
|
||||
})
|
||||
}
|
||||
|
||||
hideError () {
|
||||
this.setState({
|
||||
showerror: false,
|
||||
errormessage: ''
|
||||
})
|
||||
}
|
||||
|
||||
confirm () {
|
||||
this.hideError()
|
||||
const { storage, folder, dispatch, location } = this.props
|
||||
|
||||
dataApi.createNoteFromUrl(this.state.name, storage, folder, dispatch, location).then((result) => {
|
||||
this.props.close()
|
||||
}).catch((result) => {
|
||||
this.showError(result.error)
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div styleName='root'
|
||||
tabIndex='-1'
|
||||
onKeyDown={(e) => this.handleKeyDown(e)}
|
||||
>
|
||||
<div styleName='header'>
|
||||
<div styleName='title'>{i18n.__('Import Markdown From URL')}</div>
|
||||
</div>
|
||||
<ModalEscButton handleEscButtonClick={(e) => this.handleCloseButtonClick(e)} />
|
||||
<div styleName='control'>
|
||||
<div styleName='control-folder'>
|
||||
<div styleName='control-folder-label'>{i18n.__('Insert URL Here')}</div>
|
||||
<input styleName='control-folder-input'
|
||||
ref='name'
|
||||
value={this.state.name}
|
||||
onChange={(e) => this.handleChange(e)}
|
||||
onKeyDown={(e) => this.handleInputKeyDown(e)}
|
||||
/>
|
||||
</div>
|
||||
<button styleName='control-confirmButton'
|
||||
onClick={(e) => this.handleConfirmButtonClick(e)}
|
||||
>
|
||||
{i18n.__('Import')}
|
||||
</button>
|
||||
<div className='error' styleName='error'>{this.state.errormessage}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
CreateMarkdownFromURLModal.propTypes = {
|
||||
storage: PropTypes.string,
|
||||
folder: PropTypes.string,
|
||||
dispatch: PropTypes.func,
|
||||
location: PropTypes.shape({
|
||||
pathname: PropTypes.string
|
||||
})
|
||||
}
|
||||
|
||||
export default CSSModules(CreateMarkdownFromURLModal, styles)
|
||||
160
browser/main/modals/CreateMarkdownFromURLModal.styl
Normal file
160
browser/main/modals/CreateMarkdownFromURLModal.styl
Normal file
@@ -0,0 +1,160 @@
|
||||
.root
|
||||
modal()
|
||||
width 500px
|
||||
height 270px
|
||||
overflow hidden
|
||||
position relative
|
||||
|
||||
.header
|
||||
height 80px
|
||||
margin-bottom 10px
|
||||
margin-top 20px
|
||||
font-size 18px
|
||||
line-height 50px
|
||||
background-color $ui-backgroundColor
|
||||
color $ui-text-color
|
||||
|
||||
.title
|
||||
font-size 36px
|
||||
font-weight 600
|
||||
|
||||
.control-folder-label
|
||||
text-align left
|
||||
font-size 14px
|
||||
color $ui-text-color
|
||||
|
||||
.control-folder-input
|
||||
display block
|
||||
height 40px
|
||||
width 490px
|
||||
padding 0 5px
|
||||
margin 10px 0
|
||||
border 1px solid $ui-input--create-folder-modal
|
||||
border-radius 2px
|
||||
background-color transparent
|
||||
outline none
|
||||
vertical-align middle
|
||||
font-size 16px
|
||||
&:disabled
|
||||
background-color $ui-input--disabled-backgroundColor
|
||||
&:focus, &:active
|
||||
border-color $ui-active-color
|
||||
|
||||
.control-confirmButton
|
||||
display block
|
||||
height 35px
|
||||
width 140px
|
||||
border none
|
||||
border-radius 2px
|
||||
padding 0 25px
|
||||
margin 20px auto
|
||||
font-size 14px
|
||||
colorPrimaryButton()
|
||||
|
||||
body[data-theme="dark"]
|
||||
.root
|
||||
modalDark()
|
||||
width 500px
|
||||
height 270px
|
||||
overflow hidden
|
||||
position relative
|
||||
|
||||
.header
|
||||
background-color transparent
|
||||
border-color $ui-dark-borderColor
|
||||
color $ui-dark-text-color
|
||||
|
||||
.control-folder-label
|
||||
color $ui-dark-text-color
|
||||
|
||||
.control-folder-input
|
||||
border 1px solid $ui-input--create-folder-modal
|
||||
color white
|
||||
|
||||
.description
|
||||
color $ui-inactive-text-color
|
||||
|
||||
.control-confirmButton
|
||||
colorDarkPrimaryButton()
|
||||
|
||||
body[data-theme="solarized-dark"]
|
||||
.root
|
||||
modalSolarizedDark()
|
||||
width 500px
|
||||
height 270px
|
||||
overflow hidden
|
||||
position relative
|
||||
|
||||
.header
|
||||
background-color transparent
|
||||
border-color $ui-dark-borderColor
|
||||
color $ui-solarized-dark-text-color
|
||||
|
||||
.control-folder-label
|
||||
color $ui-solarized-dark-text-color
|
||||
|
||||
.control-folder-input
|
||||
border 1px solid $ui-input--create-folder-modal
|
||||
color white
|
||||
|
||||
.description
|
||||
color $ui-inactive-text-color
|
||||
|
||||
.control-confirmButton
|
||||
colorSolarizedDarkPrimaryButton()
|
||||
|
||||
.error
|
||||
text-align center
|
||||
color #F44336
|
||||
|
||||
body[data-theme="monokai"]
|
||||
.root
|
||||
modalMonokai()
|
||||
width 500px
|
||||
height 270px
|
||||
overflow hidden
|
||||
position relative
|
||||
|
||||
.header
|
||||
background-color transparent
|
||||
border-color $ui-dark-borderColor
|
||||
color $ui-monokai-text-color
|
||||
|
||||
.control-folder-label
|
||||
color $ui-monokai-text-color
|
||||
|
||||
.control-folder-input
|
||||
border 1px solid $ui-input--create-folder-modal
|
||||
color white
|
||||
|
||||
.description
|
||||
color $ui-inactive-text-color
|
||||
|
||||
.control-confirmButton
|
||||
colorMonokaiPrimaryButton()
|
||||
|
||||
body[data-theme="dracula"]
|
||||
.root
|
||||
modalDracula()
|
||||
width 500px
|
||||
height 270px
|
||||
overflow hidden
|
||||
position relative
|
||||
|
||||
.header
|
||||
background-color transparent
|
||||
border-color $ui-dracula-borderColor
|
||||
color $ui-dracula-text-color
|
||||
|
||||
.control-folder-label
|
||||
color $ui-dracula-text-color
|
||||
|
||||
.control-folder-input
|
||||
border 1px solid $ui-input--create-folder-modal
|
||||
color white
|
||||
|
||||
.description
|
||||
color $ui-inactive-text-color
|
||||
|
||||
.control-confirmButton
|
||||
colorDraculaPrimaryButton()
|
||||
@@ -3,12 +3,15 @@ import CSSModules from 'browser/lib/CSSModules'
|
||||
import styles from './NewNoteModal.styl'
|
||||
import ModalEscButton from 'browser/components/ModalEscButton'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
import { openModal } from 'browser/main/lib/modal'
|
||||
import CreateMarkdownFromURLModal from '../modals/CreateMarkdownFromURLModal'
|
||||
import { createMarkdownNote, createSnippetNote } from 'browser/lib/newNote'
|
||||
import queryString from 'query-string'
|
||||
|
||||
class NewNoteModal extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.lock = false
|
||||
this.state = {}
|
||||
}
|
||||
|
||||
@@ -20,13 +23,29 @@ class NewNoteModal extends React.Component {
|
||||
this.props.close()
|
||||
}
|
||||
|
||||
handleMarkdownNoteButtonClick (e) {
|
||||
const { storage, folder, dispatch, location, params, config } = this.props
|
||||
createMarkdownNote(storage, folder, dispatch, location, params, config).then(() => {
|
||||
setTimeout(this.props.close, 200)
|
||||
handleCreateMarkdownFromUrlClick (e) {
|
||||
this.props.close()
|
||||
|
||||
const { storage, folder, dispatch, location } = this.props
|
||||
openModal(CreateMarkdownFromURLModal, {
|
||||
storage: storage,
|
||||
folder: folder,
|
||||
dispatch,
|
||||
location
|
||||
})
|
||||
}
|
||||
|
||||
handleMarkdownNoteButtonClick (e) {
|
||||
const { storage, folder, dispatch, location, config } = this.props
|
||||
const params = location.search !== '' && queryString.parse(location.search)
|
||||
if (!this.lock) {
|
||||
this.lock = true
|
||||
createMarkdownNote(storage, folder, dispatch, location, params, config).then(() => {
|
||||
setTimeout(this.props.close, 200)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handleMarkdownNoteButtonKeyDown (e) {
|
||||
if (e.keyCode === 9) {
|
||||
e.preventDefault()
|
||||
@@ -35,10 +54,14 @@ class NewNoteModal extends React.Component {
|
||||
}
|
||||
|
||||
handleSnippetNoteButtonClick (e) {
|
||||
const { storage, folder, dispatch, location, params, config } = this.props
|
||||
createSnippetNote(storage, folder, dispatch, location, params, config).then(() => {
|
||||
setTimeout(this.props.close, 200)
|
||||
})
|
||||
const { storage, folder, dispatch, location, config } = this.props
|
||||
const params = location.search !== '' && queryString.parse(location.search)
|
||||
if (!this.lock) {
|
||||
this.lock = true
|
||||
createSnippetNote(storage, folder, dispatch, location, params, config).then(() => {
|
||||
setTimeout(this.props.close, 200)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handleSnippetNoteButtonKeyDown (e) {
|
||||
@@ -106,10 +129,8 @@ class NewNoteModal extends React.Component {
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div styleName='description'>
|
||||
<i className='fa fa-arrows-h' />{i18n.__('Tab to switch format')}
|
||||
</div>
|
||||
|
||||
<div styleName='description'><i className='fa fa-arrows-h' />{i18n.__('Tab to switch format')}</div>
|
||||
<div styleName='from-url' onClick={(e) => this.handleCreateMarkdownFromUrlClick(e)}>Or, create a new markdown note from a URL</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
.control
|
||||
padding 25px 0px
|
||||
text-align center
|
||||
display: flex
|
||||
|
||||
.control-button
|
||||
width 240px
|
||||
@@ -47,6 +48,12 @@
|
||||
text-align center
|
||||
margin-bottom 25px
|
||||
|
||||
.from-url
|
||||
color $ui-inactive-text-color
|
||||
text-align center
|
||||
margin-bottom 25px
|
||||
cursor pointer
|
||||
|
||||
apply-theme(theme)
|
||||
body[data-theme={theme}]
|
||||
.root
|
||||
@@ -69,4 +76,4 @@ for theme in 'dark' 'solarized-dark' 'dracula'
|
||||
apply-theme(theme)
|
||||
|
||||
for theme in $themes
|
||||
apply-theme(theme)
|
||||
apply-theme(theme)
|
||||
|
||||
@@ -2,7 +2,7 @@ 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 { store } from 'browser/main/store'
|
||||
import PropTypes from 'prop-types'
|
||||
import _ from 'lodash'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
|
||||
@@ -18,6 +18,14 @@
|
||||
margin-bottom 15px
|
||||
margin-top 30px
|
||||
|
||||
.group-header--sub
|
||||
@extend .group-header
|
||||
margin-bottom 10px
|
||||
|
||||
.group-header2--sub
|
||||
@extend .group-header2
|
||||
margin-bottom 10px
|
||||
|
||||
.group-section
|
||||
margin-bottom 20px
|
||||
display flex
|
||||
@@ -138,10 +146,12 @@ body[data-theme="dark"]
|
||||
color $ui-dark-text-color
|
||||
|
||||
.group-header
|
||||
.group-header--sub
|
||||
color $ui-dark-text-color
|
||||
border-color $ui-dark-borderColor
|
||||
|
||||
.group-header2
|
||||
.group-header2--sub
|
||||
color $ui-dark-text-color
|
||||
|
||||
.group-section-control-input
|
||||
@@ -192,4 +202,4 @@ for theme in 'solarized-dark' 'dracula'
|
||||
apply-theme(theme)
|
||||
|
||||
for theme in $themes
|
||||
apply-theme(theme)
|
||||
apply-theme(theme)
|
||||
|
||||
@@ -22,18 +22,16 @@ class Crowdfunding extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<div styleName='root'>
|
||||
<div styleName='header'>{i18n.__('Crowdfunding')}</div>
|
||||
<div styleName='group-header'>{i18n.__('Crowdfunding')}</div>
|
||||
<p>{i18n.__('Thank you for using Boostnote!')}</p>
|
||||
<br />
|
||||
<p>{i18n.__('We launched IssueHunt which is an issue-based crowdfunding / sourcing platform for open source projects.')}</p>
|
||||
<p>{i18n.__('Anyone can put a bounty on not only a bug but also on OSS feature requests listed on IssueHunt. Collected funds will be distributed to project owners and contributors.')}</p>
|
||||
<br />
|
||||
<p>{i18n.__('### Sustainable Open Source Ecosystem')}</p>
|
||||
<div styleName='group-header2--sub'>{i18n.__('Sustainable Open Source Ecosystem')}</div>
|
||||
<p>{i18n.__('We discussed about open-source ecosystem and IssueHunt concept with the Boostnote team repeatedly. We actually also discussed with Matz who father of Ruby.')}</p>
|
||||
<p>{i18n.__('The original reason why we made IssueHunt was to reward our contributors of Boostnote project. We’ve got tons of Github stars and hundred of contributors in two years.')}</p>
|
||||
<p>{i18n.__('We thought that it will be nice if we can pay reward for our contributors.')}</p>
|
||||
<br />
|
||||
<p>{i18n.__('### We believe Meritocracy')}</p>
|
||||
<div styleName='group-header2--sub'>{i18n.__('We believe Meritocracy')}</div>
|
||||
<p>{i18n.__('We think developers who have skills and do great things must be rewarded properly.')}</p>
|
||||
<p>{i18n.__('OSS projects are used in everywhere on the internet, but no matter how they great, most of owners of those projects need to have another job to sustain their living.')}</p>
|
||||
<p>{i18n.__('It sometimes looks like exploitation.')}</p>
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
@import('./Tab')
|
||||
@import('./ConfigTab')
|
||||
|
||||
.root
|
||||
padding 15px
|
||||
white-space pre
|
||||
line-height 1.4
|
||||
color alpha($ui-text-color, 90%)
|
||||
width 100%
|
||||
font-size 14px
|
||||
p
|
||||
font-size 16px
|
||||
line-height 1.4
|
||||
|
||||
.cf-link
|
||||
height 35px
|
||||
|
||||
@@ -4,7 +4,7 @@ import CSSModules from 'browser/lib/CSSModules'
|
||||
import ReactDOM from 'react-dom'
|
||||
import styles from './FolderItem.styl'
|
||||
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 { SortableElement, SortableHandle } from 'react-sortable-hoc'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
@@ -225,7 +225,7 @@ class FolderItem extends React.Component {
|
||||
<div styleName='folderItem-left'
|
||||
style={{borderColor: folder.color}}
|
||||
>
|
||||
<span styleName='folderItem-left-name'>{folder.name}</span>
|
||||
<span>{folder.name}</span>
|
||||
<span styleName='folderItem-left-key'>({folder.key})</span>
|
||||
</div>
|
||||
<div styleName='folderItem-right'>
|
||||
@@ -288,10 +288,10 @@ class Handle extends React.Component {
|
||||
|
||||
class SortableFolderItemComponent extends React.Component {
|
||||
render () {
|
||||
const StyledHandle = CSSModules(Handle, this.props.styles)
|
||||
const StyledHandle = CSSModules(Handle, styles)
|
||||
const DragHandle = SortableHandle(StyledHandle)
|
||||
|
||||
const StyledFolderItem = CSSModules(FolderItem, this.props.styles)
|
||||
const StyledFolderItem = CSSModules(FolderItem, styles)
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from 'react'
|
||||
import CSSModules from 'browser/lib/CSSModules'
|
||||
import dataApi from 'browser/main/lib/dataApi'
|
||||
import styles from './FolderList.styl'
|
||||
import store from 'browser/main/store'
|
||||
import { store } from 'browser/main/store'
|
||||
import FolderItem from './FolderItem'
|
||||
import { SortableContainer } from 'react-sortable-hoc'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
@@ -22,7 +22,7 @@ class FolderList extends React.Component {
|
||||
})
|
||||
|
||||
return (
|
||||
<div styleName='folderList'>
|
||||
<div>
|
||||
{folderList.length > 0
|
||||
? folderList
|
||||
: <div styleName='folderList-empty'>{i18n.__('No Folders')}</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ 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 { store } from 'browser/main/store'
|
||||
import _ from 'lodash'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
|
||||
@@ -30,7 +30,8 @@ class HotkeyTab extends React.Component {
|
||||
this.handleSettingError = (err) => {
|
||||
if (
|
||||
this.state.config.hotkey.toggleMain === '' ||
|
||||
this.state.config.hotkey.toggleMode === ''
|
||||
this.state.config.hotkey.toggleMode === '' ||
|
||||
this.state.config.hotkey.toggleDirection === ''
|
||||
) {
|
||||
this.setState({keymapAlert: {
|
||||
type: 'success',
|
||||
@@ -76,13 +77,17 @@ class HotkeyTab extends React.Component {
|
||||
|
||||
handleHotkeyChange (e) {
|
||||
const { config } = this.state
|
||||
config.hotkey = {
|
||||
config.hotkey = Object.assign({}, config.hotkey, {
|
||||
toggleMain: this.refs.toggleMain.value,
|
||||
toggleMode: this.refs.toggleMode.value,
|
||||
toggleDirection: this.refs.toggleDirection.value,
|
||||
deleteNote: this.refs.deleteNote.value,
|
||||
pasteSmartly: this.refs.pasteSmartly.value,
|
||||
toggleMenuBar: this.refs.toggleMenuBar.value
|
||||
}
|
||||
prettifyMarkdown: this.refs.prettifyMarkdown.value,
|
||||
toggleMenuBar: this.refs.toggleMenuBar.value,
|
||||
insertDate: this.refs.insertDate.value,
|
||||
insertDateTime: this.refs.insertDateTime.value
|
||||
})
|
||||
this.setState({
|
||||
config
|
||||
})
|
||||
@@ -151,6 +156,17 @@ class HotkeyTab extends React.Component {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-label'>{i18n.__('Toggle Direction')}</div>
|
||||
<div styleName='group-section-control'>
|
||||
<input styleName='group-section-control-input'
|
||||
onChange={(e) => this.handleHotkeyChange(e)}
|
||||
ref='toggleDirection'
|
||||
value={config.hotkey.toggleDirection}
|
||||
type='text'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-label'>{i18n.__('Delete Note')}</div>
|
||||
<div styleName='group-section-control'>
|
||||
@@ -173,6 +189,38 @@ class HotkeyTab extends React.Component {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-label'>{i18n.__('Prettify Markdown')}</div>
|
||||
<div styleName='group-section-control'>
|
||||
<input styleName='group-section-control-input'
|
||||
onChange={(e) => this.handleHotkeyChange(e)}
|
||||
ref='prettifyMarkdown'
|
||||
value={config.hotkey.prettifyMarkdown}
|
||||
type='text' />
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-label'>{i18n.__('Insert Current Date')}</div>
|
||||
<div styleName='group-section-control'>
|
||||
<input styleName='group-section-control-input'
|
||||
ref='insertDate'
|
||||
value={config.hotkey.insertDate}
|
||||
type='text'
|
||||
disabled='true'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-label'>{i18n.__('Insert Current Date and Time')}</div>
|
||||
<div styleName='group-section-control'>
|
||||
<input styleName='group-section-control-input'
|
||||
ref='insertDateTime'
|
||||
value={config.hotkey.insertDateTime}
|
||||
type='text'
|
||||
disabled='true'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='group-control'>
|
||||
<button styleName='group-control-leftButton'
|
||||
onClick={(e) => this.handleHintToggleButtonClick(e)}
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react'
|
||||
import CSSModules from 'browser/lib/CSSModules'
|
||||
import styles from './InfoTab.styl'
|
||||
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 _ from 'lodash'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
@@ -61,6 +61,15 @@ class InfoTab extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
toggleAutoUpdate () {
|
||||
const newConfig = {
|
||||
autoUpdateEnabled: !this.state.config.autoUpdateEnabled
|
||||
}
|
||||
|
||||
this.setState({ config: newConfig })
|
||||
ConfigManager.set(newConfig)
|
||||
}
|
||||
|
||||
infoMessage () {
|
||||
const { amaMessage } = this.state
|
||||
return amaMessage ? <p styleName='policy-confirm'>{amaMessage}</p> : null
|
||||
@@ -69,8 +78,7 @@ class InfoTab extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<div styleName='root'>
|
||||
|
||||
<div styleName='header--sub'>{i18n.__('Community')}</div>
|
||||
<div styleName='group-header'>{i18n.__('Community')}</div>
|
||||
<div styleName='top'>
|
||||
<ul styleName='list'>
|
||||
<li>
|
||||
@@ -108,7 +116,7 @@ class InfoTab extends React.Component {
|
||||
|
||||
<hr />
|
||||
|
||||
<div styleName='header--sub'>{i18n.__('About')}</div>
|
||||
<div styleName='group-header--sub'>{i18n.__('About')}</div>
|
||||
|
||||
<div styleName='top'>
|
||||
<div styleName='icon-space'>
|
||||
@@ -134,16 +142,18 @@ class InfoTab extends React.Component {
|
||||
>{i18n.__('Development')}</a>{i18n.__(' : Development configurations for Boostnote.')}
|
||||
</li>
|
||||
<li styleName='cc'>
|
||||
{i18n.__('Copyright (C) 2017 - 2019 BoostIO')}
|
||||
{i18n.__('Copyright (C) 2017 - 2020 BoostIO')}
|
||||
</li>
|
||||
<li styleName='cc'>
|
||||
{i18n.__('License: GPL v3')}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div><label><input type='checkbox' onChange={this.toggleAutoUpdate.bind(this)} checked={this.state.config.autoUpdateEnabled} />{i18n.__('Enable Auto Update')}</label></div>
|
||||
|
||||
<hr styleName='separate-line' />
|
||||
|
||||
<div styleName='policy'>{i18n.__('Analytics')}</div>
|
||||
<div styleName='group-header2--sub'>{i18n.__('Analytics')}</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>{i18n.__('You can see how it works on ')}<a href='https://github.com/BoostIO/Boostnote' onClick={(e) => this.handleLinkClick(e)}>GitHub</a>.</div>
|
||||
<br />
|
||||
|
||||
@@ -1,16 +1,4 @@
|
||||
@import('./Tab')
|
||||
|
||||
.root
|
||||
padding 15px
|
||||
white-space pre
|
||||
line-height 1.4
|
||||
color alpha($ui-text-color, 90%)
|
||||
width 100%
|
||||
font-size 14px
|
||||
|
||||
.top
|
||||
text-align left
|
||||
margin-bottom 20px
|
||||
@import('./ConfigTab.styl')
|
||||
|
||||
.icon-space
|
||||
margin 20px 0
|
||||
@@ -45,13 +33,21 @@
|
||||
.separate-line
|
||||
margin 40px 0
|
||||
|
||||
.policy
|
||||
width 100%
|
||||
font-size 20px
|
||||
margin-bottom 10px
|
||||
|
||||
.policy-submit
|
||||
margin-top 10px
|
||||
height 35px
|
||||
border-radius 2px
|
||||
border none
|
||||
background-color alpha(#1EC38B, 90%)
|
||||
padding-left 20px
|
||||
padding-right 20px
|
||||
text-decoration none
|
||||
color white
|
||||
font-weight 600
|
||||
font-size 16px
|
||||
&:hover
|
||||
background-color #1EC38B
|
||||
transition 0.2s
|
||||
|
||||
.policy-confirm
|
||||
margin-top 10px
|
||||
@@ -60,11 +56,16 @@
|
||||
body[data-theme="dark"]
|
||||
.root
|
||||
color alpha($tab--dark-text-color, 80%)
|
||||
.appId
|
||||
color $ui-dark-text-color
|
||||
|
||||
|
||||
apply-theme(theme)
|
||||
body[data-theme={theme}]
|
||||
.root
|
||||
color get-theme-var(theme, 'text-color')
|
||||
.appId
|
||||
color get-theme-var(theme, 'text-color')
|
||||
.list
|
||||
a
|
||||
color get-theme-var(theme, 'active-color')
|
||||
@@ -73,4 +74,4 @@ for theme in 'solarized-dark' 'dracula'
|
||||
apply-theme(theme)
|
||||
|
||||
for theme in $themes
|
||||
apply-theme(theme)
|
||||
apply-theme(theme)
|
||||
|
||||
@@ -4,6 +4,7 @@ import _ from 'lodash'
|
||||
import styles from './SnippetTab.styl'
|
||||
import CSSModules from 'browser/lib/CSSModules'
|
||||
import dataApi from 'browser/main/lib/dataApi'
|
||||
import snippetManager from '../../../lib/SnippetManager'
|
||||
|
||||
const defaultEditorFontFamily = ['Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', 'monospace']
|
||||
const buildCMRulers = (rulers, enableRulers) =>
|
||||
@@ -64,7 +65,9 @@ class SnippetEditor extends React.Component {
|
||||
}
|
||||
|
||||
saveSnippet () {
|
||||
dataApi.updateSnippet(this.snippet).catch((err) => { throw err })
|
||||
dataApi.updateSnippet(this.snippet)
|
||||
.then(snippets => snippetManager.assignSnippets(snippets))
|
||||
.catch((err) => { throw err })
|
||||
}
|
||||
|
||||
render () {
|
||||
|
||||
@@ -91,7 +91,7 @@ class SnippetTab extends React.Component {
|
||||
if (!(editorFontSize > 0 && editorFontSize < 132)) editorIndentSize = 4
|
||||
return (
|
||||
<div styleName='root'>
|
||||
<div styleName='header'>{i18n.__('Snippets')}</div>
|
||||
<div styleName='group-header'>{i18n.__('Snippets')}</div>
|
||||
<SnippetList
|
||||
onSnippetSelect={this.handleSnippetSelect.bind(this)}
|
||||
onSnippetDeleted={this.handleDeleteSnippet.bind(this)}
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
@import('./Tab')
|
||||
@import('./ConfigTab')
|
||||
|
||||
.root
|
||||
padding 15px
|
||||
white-space pre
|
||||
line-height 1.4
|
||||
color alpha($ui-text-color, 90%)
|
||||
width 100%
|
||||
font-size 14px
|
||||
|
||||
.group
|
||||
margin-bottom 45px
|
||||
|
||||
@@ -127,7 +118,7 @@
|
||||
background darken(#f5f5f5, 5)
|
||||
|
||||
.snippet-detail
|
||||
width 70%
|
||||
width 67%
|
||||
height calc(100% - 200px)
|
||||
position absolute
|
||||
left 33%
|
||||
|
||||
@@ -4,7 +4,7 @@ import CSSModules from 'browser/lib/CSSModules'
|
||||
import styles from './StorageItem.styl'
|
||||
import consts from 'browser/lib/consts'
|
||||
import dataApi from 'browser/main/lib/dataApi'
|
||||
import store from 'browser/main/store'
|
||||
import { store } from 'browser/main/store'
|
||||
import FolderList from './FolderList'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
|
||||
|
||||
@@ -101,4 +101,19 @@ body[data-theme="solarized-dark"]
|
||||
.header-control-button
|
||||
border-color $ui-solarized-dark-button-backgroundColor
|
||||
background-color $ui-solarized-dark-button-backgroundColor
|
||||
color $ui-solarized-dark-text-color
|
||||
color $ui-solarized-dark-text-color
|
||||
|
||||
apply-theme(theme)
|
||||
body[data-theme={theme}]
|
||||
.header
|
||||
border-color get-theme-var(theme, 'borderColor')
|
||||
|
||||
.header-control-button
|
||||
colorThemedPrimaryButton(theme)
|
||||
border-color get-theme-var(theme, 'borderColor')
|
||||
|
||||
for theme in 'dracula'
|
||||
apply-theme(theme)
|
||||
|
||||
for theme in $themes
|
||||
apply-theme(theme)
|
||||
@@ -3,8 +3,11 @@ import React from 'react'
|
||||
import CSSModules from 'browser/lib/CSSModules'
|
||||
import styles from './StoragesTab.styl'
|
||||
import dataApi from 'browser/main/lib/dataApi'
|
||||
import attachmentManagement from 'browser/main/lib/dataApi/attachmentManagement'
|
||||
import StorageItem from './StorageItem'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
import { humanFileSize } from 'browser/lib/utils'
|
||||
import fs from 'fs'
|
||||
|
||||
const electron = require('electron')
|
||||
const { shell, remote } = electron
|
||||
@@ -35,8 +38,29 @@ class StoragesTab extends React.Component {
|
||||
name: 'Unnamed',
|
||||
type: 'FILESYSTEM',
|
||||
path: ''
|
||||
}
|
||||
},
|
||||
attachments: []
|
||||
}
|
||||
this.loadAttachmentStorage()
|
||||
}
|
||||
|
||||
loadAttachmentStorage () {
|
||||
const promises = []
|
||||
this.props.data.noteMap.map(note => {
|
||||
const promise = attachmentManagement.getAttachmentsPathAndStatus(
|
||||
note.content,
|
||||
note.storage,
|
||||
note.key
|
||||
)
|
||||
if (promise) promises.push(promise)
|
||||
})
|
||||
|
||||
Promise.all(promises)
|
||||
.then(data => {
|
||||
const result = data.reduce((acc, curr) => acc.concat(curr), [])
|
||||
this.setState({attachments: result})
|
||||
})
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
handleAddStorageButton (e) {
|
||||
@@ -57,8 +81,39 @@ class StoragesTab extends React.Component {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
handleRemoveUnusedAttachments (attachments) {
|
||||
attachmentManagement.removeAttachmentsByPaths(attachments)
|
||||
.then(() => this.loadAttachmentStorage())
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
renderList () {
|
||||
const { data, boundingBox } = this.props
|
||||
const { attachments } = this.state
|
||||
|
||||
const unusedAttachments = attachments.filter(attachment => !attachment.isInUse)
|
||||
const inUseAttachments = attachments.filter(attachment => attachment.isInUse)
|
||||
|
||||
const totalUnusedAttachments = unusedAttachments.length
|
||||
const totalInuseAttachments = inUseAttachments.length
|
||||
const totalAttachments = totalUnusedAttachments + totalInuseAttachments
|
||||
|
||||
const totalUnusedAttachmentsSize = unusedAttachments
|
||||
.reduce((acc, curr) => {
|
||||
const stats = fs.statSync(curr.path)
|
||||
const fileSizeInBytes = stats.size
|
||||
return acc + fileSizeInBytes
|
||||
}, 0)
|
||||
const totalInuseAttachmentsSize = inUseAttachments
|
||||
.reduce((acc, curr) => {
|
||||
const stats = fs.statSync(curr.path)
|
||||
const fileSizeInBytes = stats.size
|
||||
return acc + fileSizeInBytes
|
||||
}, 0)
|
||||
const totalAttachmentsSize = totalUnusedAttachmentsSize + totalInuseAttachmentsSize
|
||||
|
||||
const unusedAttachmentPaths = unusedAttachments
|
||||
.reduce((acc, curr) => acc.concat(curr.path), [])
|
||||
|
||||
if (!boundingBox) { return null }
|
||||
const storageList = data.storageMap.map((storage) => {
|
||||
@@ -82,6 +137,20 @@ class StoragesTab extends React.Component {
|
||||
<i className='fa fa-plus' /> {i18n.__('Add Storage Location')}
|
||||
</button>
|
||||
</div>
|
||||
<div styleName='header'>{i18n.__('Attachment storage')}</div>
|
||||
<p styleName='list-attachment-label'>
|
||||
Unused attachments size: {humanFileSize(totalUnusedAttachmentsSize)} ({totalUnusedAttachments} items)
|
||||
</p>
|
||||
<p styleName='list-attachment-label'>
|
||||
In use attachments size: {humanFileSize(totalInuseAttachmentsSize)} ({totalInuseAttachments} items)
|
||||
</p>
|
||||
<p styleName='list-attachment-label'>
|
||||
Total attachments size: {humanFileSize(totalAttachmentsSize)} ({totalAttachments} items)
|
||||
</p>
|
||||
<button styleName='list-attachement-clear-button'
|
||||
onClick={() => this.handleRemoveUnusedAttachments(unusedAttachmentPaths)}>
|
||||
{i18n.__('Clear unused attachments')}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
@import('./Tab')
|
||||
|
||||
.root
|
||||
padding 15px
|
||||
color $ui-text-color
|
||||
@import('./ConfigTab')
|
||||
|
||||
.list
|
||||
margin-bottom 15px
|
||||
@@ -37,6 +33,17 @@
|
||||
colorDefaultButton()
|
||||
font-size $tab--button-font-size
|
||||
border-radius 2px
|
||||
.list-attachment-label
|
||||
margin-bottom 10px
|
||||
color $ui-text-color
|
||||
.list-attachement-clear-button
|
||||
height 30px
|
||||
border none
|
||||
border-top-right-radius 2px
|
||||
border-bottom-right-radius 2px
|
||||
colorPrimaryButton()
|
||||
vertical-align middle
|
||||
padding 0 20px
|
||||
|
||||
.addStorage
|
||||
margin-bottom 15px
|
||||
@@ -158,6 +165,8 @@ body[data-theme="dark"]
|
||||
.addStorage-body-control-cancelButton
|
||||
colorDarkDefaultButton()
|
||||
border-color $ui-dark-borderColor
|
||||
.list-attachement-clear-button
|
||||
colorDarkPrimaryButton()
|
||||
|
||||
apply-theme(theme)
|
||||
body[data-theme={theme}]
|
||||
@@ -197,9 +206,11 @@ apply-theme(theme)
|
||||
.addStorage-body-control-cancelButton
|
||||
colorDarkDefaultButton()
|
||||
border-color get-theme-var(theme, 'borderColor')
|
||||
.list-attachement-clear-button
|
||||
colorThemedPrimaryButton(theme)
|
||||
|
||||
for theme in 'solarized-dark' 'dracula'
|
||||
apply-theme(theme)
|
||||
|
||||
for theme in $themes
|
||||
apply-theme(theme)
|
||||
apply-theme(theme)
|
||||
|
||||
@@ -3,7 +3,7 @@ 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 { store } from 'browser/main/store'
|
||||
import consts from 'browser/lib/consts'
|
||||
import ReactCodeMirror from 'react-codemirror'
|
||||
import CodeMirror from 'codemirror'
|
||||
@@ -31,7 +31,13 @@ class UiTab extends React.Component {
|
||||
componentDidMount () {
|
||||
CodeMirror.autoLoadMode(this.codeMirrorInstance.getCodeMirror(), 'javascript')
|
||||
CodeMirror.autoLoadMode(this.customCSSCM.getCodeMirror(), 'css')
|
||||
CodeMirror.autoLoadMode(this.customMarkdownLintConfigCM.getCodeMirror(), 'javascript')
|
||||
CodeMirror.autoLoadMode(this.prettierConfigCM.getCodeMirror(), 'javascript')
|
||||
// Set CM editor Sizes
|
||||
this.customCSSCM.getCodeMirror().setSize('400px', '400px')
|
||||
this.prettierConfigCM.getCodeMirror().setSize('400px', '400px')
|
||||
this.customMarkdownLintConfigCM.getCodeMirror().setSize('400px', '200px')
|
||||
|
||||
this.handleSettingDone = () => {
|
||||
this.setState({UiAlert: {
|
||||
type: 'success',
|
||||
@@ -90,6 +96,7 @@ class UiTab extends React.Component {
|
||||
enableRulers: this.refs.enableEditorRulers.value === 'true',
|
||||
rulers: this.refs.editorRulers.value.replace(/[^0-9,]/g, '').split(','),
|
||||
displayLineNumbers: this.refs.editorDisplayLineNumbers.checked,
|
||||
lineWrapping: this.refs.editorLineWrapping.checked,
|
||||
switchPreview: this.refs.editorSwitchPreview.value,
|
||||
keyMap: this.refs.editorKeyMap.value,
|
||||
snippetDefaultLanguage: this.refs.editorSnippetDefaultLanguage.value,
|
||||
@@ -102,7 +109,11 @@ class UiTab extends React.Component {
|
||||
matchingTriples: this.refs.matchingTriples.value,
|
||||
explodingPairs: this.refs.explodingPairs.value,
|
||||
spellcheck: this.refs.spellcheck.checked,
|
||||
enableSmartPaste: this.refs.enableSmartPaste.checked
|
||||
enableSmartPaste: this.refs.enableSmartPaste.checked,
|
||||
enableMarkdownLint: this.refs.enableMarkdownLint.checked,
|
||||
customMarkdownLintConfig: this.customMarkdownLintConfigCM.getCodeMirror().getValue(),
|
||||
prettierConfig: this.prettierConfigCM.getCodeMirror().getValue(),
|
||||
deleteUnusedAttachments: this.refs.deleteUnusedAttachments.checked
|
||||
},
|
||||
preview: {
|
||||
fontSize: this.refs.previewFontSize.value,
|
||||
@@ -120,6 +131,7 @@ class UiTab extends React.Component {
|
||||
breaks: this.refs.previewBreaks.checked,
|
||||
smartArrows: this.refs.previewSmartArrows.checked,
|
||||
sanitize: this.refs.previewSanitize.value,
|
||||
mermaidHTMLLabel: this.refs.previewMermaidHTMLLabel.checked,
|
||||
allowCustomCSS: this.refs.previewAllowCustomCSS.checked,
|
||||
lineThroughCheckbox: this.refs.lineThroughCheckbox.checked,
|
||||
customCSS: this.customCSSCM.getCodeMirror().getValue()
|
||||
@@ -129,8 +141,13 @@ class UiTab extends React.Component {
|
||||
const newCodemirrorTheme = this.refs.editorTheme.value
|
||||
|
||||
if (newCodemirrorTheme !== codemirrorTheme) {
|
||||
checkHighLight.setAttribute('href', `../node_modules/codemirror/theme/${newCodemirrorTheme.split(' ')[0]}.css`)
|
||||
const theme = consts.THEMES.find(theme => theme.name === newCodemirrorTheme)
|
||||
|
||||
if (theme) {
|
||||
checkHighLight.setAttribute('href', theme.path)
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({ config: newConfig, codemirrorTheme: newCodemirrorTheme }, () => {
|
||||
const {ui, editor, preview} = this.props.config
|
||||
this.currentConfig = {ui, editor, preview}
|
||||
@@ -364,7 +381,7 @@ class UiTab extends React.Component {
|
||||
>
|
||||
{
|
||||
themes.map((theme) => {
|
||||
return (<option value={theme} key={theme}>{theme}</option>)
|
||||
return (<option value={theme.name} key={theme.name}>{theme.name}</option>)
|
||||
})
|
||||
}
|
||||
</select>
|
||||
@@ -501,7 +518,7 @@ class UiTab extends React.Component {
|
||||
ref='editorSnippetDefaultLanguage'
|
||||
onChange={(e) => this.handleUIChange(e)}
|
||||
>
|
||||
<option key='Auto Detect' value='Auto Detect'>Auto Detect</option>
|
||||
<option key='Auto Detect' value='Auto Detect'>{i18n.__('Auto Detect')}</option>
|
||||
{
|
||||
_.sortBy(CodeMirror.modeInfo.map(mode => mode.name)).map(name => (<option key={name} value={name}>{name}</option>))
|
||||
}
|
||||
@@ -545,6 +562,17 @@ class UiTab extends React.Component {
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div styleName='group-checkBoxSection'>
|
||||
<label>
|
||||
<input onChange={(e) => this.handleUIChange(e)}
|
||||
checked={this.state.config.editor.lineWrapping}
|
||||
ref='editorLineWrapping'
|
||||
type='checkbox'
|
||||
/>
|
||||
{i18n.__('Wrap line in Snippet Note')}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div styleName='group-checkBoxSection'>
|
||||
<label>
|
||||
<input onChange={(e) => this.handleUIChange(e)}
|
||||
@@ -599,6 +627,16 @@ class UiTab extends React.Component {
|
||||
{i18n.__('Enable spellcheck - Experimental feature!! :)')}
|
||||
</label>
|
||||
</div>
|
||||
<div styleName='group-checkBoxSection'>
|
||||
<label>
|
||||
<input onChange={(e) => this.handleUIChange(e)}
|
||||
checked={this.state.config.editor.deleteUnusedAttachments}
|
||||
ref='deleteUnusedAttachments'
|
||||
type='checkbox'
|
||||
/>
|
||||
{i18n.__('Delete attachments, that are not referenced in the text anymore')}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-label'>
|
||||
@@ -641,6 +679,34 @@ class UiTab extends React.Component {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-label'>
|
||||
{i18n.__('Custom MarkdownLint Rules')}
|
||||
</div>
|
||||
<div styleName='group-section-control'>
|
||||
<input onChange={(e) => this.handleUIChange(e)}
|
||||
checked={this.state.config.editor.enableMarkdownLint}
|
||||
ref='enableMarkdownLint'
|
||||
type='checkbox'
|
||||
/>
|
||||
{i18n.__('Enable MarkdownLint')}
|
||||
<div style={{fontFamily, display: this.state.config.editor.enableMarkdownLint ? 'block' : 'none'}}>
|
||||
<ReactCodeMirror
|
||||
width='400px'
|
||||
height='200px'
|
||||
onChange={e => this.handleUIChange(e)}
|
||||
ref={e => (this.customMarkdownLintConfigCM = e)}
|
||||
value={config.editor.customMarkdownLintConfig}
|
||||
options={{
|
||||
lineNumbers: true,
|
||||
mode: 'application/json',
|
||||
theme: codemirrorTheme,
|
||||
lint: true,
|
||||
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers']
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div styleName='group-header2'>{i18n.__('Preview')}</div>
|
||||
<div styleName='group-section'>
|
||||
@@ -679,7 +745,7 @@ class UiTab extends React.Component {
|
||||
>
|
||||
{
|
||||
themes.map((theme) => {
|
||||
return (<option value={theme} key={theme}>{theme}</option>)
|
||||
return (<option value={theme.name} key={theme.name}>{theme.name}</option>)
|
||||
})
|
||||
}
|
||||
</select>
|
||||
@@ -772,6 +838,16 @@ class UiTab extends React.Component {
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='group-checkBoxSection'>
|
||||
<label>
|
||||
<input onChange={(e) => this.handleUIChange(e)}
|
||||
checked={this.state.config.preview.mermaidHTMLLabel}
|
||||
ref='previewMermaidHTMLLabel'
|
||||
type='checkbox'
|
||||
/>
|
||||
{i18n.__('Enable HTML label in mermaid flowcharts')}
|
||||
</label>
|
||||
</div>
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-label'>
|
||||
{i18n.__('LaTeX Inline Open Delimiter')}
|
||||
@@ -863,7 +939,27 @@ class UiTab extends React.Component {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-label'>
|
||||
{i18n.__('Prettier Config')}
|
||||
</div>
|
||||
<div styleName='group-section-control'>
|
||||
<div style={{fontFamily}}>
|
||||
<ReactCodeMirror
|
||||
width='400px'
|
||||
height='400px'
|
||||
onChange={e => this.handleUIChange(e)}
|
||||
ref={e => (this.prettierConfigCM = e)}
|
||||
value={config.editor.prettierConfig}
|
||||
options={{
|
||||
lineNumbers: true,
|
||||
mode: 'application/json',
|
||||
lint: true,
|
||||
theme: codemirrorTheme
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='group-control'>
|
||||
<button styleName='group-control-rightButton'
|
||||
onClick={(e) => this.handleSaveUIClick(e)}>{i18n.__('Save')}
|
||||
|
||||
@@ -147,7 +147,7 @@ class Preferences extends React.Component {
|
||||
key={tab.target}
|
||||
onClick={(e) => this.handleNavButtonClick(tab.target)(e)}
|
||||
>
|
||||
<span styleName='nav-button-label'>
|
||||
<span>
|
||||
{tab.label}
|
||||
</span>
|
||||
{isUiHotkeyTab ? this.haveToSaveNotif(tab[tab.label].type, tab[tab.label].message) : null}
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from 'react'
|
||||
import CSSModules from 'browser/lib/CSSModules'
|
||||
import styles from './RenameFolderModal.styl'
|
||||
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 i18n from 'browser/lib/i18n'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user