mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
snippet note
This commit is contained in:
@@ -71,7 +71,6 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
el.removeEventListener('click', goExternal)
|
el.removeEventListener('click', goExternal)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
let { value, fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme } = this.props
|
let { value, fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme } = this.props
|
||||||
fontFamily = _.isString(fontFamily) && fontFamily.trim().length > 0
|
fontFamily = _.isString(fontFamily) && fontFamily.trim().length > 0
|
||||||
? [fontFamily].concat(defaultFontFamily)
|
? [fontFamily].concat(defaultFontFamily)
|
||||||
|
|||||||
@@ -1,90 +1,9 @@
|
|||||||
const modes = [
|
const modes = [
|
||||||
// Major
|
|
||||||
{
|
{
|
||||||
name: 'text',
|
name: 'text',
|
||||||
label: 'Plain text',
|
label: 'Plain text',
|
||||||
mode: 'text'
|
mode: 'text'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'markdown',
|
|
||||||
label: 'Markdown',
|
|
||||||
alias: ['md'],
|
|
||||||
mode: 'markdown'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'javascript',
|
|
||||||
label: 'JavaScript',
|
|
||||||
alias: ['js', 'jscript', 'babel', 'es'],
|
|
||||||
mode: 'javascript'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'html',
|
|
||||||
label: 'HTML',
|
|
||||||
alias: [],
|
|
||||||
mode: 'html'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'css',
|
|
||||||
label: 'CSS',
|
|
||||||
alias: ['cascade', 'stylesheet'],
|
|
||||||
mode: 'css'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'php',
|
|
||||||
label: 'PHP',
|
|
||||||
alias: [],
|
|
||||||
mode: 'php'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'python',
|
|
||||||
label: 'Python',
|
|
||||||
alias: ['py'],
|
|
||||||
mode: 'python'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ruby',
|
|
||||||
label: 'Ruby',
|
|
||||||
alias: ['rb'],
|
|
||||||
mode: 'ruby'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'java',
|
|
||||||
label: 'Java',
|
|
||||||
alias: [],
|
|
||||||
mode: 'java'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'c',
|
|
||||||
label: 'C',
|
|
||||||
alias: ['c', 'h', 'clang', 'clang'],
|
|
||||||
mode: 'c_cpp'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'cpp',
|
|
||||||
label: 'C++',
|
|
||||||
alias: ['cc', 'cpp', 'cxx', 'hh', 'c++', 'cplusplus'],
|
|
||||||
mode: 'c_cpp'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'csharp',
|
|
||||||
label: 'C#',
|
|
||||||
alias: ['cs', 'c#'],
|
|
||||||
mode: 'csharp'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'swift',
|
|
||||||
label: 'Swift',
|
|
||||||
alias: [],
|
|
||||||
mode: 'swift'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'golang',
|
|
||||||
label: 'Go',
|
|
||||||
alias: ['go'],
|
|
||||||
mode: 'golang'
|
|
||||||
},
|
|
||||||
|
|
||||||
// Minor
|
|
||||||
{
|
{
|
||||||
name: 'abap',
|
name: 'abap',
|
||||||
label: 'ABAP',
|
label: 'ABAP',
|
||||||
@@ -145,6 +64,12 @@ const modes = [
|
|||||||
alias: ['dos', 'windows', 'bat', 'cmd', 'btm'],
|
alias: ['dos', 'windows', 'bat', 'cmd', 'btm'],
|
||||||
mode: 'batchfile'
|
mode: 'batchfile'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'c',
|
||||||
|
label: 'C',
|
||||||
|
alias: ['c', 'h', 'clang', 'clang'],
|
||||||
|
mode: 'c_cpp'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'cirru',
|
name: 'cirru',
|
||||||
label: 'Cirru',
|
label: 'Cirru',
|
||||||
@@ -175,6 +100,24 @@ const modes = [
|
|||||||
alias: ['cfm', 'cfc'],
|
alias: ['cfm', 'cfc'],
|
||||||
mode: 'coldfusion'
|
mode: 'coldfusion'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'cpp',
|
||||||
|
label: 'C++',
|
||||||
|
alias: ['cc', 'cpp', 'cxx', 'hh', 'c++', 'cplusplus'],
|
||||||
|
mode: 'c_cpp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'csharp',
|
||||||
|
label: 'C#',
|
||||||
|
alias: ['cs', 'c#'],
|
||||||
|
mode: 'csharp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'css',
|
||||||
|
label: 'CSS',
|
||||||
|
alias: ['cascade', 'stylesheet'],
|
||||||
|
mode: 'css'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'curly',
|
name: 'curly',
|
||||||
label: 'Curly',
|
label: 'Curly',
|
||||||
@@ -283,6 +226,12 @@ const modes = [
|
|||||||
alias: ['opengl', 'shading'],
|
alias: ['opengl', 'shading'],
|
||||||
mode: 'glsl'
|
mode: 'glsl'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'golang',
|
||||||
|
label: 'Go',
|
||||||
|
alias: ['go'],
|
||||||
|
mode: 'golang'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'groovy',
|
name: 'groovy',
|
||||||
label: 'Groovy',
|
label: 'Groovy',
|
||||||
@@ -313,6 +262,12 @@ const modes = [
|
|||||||
alias: ['hx', 'hxml'],
|
alias: ['hx', 'hxml'],
|
||||||
mode: 'haxe'
|
mode: 'haxe'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'html',
|
||||||
|
label: 'HTML',
|
||||||
|
alias: [],
|
||||||
|
mode: 'html'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'html_ruby',
|
name: 'html_ruby',
|
||||||
label: 'HTML (Ruby)',
|
label: 'HTML (Ruby)',
|
||||||
@@ -355,6 +310,18 @@ const modes = [
|
|||||||
alias: [],
|
alias: [],
|
||||||
mode: 'jade'
|
mode: 'jade'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'java',
|
||||||
|
label: 'Java',
|
||||||
|
alias: [],
|
||||||
|
mode: 'java'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'javascript',
|
||||||
|
label: 'JavaScript',
|
||||||
|
alias: ['js', 'jscript', 'babel', 'es'],
|
||||||
|
mode: 'javascript'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'json',
|
name: 'json',
|
||||||
label: 'JSON',
|
label: 'JSON',
|
||||||
@@ -451,6 +418,12 @@ const modes = [
|
|||||||
alias: [],
|
alias: [],
|
||||||
mode: 'makefile'
|
mode: 'makefile'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'markdown',
|
||||||
|
label: 'Markdown',
|
||||||
|
alias: ['md'],
|
||||||
|
mode: 'markdown'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'mask',
|
name: 'mask',
|
||||||
label: 'Mask',
|
label: 'Mask',
|
||||||
@@ -529,6 +502,12 @@ const modes = [
|
|||||||
alias: ['postgres'],
|
alias: ['postgres'],
|
||||||
mode: 'pgsql'
|
mode: 'pgsql'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'php',
|
||||||
|
label: 'PHP',
|
||||||
|
alias: [],
|
||||||
|
mode: 'php'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'powershell',
|
name: 'powershell',
|
||||||
label: 'PowerShell',
|
label: 'PowerShell',
|
||||||
@@ -559,6 +538,12 @@ const modes = [
|
|||||||
alias: ['protocol', 'buffers'],
|
alias: ['protocol', 'buffers'],
|
||||||
mode: 'protobuf'
|
mode: 'protobuf'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'python',
|
||||||
|
label: 'Python',
|
||||||
|
alias: ['py'],
|
||||||
|
mode: 'python'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'r',
|
name: 'r',
|
||||||
label: 'R',
|
label: 'R',
|
||||||
@@ -571,6 +556,12 @@ const modes = [
|
|||||||
alias: [],
|
alias: [],
|
||||||
mode: 'rdoc'
|
mode: 'rdoc'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'ruby',
|
||||||
|
label: 'Ruby',
|
||||||
|
alias: ['rb'],
|
||||||
|
mode: 'ruby'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'rust',
|
name: 'rust',
|
||||||
label: 'Rust',
|
label: 'Rust',
|
||||||
@@ -667,6 +658,12 @@ const modes = [
|
|||||||
alias: [],
|
alias: [],
|
||||||
mode: 'svg'
|
mode: 'svg'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'swift',
|
||||||
|
label: 'Swift',
|
||||||
|
alias: [],
|
||||||
|
mode: 'swift'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'swig',
|
name: 'swig',
|
||||||
label: 'SWIG',
|
label: 'SWIG',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from 'react'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './NoteDetail.styl'
|
import styles from './MarkdownNoteDetail.styl'
|
||||||
import MarkdownEditor from 'browser/components/MarkdownEditor'
|
import MarkdownEditor from 'browser/components/MarkdownEditor'
|
||||||
import StarButton from './StarButton'
|
import StarButton from './StarButton'
|
||||||
import TagSelect from './TagSelect'
|
import TagSelect from './TagSelect'
|
||||||
@@ -13,7 +13,7 @@ const { remote } = electron
|
|||||||
const Menu = remote.Menu
|
const Menu = remote.Menu
|
||||||
const MenuItem = remote.MenuItem
|
const MenuItem = remote.MenuItem
|
||||||
|
|
||||||
class NoteDetail extends React.Component {
|
class MarkdownNoteDetail extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ class NoteDetail extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NoteDetail.propTypes = {
|
MarkdownNoteDetail.propTypes = {
|
||||||
dispatch: PropTypes.func,
|
dispatch: PropTypes.func,
|
||||||
repositories: PropTypes.array,
|
repositories: PropTypes.array,
|
||||||
note: PropTypes.shape({
|
note: PropTypes.shape({
|
||||||
@@ -229,4 +229,4 @@ NoteDetail.propTypes = {
|
|||||||
ignorePreviewPointerEvents: PropTypes.bool
|
ignorePreviewPointerEvents: PropTypes.bool
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CSSModules(NoteDetail, styles)
|
export default CSSModules(MarkdownNoteDetail, styles)
|
||||||
@@ -2,7 +2,7 @@ $info-height = 75px
|
|||||||
|
|
||||||
.root
|
.root
|
||||||
absolute top bottom right
|
absolute top bottom right
|
||||||
border-width 1px 0
|
border-width 0 0 1px
|
||||||
border-style solid
|
border-style solid
|
||||||
border-color $ui-borderColor
|
border-color $ui-borderColor
|
||||||
|
|
||||||
410
browser/main/Detail/SnippetNoteDetail.js
Normal file
410
browser/main/Detail/SnippetNoteDetail.js
Normal file
@@ -0,0 +1,410 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './SnippetNoteDetail.styl'
|
||||||
|
import CodeEditor from 'browser/components/CodeEditor'
|
||||||
|
import StarButton from './StarButton'
|
||||||
|
import TagSelect from './TagSelect'
|
||||||
|
import FolderSelect from './FolderSelect'
|
||||||
|
import Commander from 'browser/main/lib/Commander'
|
||||||
|
import dataApi from 'browser/main/lib/dataApi'
|
||||||
|
import modes from 'browser/lib/modes'
|
||||||
|
|
||||||
|
const electron = require('electron')
|
||||||
|
const { remote } = electron
|
||||||
|
const Menu = remote.Menu
|
||||||
|
const MenuItem = remote.MenuItem
|
||||||
|
|
||||||
|
class SnippetNoteDetail extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
snippetIndex: 0,
|
||||||
|
note: Object.assign({
|
||||||
|
description: ''
|
||||||
|
}, props.note, {
|
||||||
|
snippets: props.note.snippets.map((snippet) => Object.assign({}, snippet))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
Commander.bind('note-detail', this)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
Commander.release(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fire (command) {
|
||||||
|
switch (command) {
|
||||||
|
case 'focus':
|
||||||
|
this.refs.description.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
if (nextProps.note.key !== this.props.note.key) {
|
||||||
|
this.setState({
|
||||||
|
snippetIndex: 0,
|
||||||
|
note: Object.assign({
|
||||||
|
description: ''
|
||||||
|
}, nextProps.note, {
|
||||||
|
snippets: nextProps.note.snippets.map((snippet) => Object.assign({}, snippet))
|
||||||
|
})
|
||||||
|
}, () => {
|
||||||
|
let { snippets } = this.state.note
|
||||||
|
snippets.forEach((snippet, index) => {
|
||||||
|
this.refs['code-' + index].reload()
|
||||||
|
})
|
||||||
|
this.refs.tags.reset()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findTitle (value) {
|
||||||
|
let splitted = value.split('\n')
|
||||||
|
let title = null
|
||||||
|
|
||||||
|
for (let i = 0; i < splitted.length; i++) {
|
||||||
|
let trimmedLine = splitted[i].trim()
|
||||||
|
if (trimmedLine.match(/^# .+/)) {
|
||||||
|
title = trimmedLine.substring(1, trimmedLine.length).trim()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (title == null) {
|
||||||
|
for (let i = 0; i < splitted.length; i++) {
|
||||||
|
let trimmedLine = splitted[i].trim()
|
||||||
|
if (trimmedLine.length > 0) {
|
||||||
|
title = trimmedLine
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (title == null) {
|
||||||
|
title = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return title
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChange (e) {
|
||||||
|
let { note } = this.state
|
||||||
|
|
||||||
|
note.tags = this.refs.tags.value
|
||||||
|
note.description = this.refs.description.value
|
||||||
|
note.updatedAt = new Date()
|
||||||
|
note.title = this.findTitle(note.description)
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
note
|
||||||
|
}, () => {
|
||||||
|
this.save()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
save () {
|
||||||
|
let { note, dispatch } = this.props
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: 'UPDATE_NOTE',
|
||||||
|
note: this.state.note
|
||||||
|
})
|
||||||
|
|
||||||
|
dataApi
|
||||||
|
.updateNote(note.storage, note.folder, note.key, this.state.note)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleFolderChange (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
handleStarButtonClick (e) {
|
||||||
|
let { note } = this.state
|
||||||
|
|
||||||
|
note.isStarred = !note.isStarred
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
note
|
||||||
|
}, () => {
|
||||||
|
this.save()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
exportAsFile () {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
handleShareButtonClick (e) {
|
||||||
|
let menu = new Menu()
|
||||||
|
menu.append(new MenuItem({
|
||||||
|
label: 'Export as a File',
|
||||||
|
click: (e) => this.handlePreferencesButtonClick(e)
|
||||||
|
}))
|
||||||
|
menu.append(new MenuItem({
|
||||||
|
label: 'Export to Web',
|
||||||
|
disabled: true,
|
||||||
|
click: (e) => this.handlePreferencesButtonClick(e)
|
||||||
|
}))
|
||||||
|
menu.popup(remote.getCurrentWindow())
|
||||||
|
}
|
||||||
|
|
||||||
|
handleContextButtonClick (e) {
|
||||||
|
let menu = new Menu()
|
||||||
|
menu.append(new MenuItem({
|
||||||
|
label: 'Delete',
|
||||||
|
click: (e) => this.handlePreferencesButtonClick(e)
|
||||||
|
}))
|
||||||
|
menu.popup(remote.getCurrentWindow())
|
||||||
|
}
|
||||||
|
|
||||||
|
handleTabPlusButtonClick (e) {
|
||||||
|
let { note } = this.state
|
||||||
|
|
||||||
|
note.snippets = note.snippets.concat([{
|
||||||
|
name: '',
|
||||||
|
mode: 'text',
|
||||||
|
content: ''
|
||||||
|
}])
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
note
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleTabButtonClick (index) {
|
||||||
|
return (e) => {
|
||||||
|
this.setState({
|
||||||
|
snippetIndex: index
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleTabDeleteButtonClick (index) {
|
||||||
|
return (e) => {
|
||||||
|
if (this.state.note.snippets.length > 1) {
|
||||||
|
let snippets = this.state.note.snippets.slice()
|
||||||
|
snippets.splice(index, 1)
|
||||||
|
this.state.note.snippets = snippets
|
||||||
|
this.setState({
|
||||||
|
note: this.state.note
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNameInputChange (index) {
|
||||||
|
return (e) => {
|
||||||
|
let snippets = this.state.note.snippets.slice()
|
||||||
|
snippets[index].name = e.target.value
|
||||||
|
this.state.note.snippets = snippets
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
note: this.state.note
|
||||||
|
}, () => {
|
||||||
|
this.save()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleModeButtonClick (index) {
|
||||||
|
return (e) => {
|
||||||
|
let menu = new Menu()
|
||||||
|
modes.forEach((mode) => {
|
||||||
|
menu.append(new MenuItem({
|
||||||
|
label: mode.label,
|
||||||
|
click: (e) => this.handleModeOptionClick(index, mode.name)(e)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
menu.popup(remote.getCurrentWindow())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleModeOptionClick (index, name) {
|
||||||
|
return (e) => {
|
||||||
|
let snippets = this.state.note.snippets.slice()
|
||||||
|
snippets[index].mode = name
|
||||||
|
this.state.note.snippets = snippets
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
note: this.state.note
|
||||||
|
}, () => {
|
||||||
|
this.save()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCodeChange (index) {
|
||||||
|
return (e) => {
|
||||||
|
let snippets = this.state.note.snippets.slice()
|
||||||
|
snippets[index].content = this.refs['code-' + index].value
|
||||||
|
this.state.note.snippets = snippets
|
||||||
|
this.setState({
|
||||||
|
note: this.state.note
|
||||||
|
}, () => {
|
||||||
|
this.save()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
let { storages, config } = this.props
|
||||||
|
let { note } = this.state
|
||||||
|
|
||||||
|
let editorFontSize = parseInt(config.editor.fontSize, 10)
|
||||||
|
if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
|
||||||
|
let editorIndentSize = parseInt(config.editor.indentSize, 10)
|
||||||
|
if (!(editorFontSize > 0 && editorFontSize < 132)) editorIndentSize = 4
|
||||||
|
|
||||||
|
let tabList = note.snippets.map((snippet, index) => {
|
||||||
|
let isActive = this.state.snippetIndex === index
|
||||||
|
return <div styleName={isActive
|
||||||
|
? 'tabList-item--active'
|
||||||
|
: 'tabList-item'
|
||||||
|
}
|
||||||
|
key={index}
|
||||||
|
>
|
||||||
|
<button styleName='tabList-item-button'
|
||||||
|
onClick={(e) => this.handleTabButtonClick(index)(e)}
|
||||||
|
>
|
||||||
|
{snippet.name.trim().length > 0
|
||||||
|
? snippet.name
|
||||||
|
: <span styleName='tabList-item-unnamed'>
|
||||||
|
Unnamed
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</button>
|
||||||
|
{note.snippets.length > 1 &&
|
||||||
|
<button styleName='tabList-item-deleteButton'
|
||||||
|
onClick={(e) => this.handleTabDeleteButtonClick(index)(e)}
|
||||||
|
>
|
||||||
|
<i className='fa fa-times'/>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
})
|
||||||
|
let viewList = note.snippets.map((snippet, index) => {
|
||||||
|
let isActive = this.state.snippetIndex === index
|
||||||
|
let mode = snippet.mode === 'text'
|
||||||
|
? null
|
||||||
|
: modes.filter((mode) => mode.name === snippet.mode)[0]
|
||||||
|
|
||||||
|
return <div styleName='tabView'
|
||||||
|
key={index}
|
||||||
|
style={{zIndex: isActive ? 5 : 4}}
|
||||||
|
>
|
||||||
|
<div styleName='tabView-top'>
|
||||||
|
<input styleName='tabView-top-name'
|
||||||
|
placeholder='Filename including extensions...'
|
||||||
|
value={snippet.name}
|
||||||
|
onChange={(e) => this.handleNameInputChange(index)(e)}
|
||||||
|
/>
|
||||||
|
<button styleName='tabView-top-mode'
|
||||||
|
onClick={(e) => this.handleModeButtonClick(index)(e)}
|
||||||
|
>
|
||||||
|
{mode == null
|
||||||
|
? 'Select Syntax...'
|
||||||
|
: mode.label
|
||||||
|
}
|
||||||
|
<i className='fa fa-caret-down'/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<CodeEditor styleName='tabView-content'
|
||||||
|
mode={snippet.mode}
|
||||||
|
value={snippet.content}
|
||||||
|
theme={config.editor.theme}
|
||||||
|
fontFamily={config.editor.fontFamily}
|
||||||
|
fontSize={editorFontSize}
|
||||||
|
indentType={config.editor.indentType}
|
||||||
|
indentSize={editorIndentSize}
|
||||||
|
onChange={(e) => this.handleCodeChange(index)(e)}
|
||||||
|
ref={'code-' + index}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='NoteDetail'
|
||||||
|
style={this.props.style}
|
||||||
|
styleName='root'
|
||||||
|
>
|
||||||
|
<div styleName='info'>
|
||||||
|
<div styleName='info-left'>
|
||||||
|
|
||||||
|
<div styleName='info-left-top'>
|
||||||
|
<FolderSelect styleName='info-left-top-folderSelect'
|
||||||
|
value={this.state.note.storage + '-' + this.state.note.folder}
|
||||||
|
ref='folder'
|
||||||
|
storages={storages}
|
||||||
|
onChange={(e) => this.handleFolderChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div styleName='info-left-bottom'>
|
||||||
|
<TagSelect
|
||||||
|
styleName='info-left-bottom-tagSelect'
|
||||||
|
ref='tags'
|
||||||
|
value={this.state.note.tags}
|
||||||
|
onChange={(e) => this.handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div styleName='info-right'>
|
||||||
|
<StarButton styleName='info-right-button'
|
||||||
|
onClick={(e) => this.handleStarButtonClick(e)}
|
||||||
|
isActive={note.isStarred}
|
||||||
|
/>
|
||||||
|
<button styleName='info-right-button'
|
||||||
|
onClick={(e) => this.handleShareButtonClick(e)}
|
||||||
|
>
|
||||||
|
<i className='fa fa-share-alt fa-fw'/>
|
||||||
|
</button>
|
||||||
|
<button styleName='info-right-button'
|
||||||
|
onClick={(e) => this.handleContextButtonClick(e)}
|
||||||
|
>
|
||||||
|
<i className='fa fa-ellipsis-v'/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div styleName='body'>
|
||||||
|
<div styleName='body-description'>
|
||||||
|
<textarea styleName='body-description-textarea'
|
||||||
|
style={{
|
||||||
|
fontFamily: config.preview.fontFamily,
|
||||||
|
fontSize: parseInt(config.preview.fontSize, 10)
|
||||||
|
}}
|
||||||
|
ref='description'
|
||||||
|
placeholder='Description...'
|
||||||
|
value={this.state.note.description}
|
||||||
|
onChange={(e) => this.handleChange(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div styleName='tabList'>
|
||||||
|
{tabList}
|
||||||
|
<button styleName='tabList-plusButton'
|
||||||
|
onClick={(e) => this.handleTabPlusButtonClick(e)}
|
||||||
|
>
|
||||||
|
<i className='fa fa-plus'/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{viewList}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SnippetNoteDetail.propTypes = {
|
||||||
|
dispatch: PropTypes.func,
|
||||||
|
repositories: PropTypes.array,
|
||||||
|
note: PropTypes.shape({
|
||||||
|
|
||||||
|
}),
|
||||||
|
style: PropTypes.shape({
|
||||||
|
left: PropTypes.number
|
||||||
|
}),
|
||||||
|
ignorePreviewPointerEvents: PropTypes.bool
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(SnippetNoteDetail, styles)
|
||||||
139
browser/main/Detail/SnippetNoteDetail.styl
Normal file
139
browser/main/Detail/SnippetNoteDetail.styl
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
$info-height = 75px
|
||||||
|
|
||||||
|
.root
|
||||||
|
absolute top bottom right
|
||||||
|
border-width 0 0 1px
|
||||||
|
border-style solid
|
||||||
|
border-color $ui-borderColor
|
||||||
|
|
||||||
|
.info
|
||||||
|
absolute top left right
|
||||||
|
height $info-height
|
||||||
|
border-bottom $ui-border
|
||||||
|
background-color $ui-backgroundColor
|
||||||
|
|
||||||
|
.info-left
|
||||||
|
float left
|
||||||
|
padding 0 5px
|
||||||
|
|
||||||
|
.info-left-top
|
||||||
|
height 40px
|
||||||
|
line-height 40px
|
||||||
|
|
||||||
|
.info-left-top-folderSelect
|
||||||
|
display inline-block
|
||||||
|
height 34px
|
||||||
|
width 200px
|
||||||
|
vertical-align middle
|
||||||
|
|
||||||
|
.info-left-bottom
|
||||||
|
height 30px
|
||||||
|
|
||||||
|
.info-left-bottom-tagSelect
|
||||||
|
height 30px
|
||||||
|
line-height 30px
|
||||||
|
|
||||||
|
.info-right
|
||||||
|
float right
|
||||||
|
|
||||||
|
.info-right-button
|
||||||
|
width 34px
|
||||||
|
height 34px
|
||||||
|
border-radius 17px
|
||||||
|
navButtonColor()
|
||||||
|
border $ui-border
|
||||||
|
font-size 14px
|
||||||
|
margin 8px 2px
|
||||||
|
padding 0
|
||||||
|
&:active
|
||||||
|
border-color $ui-button--focus-borderColor
|
||||||
|
&:hover .left-control-newPostButton-tooltip
|
||||||
|
display block
|
||||||
|
&:focus
|
||||||
|
border-color $ui-button--focus-borderColor
|
||||||
|
|
||||||
|
.body
|
||||||
|
absolute bottom left right
|
||||||
|
top $info-height
|
||||||
|
|
||||||
|
.body-description
|
||||||
|
absolute top left right
|
||||||
|
height 80px
|
||||||
|
border-bottom $ui-border
|
||||||
|
|
||||||
|
.body-description-textarea
|
||||||
|
display block
|
||||||
|
height 100%
|
||||||
|
width 100%
|
||||||
|
resize none
|
||||||
|
border none
|
||||||
|
padding 10px
|
||||||
|
|
||||||
|
.tabList
|
||||||
|
absolute left right
|
||||||
|
top 80px
|
||||||
|
height 30px
|
||||||
|
border-bottom $ui-border
|
||||||
|
display flex
|
||||||
|
background-color $ui-backgroundColor
|
||||||
|
.tabList-item
|
||||||
|
position relative
|
||||||
|
flex 1
|
||||||
|
border-right $ui-border
|
||||||
|
&:hover
|
||||||
|
.tabList-item-deleteButton
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
&:hover
|
||||||
|
background-color darken($ui-backgroundColor, 15%)
|
||||||
|
&:active
|
||||||
|
color white
|
||||||
|
background-color $ui-active-color
|
||||||
|
.tabList-item--active
|
||||||
|
@extend .tabList-item
|
||||||
|
.tabList-item-button
|
||||||
|
border-color $brand-color
|
||||||
|
.tabList-item-button
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
navButtonColor()
|
||||||
|
border-left 4px solid transparent
|
||||||
|
.tabList-item-deleteButton
|
||||||
|
position absolute
|
||||||
|
top 5px
|
||||||
|
height 20px
|
||||||
|
right 5px
|
||||||
|
width 20px
|
||||||
|
text-align center
|
||||||
|
border none
|
||||||
|
padding 0
|
||||||
|
color transparent
|
||||||
|
background-color transparent
|
||||||
|
border-radius 2px
|
||||||
|
.tabList-plusButton
|
||||||
|
navButtonColor()
|
||||||
|
width 30px
|
||||||
|
.tabView
|
||||||
|
absolute left right bottom
|
||||||
|
top 110px
|
||||||
|
.tabView-top
|
||||||
|
absolute top left right
|
||||||
|
height 30px
|
||||||
|
border-bottom $ui-border
|
||||||
|
display flex
|
||||||
|
.tabView-top-name
|
||||||
|
flex 1
|
||||||
|
border none
|
||||||
|
padding 0 10px
|
||||||
|
font-size 14px
|
||||||
|
.tabView-top-mode
|
||||||
|
width 110px
|
||||||
|
padding 0
|
||||||
|
border none
|
||||||
|
border-left $ui-border
|
||||||
|
colorDefaultButton()
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
&:hover
|
||||||
|
color $ui-text-color
|
||||||
|
.tabView-content
|
||||||
|
absolute left right bottom
|
||||||
|
top 30px
|
||||||
@@ -2,7 +2,8 @@ import React, { PropTypes } from 'react'
|
|||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './Detail.styl'
|
import styles from './Detail.styl'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import NoteDetail from './NoteDetail'
|
import MarkdownNoteDetail from './MarkdownNoteDetail'
|
||||||
|
import SnippetNoteDetail from './SnippetNoteDetail'
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ class Detail extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
let { storages, location, notes, config } = this.props
|
let { location, notes, config } = this.props
|
||||||
let note = null
|
let note = null
|
||||||
if (location.query.key != null) {
|
if (location.query.key != null) {
|
||||||
let splitted = location.query.key.split('-')
|
let splitted = location.query.key.split('-')
|
||||||
@@ -41,8 +42,23 @@ class Detail extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (note.type === 'SNIPPET_NOTE') {
|
||||||
return (
|
return (
|
||||||
<NoteDetail
|
<SnippetNoteDetail
|
||||||
|
note={note}
|
||||||
|
config={config}
|
||||||
|
{..._.pick(this.props, [
|
||||||
|
'dispatch',
|
||||||
|
'storages',
|
||||||
|
'style',
|
||||||
|
'ignorePreviewPointerEvents'
|
||||||
|
])}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MarkdownNoteDetail
|
||||||
note={note}
|
note={note}
|
||||||
config={config}
|
config={config}
|
||||||
{..._.pick(this.props, [
|
{..._.pick(this.props, [
|
||||||
|
|||||||
@@ -54,9 +54,17 @@
|
|||||||
.item-title
|
.item-title
|
||||||
height 20px
|
height 20px
|
||||||
line-height 20px
|
line-height 20px
|
||||||
padding 0 5px
|
padding 0 5px 0 0
|
||||||
font-weight bold
|
font-weight bold
|
||||||
overflow ellipsis
|
overflow ellipsis
|
||||||
|
color $ui-text-color
|
||||||
|
.item-title-icon
|
||||||
|
font-size 12px
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
padding-right 3px
|
||||||
|
.item-title-empty
|
||||||
|
font-weight normal
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
|
||||||
.item-tagList
|
.item-tagList
|
||||||
height 30px
|
height 30px
|
||||||
|
|||||||
@@ -236,7 +236,16 @@ class NoteList extends React.Component {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div styleName='item-title'>{note.title}</div>
|
<div styleName='item-title'>
|
||||||
|
{note.type === 'SNIPPET_NOTE'
|
||||||
|
? <i styleName='item-title-icon' className='fa fa-fw fa-code'/>
|
||||||
|
: <i styleName='item-title-icon' className='fa fa-fw fa-file-text-o'/>
|
||||||
|
}
|
||||||
|
{note.title.trim().length > 0
|
||||||
|
? note.title
|
||||||
|
: <span styleName='item-title-empty'>Empty</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div styleName='item-tagList'>
|
<div styleName='item-tagList'>
|
||||||
<i styleName='item-tagList-icon'
|
<i styleName='item-tagList-icon'
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class StorageItem extends React.Component {
|
|||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
isOpen: false
|
isOpen: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -322,18 +322,49 @@ function removeFolder (storageKey, folderKey) {
|
|||||||
.then((storage) => storage.toJSON())
|
.then((storage) => storage.toJSON())
|
||||||
}
|
}
|
||||||
|
|
||||||
function createNote (storageKey, folderKey, input) {
|
function createMarkdownNote (storageKey, folderKey, input) {
|
||||||
let key = keygen()
|
let key = keygen()
|
||||||
while (notes.some((note) => note.storage === storageKey && note.folder === folderKey && note.key === key)) {
|
while (notes.some((note) => note.storage === storageKey && note.folder === folderKey && note.key === key)) {
|
||||||
key = keygen()
|
key = keygen()
|
||||||
}
|
}
|
||||||
|
|
||||||
let newNote = new Note(Object.assign({
|
let newNote = new Note(Object.assign({
|
||||||
type: 'MARKDOWN_NOTE',
|
|
||||||
tags: [],
|
tags: [],
|
||||||
title: '',
|
title: '',
|
||||||
content: ''
|
content: ''
|
||||||
}, input, {
|
}, input, {
|
||||||
|
type: 'MARKDOWN_NOTE',
|
||||||
|
storage: storageKey,
|
||||||
|
folder: folderKey,
|
||||||
|
key: key,
|
||||||
|
isStarred: false,
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}))
|
||||||
|
notes.push(newNote)
|
||||||
|
|
||||||
|
return newNote
|
||||||
|
.save()
|
||||||
|
.then(() => newNote.toJSON())
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSnippetNote (storageKey, folderKey, input) {
|
||||||
|
let key = keygen()
|
||||||
|
while (notes.some((note) => note.storage === storageKey && note.folder === folderKey && note.key === key)) {
|
||||||
|
key = keygen()
|
||||||
|
}
|
||||||
|
|
||||||
|
let newNote = new Note(Object.assign({
|
||||||
|
tags: [],
|
||||||
|
title: '',
|
||||||
|
description: '',
|
||||||
|
snippets: [{
|
||||||
|
name: '',
|
||||||
|
mode: 'text',
|
||||||
|
content: ''
|
||||||
|
}]
|
||||||
|
}, input, {
|
||||||
|
type: 'SNIPPET_NOTE',
|
||||||
storage: storageKey,
|
storage: storageKey,
|
||||||
folder: folderKey,
|
folder: folderKey,
|
||||||
key: key,
|
key: key,
|
||||||
@@ -374,7 +405,8 @@ export default {
|
|||||||
createFolder,
|
createFolder,
|
||||||
updateFolder,
|
updateFolder,
|
||||||
removeFolder,
|
removeFolder,
|
||||||
createNote,
|
createMarkdownNote,
|
||||||
|
createSnippetNote,
|
||||||
updateNote,
|
updateNote,
|
||||||
removeNote
|
removeNote
|
||||||
}
|
}
|
||||||
|
|||||||
128
browser/main/modals/NewNoteModal.js
Normal file
128
browser/main/modals/NewNoteModal.js
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './NewNoteModal.styl'
|
||||||
|
import dataApi from 'browser/main/lib/dataApi'
|
||||||
|
import { hashHistory } from 'react-router'
|
||||||
|
|
||||||
|
class NewNoteModal extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
this.refs.markdownButton.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCloseButtonClick (e) {
|
||||||
|
this.props.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMarkdownNoteButtonClick (e) {
|
||||||
|
let { storage, folder, dispatch, location } = this.props
|
||||||
|
dataApi
|
||||||
|
.createMarkdownNote(storage, folder, {
|
||||||
|
title: '',
|
||||||
|
content: ''
|
||||||
|
})
|
||||||
|
.then((note) => {
|
||||||
|
dispatch({
|
||||||
|
type: 'CREATE_NOTE',
|
||||||
|
note: note
|
||||||
|
})
|
||||||
|
hashHistory.push({
|
||||||
|
pathname: location.pathname,
|
||||||
|
query: {key: note.uniqueKey}
|
||||||
|
})
|
||||||
|
this.props.close()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
handleMarkdownNoteButtonKeyDown (e) {
|
||||||
|
if (e.keyCode === 9) {
|
||||||
|
e.preventDefault()
|
||||||
|
this.refs.snippetButton.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSnippetNoteButtonClick (e) {
|
||||||
|
let { storage, folder, dispatch, location } = this.props
|
||||||
|
dataApi
|
||||||
|
.createSnippetNote(storage, folder, {
|
||||||
|
title: '',
|
||||||
|
description: '',
|
||||||
|
snippets: [{
|
||||||
|
name: '',
|
||||||
|
mode: 'text',
|
||||||
|
content: ''
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
.then((note) => {
|
||||||
|
dispatch({
|
||||||
|
type: 'CREATE_NOTE',
|
||||||
|
note: note
|
||||||
|
})
|
||||||
|
hashHistory.push({
|
||||||
|
pathname: location.pathname,
|
||||||
|
query: {key: note.uniqueKey}
|
||||||
|
})
|
||||||
|
this.props.close()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSnippetNoteButtonKeyDown (e) {
|
||||||
|
if (e.keyCode === 9) {
|
||||||
|
e.preventDefault()
|
||||||
|
this.refs.markdownButton.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div styleName='root'>
|
||||||
|
<div styleName='header'>
|
||||||
|
<div styleName='title'>New Note</div>
|
||||||
|
</div>
|
||||||
|
<button styleName='closeButton'
|
||||||
|
onClick={(e) => this.handleCloseButtonClick(e)}
|
||||||
|
>Close</button>
|
||||||
|
|
||||||
|
<div styleName='control'>
|
||||||
|
<button styleName='control-button'
|
||||||
|
onClick={(e) => this.handleMarkdownNoteButtonClick(e)}
|
||||||
|
onKeyDown={(e) => this.handleMarkdownNoteButtonKeyDown(e)}
|
||||||
|
ref='markdownButton'
|
||||||
|
>
|
||||||
|
<i styleName='control-button-icon'
|
||||||
|
className='fa fa-file-text-o'
|
||||||
|
/><br/>
|
||||||
|
<span styleName='control-button-label'>Markdown Note</span><br/>
|
||||||
|
<span styleName='control-button-description'>It is good for any type of documents. Check List, Code block and Latex block are available.</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button styleName='control-button'
|
||||||
|
onClick={(e) => this.handleSnippetNoteButtonClick(e)}
|
||||||
|
onKeyDown={(e) => this.handleSnippetNoteButtonKeyDown(e)}
|
||||||
|
ref='snippetButton'
|
||||||
|
>
|
||||||
|
<i styleName='control-button-icon'
|
||||||
|
className='fa fa-code'
|
||||||
|
/><br/>
|
||||||
|
<span styleName='control-button-label'>Snippet Note</span><br/>
|
||||||
|
<span styleName='control-button-description'>This format is specialized on managing snippets like Gist. Multiple snippets can be grouped as a note.
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div styleName='description'><i className='fa fa-arrows-h'/> Tab to switch format</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NewNoteModal.propTypes = {
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(NewNoteModal, styles)
|
||||||
56
browser/main/modals/NewNoteModal.styl
Normal file
56
browser/main/modals/NewNoteModal.styl
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
.root
|
||||||
|
modal()
|
||||||
|
max-width 540px
|
||||||
|
overflow hidden
|
||||||
|
position relative
|
||||||
|
|
||||||
|
.header
|
||||||
|
height 50px
|
||||||
|
font-size 18px
|
||||||
|
line-height 50px
|
||||||
|
padding 0 15px
|
||||||
|
background-color $ui-backgroundColor
|
||||||
|
border-bottom solid 1px $ui-borderColor
|
||||||
|
color $ui-text-color
|
||||||
|
|
||||||
|
.closeButton
|
||||||
|
position absolute
|
||||||
|
top 10px
|
||||||
|
right 10px
|
||||||
|
height 30px
|
||||||
|
width 0 25px
|
||||||
|
border $ui-border
|
||||||
|
border-radius 2px
|
||||||
|
color $ui-text-color
|
||||||
|
colorDefaultButton()
|
||||||
|
|
||||||
|
.control
|
||||||
|
padding 25px 15px 15px
|
||||||
|
text-align center
|
||||||
|
|
||||||
|
.control-button
|
||||||
|
width 220px
|
||||||
|
height 220px
|
||||||
|
margin 0 15px
|
||||||
|
border $ui-border
|
||||||
|
border-radius 5px
|
||||||
|
color $ui-text-color
|
||||||
|
colorDefaultButton()
|
||||||
|
padding 10px
|
||||||
|
&:focus
|
||||||
|
colorPrimaryButton()
|
||||||
|
|
||||||
|
.control-button-icon
|
||||||
|
font-size 50px
|
||||||
|
margin-bottom 15px
|
||||||
|
|
||||||
|
.control-button-label
|
||||||
|
font-size 18px
|
||||||
|
line-height 32px
|
||||||
|
.control-button-description
|
||||||
|
font-size 12px
|
||||||
|
|
||||||
|
.description
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
text-align center
|
||||||
|
margin-bottom 25px
|
||||||
Reference in New Issue
Block a user