mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 09:46:22 +00:00
cleaned up redundant variables, fixed eslint fix command, split snippetList into component
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
import CodeMirror from 'codemirror'
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import fs from 'fs'
|
||||
import consts from 'browser/lib/consts'
|
||||
import dataApi from 'browser/main/lib/dataApi'
|
||||
|
||||
const defaultEditorFontFamily = ['Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', 'monospace']
|
||||
@@ -71,10 +69,7 @@ export default class SnippetEditor extends React.Component {
|
||||
return (
|
||||
<div styleName='SnippetEditor' ref='root' tabIndex='-1' style={{
|
||||
fontFamily: fontFamily.join(', '),
|
||||
fontSize: fontSize,
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '90%'
|
||||
fontSize: fontSize
|
||||
}} />
|
||||
)
|
||||
}
|
||||
|
||||
87
browser/main/modals/PreferencesModal/SnippetList.js
Normal file
87
browser/main/modals/PreferencesModal/SnippetList.js
Normal file
@@ -0,0 +1,87 @@
|
||||
import React from 'react'
|
||||
import styles from './SnippetTab.styl'
|
||||
import CSSModules from 'browser/lib/CSSModules'
|
||||
import dataApi from 'browser/main/lib/dataApi'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
import eventEmitter from 'browser/main/lib/eventEmitter'
|
||||
const { remote } = require('electron')
|
||||
const { Menu, MenuItem } = remote
|
||||
|
||||
class SnippetList extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
snippets: []
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.reloadSnippetList()
|
||||
eventEmitter.on('snippetList:reload', this.reloadSnippetList.bind(this))
|
||||
}
|
||||
|
||||
reloadSnippetList () {
|
||||
dataApi.fetchSnippet().then(snippets => this.setState({snippets}))
|
||||
}
|
||||
|
||||
handleSnippetContextMenu (snippet) {
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({
|
||||
label: i18n.__('Delete snippet'),
|
||||
click: () => {
|
||||
this.deleteSnippet(snippet)
|
||||
}
|
||||
}))
|
||||
menu.popup()
|
||||
}
|
||||
|
||||
deleteSnippet (snippet) {
|
||||
dataApi.deleteSnippet(snippet).then(() => {
|
||||
this.reloadSnippetList()
|
||||
this.props.onSnippetDeleted(snippet)
|
||||
}).catch(err => { throw err })
|
||||
}
|
||||
|
||||
handleSnippetClick (snippet) {
|
||||
this.props.onSnippetClick(snippet)
|
||||
}
|
||||
|
||||
createSnippet () {
|
||||
dataApi.createSnippet().then(() => {
|
||||
this.reloadSnippetList()
|
||||
// scroll to end of list when added new snippet
|
||||
const snippetList = document.getElementById('snippets')
|
||||
snippetList.scrollTop = snippetList.scrollHeight
|
||||
}).catch(err => { throw err })
|
||||
}
|
||||
|
||||
render () {
|
||||
const { snippets } = this.state
|
||||
return (
|
||||
<div styleName='snippet-list'>
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-control'>
|
||||
<button styleName='group-control-button' onClick={() => this.createSnippet()}>
|
||||
<i className='fa fa-plus' /> {i18n.__('New Snippet')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul id='snippets' styleName='snippets'>
|
||||
{
|
||||
snippets.map((snippet) => (
|
||||
<li
|
||||
styleName='snippet-item'
|
||||
key={snippet.id}
|
||||
onContextMenu={() => this.handleSnippetContextMenu(snippet)}
|
||||
onClick={() => this.handleSnippetClick(snippet)}>
|
||||
{snippet.name}
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default CSSModules(SnippetList, styles)
|
||||
@@ -1,33 +1,33 @@
|
||||
import React from 'react'
|
||||
import CSSModules from 'browser/lib/CSSModules'
|
||||
import styles from './SnippetTab.styl'
|
||||
import fs from 'fs'
|
||||
import SnippetEditor from './SnippetEditor'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
import dataApi from 'browser/main/lib/dataApi'
|
||||
import consts from 'browser/lib/consts'
|
||||
|
||||
const { remote } = require('electron')
|
||||
|
||||
const { Menu, MenuItem } = remote
|
||||
import SnippetList from './SnippetList'
|
||||
import eventEmitter from 'browser/main/lib/eventEmitter'
|
||||
|
||||
class SnippetTab extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
snippets: [],
|
||||
currentSnippet: null
|
||||
}
|
||||
this.changeDelay = null
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.reloadSnippetList()
|
||||
handleSnippetNameOrPrefixChange () {
|
||||
clearTimeout(this.changeDelay)
|
||||
this.changeDelay = setTimeout(() => {
|
||||
// notify the snippet editor that the name or prefix of snippet has been changed
|
||||
this.snippetEditor.onSnippetNameOrPrefixChanged(this.state.currentSnippet)
|
||||
eventEmitter.emit('snippetList:reload')
|
||||
}, 500)
|
||||
}
|
||||
|
||||
handleSnippetClick (snippet) {
|
||||
if (this.state.currentSnippet === null || this.state.currentSnippet.id !== snippet.id) {
|
||||
const { currentSnippet } = this.state
|
||||
if (currentSnippet === null || currentSnippet.id !== snippet.id) {
|
||||
dataApi.fetchSnippet(snippet.id).then(changedSnippet => {
|
||||
// notify the snippet editor to load the content of the new snippet
|
||||
this.snippetEditor.onSnippetChanged(changedSnippet)
|
||||
@@ -36,70 +36,27 @@ class SnippetTab extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleSnippetNameOrPrefixChange () {
|
||||
clearTimeout(this.changeDelay)
|
||||
this.changeDelay = setTimeout(() => {
|
||||
// notify the snippet editor that the name or prefix of snippet has been changed
|
||||
this.snippetEditor.onSnippetNameOrPrefixChanged(this.state.currentSnippet)
|
||||
this.reloadSnippetList()
|
||||
}, 500)
|
||||
onSnippetNameOrPrefixChanged (e, type) {
|
||||
const newSnippet = Object.assign({}, this.state.currentSnippet)
|
||||
if (type === 'name') {
|
||||
newSnippet.name = e.target.value
|
||||
} else {
|
||||
newSnippet.prefix = e.target.value
|
||||
}
|
||||
this.setState({ currentSnippet: newSnippet })
|
||||
this.handleSnippetNameOrPrefixChange()
|
||||
}
|
||||
|
||||
handleSnippetContextMenu (snippet) {
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({
|
||||
label: i18n.__('Delete snippet'),
|
||||
click: () => {
|
||||
this.deleteSnippet(snippet)
|
||||
}
|
||||
}))
|
||||
menu.popup()
|
||||
}
|
||||
|
||||
reloadSnippetList () {
|
||||
dataApi.fetchSnippet().then(snippets => this.setState({snippets}))
|
||||
}
|
||||
|
||||
deleteSnippet (snippet) {
|
||||
dataApi.deleteSnippet(snippet).then(() => {
|
||||
this.reloadSnippetList()
|
||||
// prevent old snippet still display when deleted
|
||||
if (snippet.id === this.state.currentSnippet.id) {
|
||||
this.setState({currentSnippet: null})
|
||||
}
|
||||
}).catch(err => { throw err })
|
||||
}
|
||||
|
||||
createSnippet () {
|
||||
dataApi.createSnippet().then(() => {
|
||||
this.reloadSnippetList()
|
||||
// scroll to end of list when added new snippet
|
||||
const snippetList = document.getElementById('snippets')
|
||||
snippetList.scrollTop = snippetList.scrollHeight
|
||||
}).catch(err => { throw err })
|
||||
}
|
||||
|
||||
renderSnippetList () {
|
||||
const { snippets } = this.state
|
||||
return (
|
||||
<ul id='snippets' style={{height: 'calc(100% - 8px)', overflow: 'scroll', background: '#f5f5f5'}}>
|
||||
{
|
||||
snippets.map((snippet) => (
|
||||
<li
|
||||
styleName='snippet-item'
|
||||
key={snippet.id}
|
||||
onContextMenu={() => this.handleSnippetContextMenu(snippet)}
|
||||
onClick={() => this.handleSnippetClick(snippet)}>
|
||||
{snippet.name}
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
)
|
||||
handleDeleteSnippet (snippet) {
|
||||
// prevent old snippet still display when deleted
|
||||
if (snippet.id === this.state.currentSnippet.id) {
|
||||
this.setState({currentSnippet: null})
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { config } = this.props
|
||||
const { config, storageKey } = this.props
|
||||
const { currentSnippet } = this.state
|
||||
|
||||
let editorFontSize = parseInt(config.editor.fontSize, 10)
|
||||
if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
|
||||
@@ -108,29 +65,17 @@ class SnippetTab extends React.Component {
|
||||
return (
|
||||
<div styleName='root'>
|
||||
<div styleName='header'>{i18n.__('Snippets')}</div>
|
||||
<div styleName='snippet-list'>
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-control'>
|
||||
<button styleName='group-control-button' onClick={() => this.createSnippet()}>
|
||||
<i className='fa fa-plus' /> {i18n.__('New Snippet')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{this.renderSnippetList()}
|
||||
</div>
|
||||
<div styleName='snippet-detail' style={{visibility: this.state.currentSnippet ? 'visible' : 'hidden'}}>
|
||||
<SnippetList
|
||||
onSnippetClick={this.handleSnippetClick.bind(this)}
|
||||
onSnippetDeleted={this.handleDeleteSnippet.bind(this)} />
|
||||
<div styleName='snippet-detail' style={{visibility: currentSnippet ? 'visible' : 'hidden'}}>
|
||||
<div styleName='group-section'>
|
||||
<div styleName='group-section-label'>{i18n.__('Snippet name')}</div>
|
||||
<div styleName='group-section-control'>
|
||||
<input
|
||||
styleName='group-section-control-input'
|
||||
value={this.state.currentSnippet ? this.state.currentSnippet.name : ''}
|
||||
onChange={e => {
|
||||
const newSnippet = Object.assign({}, this.state.currentSnippet)
|
||||
newSnippet.name = e.target.value
|
||||
this.setState({ currentSnippet: newSnippet })
|
||||
this.handleSnippetNameOrPrefixChange()
|
||||
}}
|
||||
value={currentSnippet ? currentSnippet.name : ''}
|
||||
onChange={e => { this.onSnippetNameOrPrefixChanged(e, 'name') }}
|
||||
type='text' />
|
||||
</div>
|
||||
</div>
|
||||
@@ -139,19 +84,14 @@ class SnippetTab extends React.Component {
|
||||
<div styleName='group-section-control'>
|
||||
<input
|
||||
styleName='group-section-control-input'
|
||||
value={this.state.currentSnippet ? this.state.currentSnippet.prefix : ''}
|
||||
onChange={e => {
|
||||
const newSnippet = Object.assign({}, this.state.currentSnippet)
|
||||
newSnippet.prefix = e.target.value
|
||||
this.setState({ currentSnippet: newSnippet })
|
||||
this.handleSnippetNameOrPrefixChange()
|
||||
}}
|
||||
value={currentSnippet ? currentSnippet.prefix : ''}
|
||||
onChange={e => { this.onSnippetNameOrPrefixChanged(e, 'prefix') }}
|
||||
type='text' />
|
||||
</div>
|
||||
</div>
|
||||
<div styleName='snippet-editor-section'>
|
||||
<SnippetEditor
|
||||
storageKey={this.props.storageKey}
|
||||
storageKey={storageKey}
|
||||
theme={config.editor.theme}
|
||||
keyMap={config.editor.keyMap}
|
||||
fontFamily={config.editor.fontFamily}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@import('./Tab')
|
||||
@import('./ConfigTab')
|
||||
|
||||
.root
|
||||
padding 15px
|
||||
@@ -96,6 +97,11 @@
|
||||
height calc(100% - 200px)
|
||||
position absolute
|
||||
|
||||
.snippets
|
||||
height calc(100% - 8px)
|
||||
overflow scroll
|
||||
background: #f5f5f5
|
||||
|
||||
.snippet-item
|
||||
height 50px
|
||||
font-size 15px
|
||||
@@ -121,3 +127,20 @@
|
||||
height calc(100% - 200px)
|
||||
position absolute
|
||||
left 33%
|
||||
|
||||
.SnippetEditor
|
||||
position absolute
|
||||
width 100%
|
||||
height 90%
|
||||
|
||||
body[data-theme="dark"]
|
||||
.snippets
|
||||
background: #2E3235
|
||||
.snippet-item
|
||||
color white
|
||||
&::after
|
||||
background rgba(255, 255, 255 0.1)
|
||||
&:hover
|
||||
background darken(#2E3235, 5)
|
||||
.snippet-detail
|
||||
color white
|
||||
Reference in New Issue
Block a user