mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 01:36:22 +00:00
resizible list
This commit is contained in:
@@ -1,339 +0,0 @@
|
|||||||
import React, { PropTypes } from 'react'
|
|
||||||
import ReactDOM from 'react-dom'
|
|
||||||
import moment from 'moment'
|
|
||||||
import _ from 'lodash'
|
|
||||||
import TagSelect from 'browser/components/TagSelect'
|
|
||||||
import ModeSelect from 'browser/components/ModeSelect'
|
|
||||||
import ShareButton from './ShareButton'
|
|
||||||
import { openModal, isModalOpen } from 'browser/main/lib/modal'
|
|
||||||
import DeleteArticleModal from '../modals/DeleteArticleModal'
|
|
||||||
import ArticleEditor from './ArticleEditor'
|
|
||||||
const electron = require('electron')
|
|
||||||
const ipc = electron.ipcRenderer
|
|
||||||
import fetchConfig from 'browser/lib/fetchConfig'
|
|
||||||
|
|
||||||
let config = fetchConfig()
|
|
||||||
ipc.on('config-apply', function (e, newConfig) {
|
|
||||||
config = newConfig
|
|
||||||
})
|
|
||||||
|
|
||||||
const BRAND_COLOR = '#18AF90'
|
|
||||||
const OSX = global.process.platform === 'darwin'
|
|
||||||
|
|
||||||
const tagSelectTutorialElement = (
|
|
||||||
<svg width='500' height='500' className='tutorial'>
|
|
||||||
<text x='155' y='50' fill={BRAND_COLOR} fontSize='24'>Attach some tags here!</text>
|
|
||||||
|
|
||||||
<svg x='0' y='-15'>
|
|
||||||
<path fill='white' d='M15.5,22.2c77.8-0.7,155.6-1.3,233.5-2c22.2-0.2,44.4-0.4,66.6-0.6c1.9,0,1.9-3,0-3
|
|
||||||
c-77.8,0.7-155.6,1.3-233.5,2c-22.2,0.2-44.4,0.4-66.6,0.6C13.6,19.2,13.6,22.2,15.5,22.2L15.5,22.2z'/>
|
|
||||||
<path fill='white' d='M130.8,25c-5.4,6.8-10.3,14-14.6,21.5c-0.8,1.4,1.2,3.2,2.4,1.8c1-1.2,2-2.4,3.1-3.7c1.2-1.5-0.9-3.6-2.1-2.1
|
|
||||||
c-1,1.2-2,2.4-3.1,3.7c0.8,0.6,1.6,1.2,2.4,1.8c4.2-7.3,8.9-14.3,14.2-20.9C134.1,25.6,132,23.4,130.8,25L130.8,25z'/>
|
|
||||||
<path fill='white' d='M132.6,22.1c8.4,5.9,16.8,11.9,25.2,17.8c1.6,1.1,3.1-1.5,1.5-2.6c-8.4-5.9-16.8-11.9-25.2-17.8
|
|
||||||
C132.5,18.4,131,21,132.6,22.1L132.6,22.1z'/>
|
|
||||||
<path fill='white' d='M132.9,18.6c0.4,6.7-0.7,13.3-3.5,19.3c-1.5,3.1-3.9,6.4-3.1,10c0.7,3.1,3.4,4.4,6.2,5.5
|
|
||||||
c5.1,2.1,10.5,3.1,16.1,3.2c1.9,0,1.9-3,0-3c-4.7-0.1-9.2-0.8-13.6-2.4c-3-1.1-6.2-1.9-5.4-6.6c0.4-2,2-4.1,2.8-5.9
|
|
||||||
c2.9-6.3,4-13.1,3.6-20.1C135.8,16.7,132.8,16.7,132.9,18.6L132.9,18.6z'/>
|
|
||||||
</svg>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const modeSelectTutorialElement = (
|
|
||||||
<svg width='500' height='500' className='tutorial'>
|
|
||||||
<text x='195' y='130' fill={BRAND_COLOR} fontSize='24'>Select code syntax!!</text>
|
|
||||||
|
|
||||||
<svg x='300' y='0'>
|
|
||||||
<path fill='white' d='M99.9,58.8c-14.5-0.5-29-2.2-43.1-5.6c-12.3-2.9-27.9-6.4-37.1-15.5C7.9,26,28.2,18.9,37,16.7
|
|
||||||
c13.8-3.5,28.3-4.7,42.4-5.8c29.6-2.2,59.3-1.7,89-1c3,0.1,7.5-0.6,10.2,0.6c3.1,1.4,3.1,5.3,3.3,8.1c0.3,5.2-0.2,10.7-2.4,15.4
|
|
||||||
c-4.4,9.6-18.4,14.7-27.5,18.1c-27.1,10.1-56.7,12.8-85.3,15.6c-1.9,0.2-1.9,3.2,0,3c29.3-2.9,59.8-5.6,87.5-16.2
|
|
||||||
c9.6-3.7,22.8-8.7,27.7-18.4c2.3-4.6,3.2-9.9,3.2-15c0-3.6,0-9.4-2.9-12c-1.9-1.7-4.7-1.8-7.1-2c-4.8-0.2-9.6-0.2-14.4-0.3
|
|
||||||
c-8.7-0.2-17.5-0.3-26.2-0.4C116.7,6.3,99,6.5,81.3,7.8c-15.8,1.1-32.1,2.3-47.4,6.6c-7.7,2.2-22.1,6.9-20.9,17.4
|
|
||||||
c0.6,5.4,5.6,9.4,9.9,12.1c6.7,4.3,14.4,6.9,22,9.2c17.8,5.4,36.4,8,54.9,8.6C101.8,61.8,101.8,58.8,99.9,58.8L99.9,58.8z'/>
|
|
||||||
<path fill='white' d='M11.1,67.8c9.2-6.1,18.6-11.9,28.2-17.2c-0.7-0.3-1.5-0.6-2.2-0.9c0.9,5.3,0.7,10.3-0.5,15.5
|
|
||||||
c-0.4,1.9,2.4,2.7,2.9,0.8c1.4-5.7,1.5-11.3,0.5-17.1c-0.2-1-1.4-1.3-2.2-0.9c-9.7,5.3-19.1,11.1-28.2,17.2
|
|
||||||
C8,66.3,9.5,68.9,11.1,67.8L11.1,67.8z'/>
|
|
||||||
<path fill='white' d='M31.5,52.8C23.4,68.9,0.2,83.2,7.9,104c0.7,1.8,3.6,1,2.9-0.8C3.6,83.7,26.4,69.7,34.1,54.3
|
|
||||||
C35,52.6,32.4,51.1,31.5,52.8L31.5,52.8z'/>
|
|
||||||
</svg>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default class ArticleDetail extends React.Component {
|
|
||||||
constructor (props) {
|
|
||||||
super(props)
|
|
||||||
|
|
||||||
this.deleteHandler = (e) => {
|
|
||||||
if (isModalOpen()) return true
|
|
||||||
this.handleDeleteButtonClick()
|
|
||||||
}
|
|
||||||
this.uncacheHandler = (e) => {
|
|
||||||
if (isModalOpen()) return true
|
|
||||||
this.handleUncache()
|
|
||||||
}
|
|
||||||
this.titleHandler = (e) => {
|
|
||||||
if (isModalOpen()) return true
|
|
||||||
if (this.refs.title) {
|
|
||||||
this.focusTitle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.editHandler = (e) => {
|
|
||||||
if (isModalOpen()) return true
|
|
||||||
if (this.refs.editor) this.refs.editor.switchEditMode()
|
|
||||||
}
|
|
||||||
this.previewHandler = (e) => {
|
|
||||||
if (isModalOpen()) return true
|
|
||||||
if (this.refs.editor) this.refs.editor.switchPreviewMode()
|
|
||||||
}
|
|
||||||
this.configApplyHandler = (e, config) => this.handleConfigApply(e, config)
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
article: Object.assign({content: ''}, props.activeArticle),
|
|
||||||
openShareDropdown: false,
|
|
||||||
fontFamily: config['editor-font-family']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount () {
|
|
||||||
this.refreshTimer = setInterval(() => this.forceUpdate(), 60 * 1000)
|
|
||||||
this.shareDropdownInterceptor = (e) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
}
|
|
||||||
|
|
||||||
ipc.on('detail-delete', this.deleteHandler)
|
|
||||||
ipc.on('detail-uncache', this.uncacheHandler)
|
|
||||||
ipc.on('detail-title', this.titleHandler)
|
|
||||||
ipc.on('detail-edit', this.editHandler)
|
|
||||||
ipc.on('detail-preview', this.previewHandler)
|
|
||||||
ipc.on('config-apply', this.configApplyHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount () {
|
|
||||||
clearInterval(this.refreshTimer)
|
|
||||||
|
|
||||||
ipc.removeListener('detail-delete', this.deleteHandler)
|
|
||||||
ipc.removeListener('detail-uncache', this.uncacheHandler)
|
|
||||||
ipc.removeListener('detail-title', this.titleHandler)
|
|
||||||
ipc.removeListener('detail-edit', this.editHandler)
|
|
||||||
ipc.removeListener('detail-preview', this.previewHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate (prevProps, prevState) {
|
|
||||||
if (this.props.activeArticle == null || prevProps.activeArticle == null || this.props.activeArticle.key !== prevProps.activeArticle.key) {
|
|
||||||
if (this.refs.editor) this.refs.editor.resetCursorPosition()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prevProps.activeArticle == null && this.props.activeArticle) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleConfigApply (e, config) {
|
|
||||||
this.setState({
|
|
||||||
fontFamily: config['editor-font-family']
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
renderEmpty () {
|
|
||||||
return (
|
|
||||||
<div className='ArticleDetail empty'>
|
|
||||||
<div className='ArticleDetail-empty-box'>
|
|
||||||
<div className='ArticleDetail-empty-box-message'>{OSX ? 'Command(⌘)' : 'Ctrl(^)'} + N<br/>to create a new post</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleOthersButtonClick (e) {
|
|
||||||
this.deleteHandler()
|
|
||||||
}
|
|
||||||
|
|
||||||
handleFolderKeyChange (e) {
|
|
||||||
let { dispatch, activeArticle, status, folders } = this.props
|
|
||||||
let article = Object.assign({}, activeArticle, {
|
|
||||||
FolderKey: e.target.value,
|
|
||||||
updatedAt: new Date()
|
|
||||||
})
|
|
||||||
|
|
||||||
// dispatch(updateArticle(article))
|
|
||||||
|
|
||||||
let targetFolderKey = e.target.value
|
|
||||||
if (status.targetFolders.length > 0) {
|
|
||||||
let targetFolder = _.findWhere(folders, {key: targetFolderKey})
|
|
||||||
// dispatch(switchFolder(targetFolder.name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleTitleChange (e) {
|
|
||||||
let { dispatch, activeArticle } = this.props
|
|
||||||
let article = Object.assign({}, activeArticle, {
|
|
||||||
title: e.target.value,
|
|
||||||
updatedAt: new Date()
|
|
||||||
})
|
|
||||||
// dispatch(updateArticle(article))
|
|
||||||
}
|
|
||||||
|
|
||||||
handleTagsChange (newTag, tags) {
|
|
||||||
let { dispatch, activeArticle } = this.props
|
|
||||||
let article = Object.assign({}, activeArticle, {
|
|
||||||
tags: tags,
|
|
||||||
updatedAt: new Date()
|
|
||||||
})
|
|
||||||
|
|
||||||
// dispatch(updateArticle(article))
|
|
||||||
}
|
|
||||||
|
|
||||||
handleModeChange (value) {
|
|
||||||
let { dispatch, activeArticle } = this.props
|
|
||||||
let article = Object.assign({}, activeArticle, {
|
|
||||||
mode: value,
|
|
||||||
updatedAt: new Date()
|
|
||||||
})
|
|
||||||
|
|
||||||
// dispatch(updateArticle(article))
|
|
||||||
this.switchEditMode()
|
|
||||||
}
|
|
||||||
|
|
||||||
handleContentChange (value) {
|
|
||||||
let { dispatch, activeArticle } = this.props
|
|
||||||
if (activeArticle.content !== value) {
|
|
||||||
let article = Object.assign({}, activeArticle, {
|
|
||||||
content: value,
|
|
||||||
updatedAt: new Date()
|
|
||||||
})
|
|
||||||
|
|
||||||
// dispatch(updateArticle(article))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDeleteButtonClick (e) {
|
|
||||||
if (this.props.activeArticle) {
|
|
||||||
openModal(DeleteArticleModal, {articleKey: this.props.activeArticle.key})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleTitleKeyDown (e) {
|
|
||||||
if (e.keyCode === 9 && !e.shiftKey) {
|
|
||||||
e.preventDefault()
|
|
||||||
this.refs.mode.handleIdleSelectClick()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleModeSelectKeyDown (e) {
|
|
||||||
if (e.keyCode === 9 && !e.shiftKey) {
|
|
||||||
e.preventDefault()
|
|
||||||
this.switchEditMode()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.keyCode === 9 && e.shiftKey) {
|
|
||||||
e.preventDefault()
|
|
||||||
this.focusTitle()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.keyCode === 27) {
|
|
||||||
this.focusTitle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switchEditMode () {
|
|
||||||
this.refs.editor.switchEditMode()
|
|
||||||
}
|
|
||||||
|
|
||||||
focusTitle () {
|
|
||||||
if (this.refs.title) {
|
|
||||||
let titleEl = ReactDOM.findDOMNode(this.refs.title)
|
|
||||||
titleEl.focus()
|
|
||||||
titleEl.select()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
let { folders, status, tags, activeArticle, modified, user } = this.props
|
|
||||||
if (activeArticle == null) return this.renderEmpty()
|
|
||||||
let folderOptions = folders.map((folder) => {
|
|
||||||
return (
|
|
||||||
<option key={folder.key} value={folder.key}>{folder.name}</option>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
let isUnsaved = !!_.findWhere(modified, {key: activeArticle.key})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div tabIndex='4' className='ArticleDetail'>
|
|
||||||
<div className='ArticleDetail-info'>
|
|
||||||
<div className='ArticleDetail-info-row'>
|
|
||||||
<select
|
|
||||||
className='ArticleDetail-info-folder'
|
|
||||||
value={activeArticle.FolderKey}
|
|
||||||
onChange={(e) => this.handleFolderKeyChange(e)}
|
|
||||||
>
|
|
||||||
{folderOptions}
|
|
||||||
</select>
|
|
||||||
<span className='ArticleDetail-info-status'
|
|
||||||
children={
|
|
||||||
isUnsaved
|
|
||||||
? <span> <span className='unsaved-mark'>●</span> Unsaved</span>
|
|
||||||
: `Created : ${moment(activeArticle.createdAt).format('YYYY/MM/DD')} Updated : ${moment(activeArticle.updatedAt).format('YYYY/MM/DD')}`
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className='ArticleDetail-info-control'>
|
|
||||||
<ShareButton
|
|
||||||
article={activeArticle}
|
|
||||||
user={user}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<button className='ArticleDetail-info-control-delete-button' onClick={(e) => this.handleOthersButtonClick(e)}>
|
|
||||||
<i className='fa fa-fw fa-trash'/>
|
|
||||||
<span className='tooltip'>Delete Post (^ + Del)</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='ArticleDetail-info-row2'>
|
|
||||||
<TagSelect
|
|
||||||
tags={activeArticle.tags}
|
|
||||||
onChange={(tags, tag) => this.handleTagsChange(tags, tag)}
|
|
||||||
suggestTags={tags}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{status.isTutorialOpen ? tagSelectTutorialElement : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='ArticleDetail-panel'>
|
|
||||||
<div className='ArticleDetail-panel-header'>
|
|
||||||
<div className='ArticleDetail-panel-header-title'>
|
|
||||||
<input
|
|
||||||
onKeyDown={(e) => this.handleTitleKeyDown(e)}
|
|
||||||
placeholder='(Untitled)'
|
|
||||||
ref='title'
|
|
||||||
value={activeArticle.title}
|
|
||||||
onChange={(e) => this.handleTitleChange(e)}
|
|
||||||
style={{
|
|
||||||
fontFamily: this.state.fontFamily
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<ModeSelect
|
|
||||||
ref='mode'
|
|
||||||
onChange={(e) => this.handleModeChange(e)}
|
|
||||||
onKeyDown={(e) => this.handleModeSelectKeyDown(e)}
|
|
||||||
value={activeArticle.mode}
|
|
||||||
className='ArticleDetail-panel-header-mode'
|
|
||||||
/>
|
|
||||||
{status.isTutorialOpen ? modeSelectTutorialElement : null}
|
|
||||||
</div>
|
|
||||||
<ArticleEditor
|
|
||||||
ref='editor'
|
|
||||||
article={activeArticle}
|
|
||||||
onChange={(content) => this.handleContentChange(content)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ArticleDetail.propTypes = {
|
|
||||||
dispatch: PropTypes.func,
|
|
||||||
repositories: PropTypes.array
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,27 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from 'react'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './Main.styl'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import SideNav from './SideNav'
|
import SideNav from './SideNav'
|
||||||
import TopBar from './TopBar'
|
import TopBar from './TopBar'
|
||||||
import ArticleList from './ArticleList'
|
import NoteList from './NoteList'
|
||||||
import ArticleDetail from './ArticleDetail'
|
import NoteDetail from './NoteDetail'
|
||||||
import Repository from 'browser/lib/Repository'
|
import Repository from 'browser/lib/Repository'
|
||||||
import StatusBar from './StatusBar'
|
import StatusBar from './StatusBar'
|
||||||
|
import _ from 'lodash'
|
||||||
|
import ConfigManager from 'browser/main/lib/ConfigManager'
|
||||||
|
|
||||||
class Main extends React.Component {
|
class Main extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
let { config } = props
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
isSliderFocused: false,
|
||||||
|
listWidth: config.listWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
let { dispatch } = this.props
|
let { dispatch } = this.props
|
||||||
|
|
||||||
@@ -18,25 +32,74 @@ class Main extends React.Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleSlideMouseDown (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
this.setState({
|
||||||
|
isSliderFocused: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMouseUp (e) {
|
||||||
|
if (this.state.isSliderFocused) {
|
||||||
|
this.setState({
|
||||||
|
isSliderFocused: false
|
||||||
|
}, () => {
|
||||||
|
let { dispatch } = this.props
|
||||||
|
let newListWidth = this.state.listWidth
|
||||||
|
// TODO: ConfigManager should dispatch itself.
|
||||||
|
ConfigManager.set({listWidth: newListWidth})
|
||||||
|
dispatch({
|
||||||
|
type: 'SET_LIST_WIDTH',
|
||||||
|
listWidth: newListWidth
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMouseMove (e) {
|
||||||
|
if (this.state.isSliderFocused) {
|
||||||
|
let offset = this.refs.body.getBoundingClientRect().left
|
||||||
|
let newListWidth = e.pageX - offset
|
||||||
|
if (newListWidth < 10) {
|
||||||
|
newListWidth = 10
|
||||||
|
} else if (newListWidth > 600) {
|
||||||
|
newListWidth = 600
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
listWidth: newListWidth
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
let { config } = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='Main'
|
className='Main'
|
||||||
|
styleName='root'
|
||||||
|
onMouseMove={(e) => this.handleMouseMove(e)}
|
||||||
|
onMouseUp={(e) => this.handleMouseUp(e)}
|
||||||
>
|
>
|
||||||
<SideNav
|
<SideNav
|
||||||
{...this.props}
|
{..._.pick(this.props, ['dispatch', 'repositories', 'config', 'location'])}
|
||||||
/>
|
|
||||||
<TopBar
|
|
||||||
{...this.props}
|
|
||||||
/>
|
|
||||||
<ArticleList
|
|
||||||
{...this.props}
|
|
||||||
/>
|
|
||||||
<ArticleDetail
|
|
||||||
{...this.props}
|
|
||||||
/>
|
/>
|
||||||
|
<TopBar/>
|
||||||
|
<div styleName={config.isSideNavFolded ? 'body--expanded' : 'body'}
|
||||||
|
ref='body'
|
||||||
|
>
|
||||||
|
<NoteList style={{width: this.state.listWidth}}/>
|
||||||
|
<div styleName={this.state.isSliderFocused ? 'slider--active' : 'slider'}
|
||||||
|
style={{left: this.state.listWidth}}
|
||||||
|
onMouseDown={(e) => this.handleSlideMouseDown(e)}
|
||||||
|
draggable='false'
|
||||||
|
/>
|
||||||
|
<NoteDetail
|
||||||
|
style={{left: this.state.listWidth + 5}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<StatusBar
|
<StatusBar
|
||||||
{...this.props}
|
{..._.pick(this.props, ['config', 'location', 'dispatch'])}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -48,4 +111,4 @@ Main.propTypes = {
|
|||||||
repositories: PropTypes.array
|
repositories: PropTypes.array
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect((x) => x)(Main)
|
export default connect((x) => x)(CSSModules(Main, styles))
|
||||||
|
|||||||
25
browser/main/Main.styl
Normal file
25
browser/main/Main.styl
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
.root
|
||||||
|
absolute top left bottom right
|
||||||
|
|
||||||
|
.body
|
||||||
|
absolute right
|
||||||
|
bottom $statusBar-height - 1
|
||||||
|
top $topBar-height - 1
|
||||||
|
left $sideNav-width
|
||||||
|
|
||||||
|
.body--expanded
|
||||||
|
@extend .body
|
||||||
|
left $sideNav--folded-width
|
||||||
|
|
||||||
|
.slider
|
||||||
|
absolute top bottom
|
||||||
|
width 5px
|
||||||
|
background-color $ui-backgroundColor
|
||||||
|
border-width 0 1px 0
|
||||||
|
border-style solid
|
||||||
|
border-color $ui-borderColor
|
||||||
|
cursor ew-resize
|
||||||
|
|
||||||
|
.slider--active
|
||||||
|
@extend .slider
|
||||||
|
background-color $ui-button--active-backgroundColor
|
||||||
17
browser/main/NoteDetail/NoteDetail.styl
Normal file
17
browser/main/NoteDetail/NoteDetail.styl
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
.root
|
||||||
|
absolute top bottom right
|
||||||
|
border-width 1px 0
|
||||||
|
border-style solid
|
||||||
|
border-color $ui-borderColor
|
||||||
|
|
||||||
|
.empty
|
||||||
|
height 320px
|
||||||
|
display flex
|
||||||
|
align-items center
|
||||||
|
.empty-message
|
||||||
|
width 100%
|
||||||
|
font-size 42px
|
||||||
|
line-height 72px
|
||||||
|
text-align center
|
||||||
|
color $ui-inactive-text-color
|
||||||
|
|
||||||
45
browser/main/NoteDetail/index.js
Normal file
45
browser/main/NoteDetail/index.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './NoteDetail.styl'
|
||||||
|
const electron = require('electron')
|
||||||
|
|
||||||
|
const OSX = global.process.platform === 'darwin'
|
||||||
|
|
||||||
|
class NoteDetail extends React.Component {
|
||||||
|
componentDidUpdate (prevProps, prevState) {
|
||||||
|
}
|
||||||
|
|
||||||
|
renderEmpty () {
|
||||||
|
return (
|
||||||
|
<div styleName='empty'>
|
||||||
|
<div styleName='empty-message'>{OSX ? 'Command(⌘)' : 'Ctrl(^)'} + N<br/>to create a new post</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
let isEmpty = true
|
||||||
|
let view = isEmpty
|
||||||
|
? this.renderEmpty()
|
||||||
|
: null
|
||||||
|
return (
|
||||||
|
<div className='NoteDetail'
|
||||||
|
style={this.props.style}
|
||||||
|
styleName='root'
|
||||||
|
tabIndex='0'
|
||||||
|
>
|
||||||
|
{view}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NoteDetail.propTypes = {
|
||||||
|
dispatch: PropTypes.func,
|
||||||
|
repositories: PropTypes.array,
|
||||||
|
style: PropTypes.shape({
|
||||||
|
left: PropTypes.number
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(NoteDetail, styles)
|
||||||
4
browser/main/NoteList/NoteList.styl
Normal file
4
browser/main/NoteList/NoteList.styl
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.root
|
||||||
|
absolute top left bottom
|
||||||
|
border-top $ui-border
|
||||||
|
border-bottom $ui-border
|
||||||
150
browser/main/NoteList/index.js
Normal file
150
browser/main/NoteList/index.js
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './NoteList.styl'
|
||||||
|
import ReactDOM from 'react-dom'
|
||||||
|
import ModeIcon from 'browser/components/ModeIcon'
|
||||||
|
import moment from 'moment'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
const electron = require('electron')
|
||||||
|
const remote = electron.remote
|
||||||
|
const ipc = electron.ipcRenderer
|
||||||
|
|
||||||
|
class NoteList extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
// this.focusHandler = (e) => this.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
// this.refreshTimer = setInterval(() => this.forceUpdate(), 60 * 1000)
|
||||||
|
// ipc.on('list-focus', this.focusHandler)
|
||||||
|
// this.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
// clearInterval(this.refreshTimer)
|
||||||
|
// ipc.removeListener('list-focus', this.focusHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate () {
|
||||||
|
// return false
|
||||||
|
// var index = articles.indexOf(null)
|
||||||
|
// var el = ReactDOM.findDOMNode(this)
|
||||||
|
// var li = el.querySelectorAll('.NoteList>div')[index]
|
||||||
|
|
||||||
|
// if (li == null) {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var overflowBelow = el.clientHeight + el.scrollTop < li.offsetTop + li.clientHeight
|
||||||
|
// if (overflowBelow) {
|
||||||
|
// el.scrollTop = li.offsetTop + li.clientHeight - el.clientHeight
|
||||||
|
// }
|
||||||
|
// var overflowAbove = el.scrollTop > li.offsetTop
|
||||||
|
// if (overflowAbove) {
|
||||||
|
// el.scrollTop = li.offsetTop
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
focus () {
|
||||||
|
// ReactDOM.findDOMNode(this).focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移動ができなかったらfalseを返す:
|
||||||
|
selectPriorArticle () {
|
||||||
|
let { articles, activeArticle, dispatch } = this.props
|
||||||
|
let targetIndex = articles.indexOf(activeArticle) - 1
|
||||||
|
let targetArticle = articles[targetIndex]
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
selectNextArticle () {
|
||||||
|
let { articles, activeArticle, dispatch } = this.props
|
||||||
|
let targetIndex = articles.indexOf(activeArticle) + 1
|
||||||
|
let targetArticle = articles[targetIndex]
|
||||||
|
|
||||||
|
if (targetArticle != null) {
|
||||||
|
dispatch(switchArticle(targetArticle.key))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
handleArticleClick (article) {
|
||||||
|
let { dispatch } = this.props
|
||||||
|
return function (e) {
|
||||||
|
dispatch(switchArticle(article.key))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNoteListKeyDown (e) {
|
||||||
|
if (e.metaKey || e.ctrlKey) return true
|
||||||
|
|
||||||
|
if (e.keyCode === 65 && !e.shiftKey) {
|
||||||
|
e.preventDefault()
|
||||||
|
remote.getCurrentWebContents().send('top-new-post')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.keyCode === 65 && e.shiftKey) {
|
||||||
|
e.preventDefault()
|
||||||
|
remote.getCurrentWebContents().send('nav-new-folder')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.keyCode === 68) {
|
||||||
|
e.preventDefault()
|
||||||
|
remote.getCurrentWebContents().send('detail-delete')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.keyCode === 84) {
|
||||||
|
e.preventDefault()
|
||||||
|
remote.getCurrentWebContents().send('detail-title')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.keyCode === 69) {
|
||||||
|
e.preventDefault()
|
||||||
|
remote.getCurrentWebContents().send('detail-edit')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.keyCode === 83) {
|
||||||
|
e.preventDefault()
|
||||||
|
remote.getCurrentWebContents().send('detail-save')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.keyCode === 38) {
|
||||||
|
e.preventDefault()
|
||||||
|
this.selectPriorArticle()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.keyCode === 40) {
|
||||||
|
e.preventDefault()
|
||||||
|
this.selectNextArticle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
let articleElements = []
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='NoteList'
|
||||||
|
styleName='root'
|
||||||
|
tabIndex='0'
|
||||||
|
onKeyDown={(e) => this.handleNoteListKeyDown(e)}
|
||||||
|
style={this.props.style}
|
||||||
|
>
|
||||||
|
{articleElements}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NoteList.propTypes = {
|
||||||
|
dispatch: PropTypes.func,
|
||||||
|
repositories: PropTypes.array,
|
||||||
|
style: PropTypes.shape({
|
||||||
|
width: PropTypes.number
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(NoteList, styles)
|
||||||
@@ -86,6 +86,7 @@
|
|||||||
margin-left 0
|
margin-left 0
|
||||||
overflow ellipsis
|
overflow ellipsis
|
||||||
background-color $ui-tooltip-backgroundColor
|
background-color $ui-tooltip-backgroundColor
|
||||||
|
z-index 10
|
||||||
color white
|
color white
|
||||||
line-height 34px
|
line-height 34px
|
||||||
border-top-right-radius 5px
|
border-top-right-radius 5px
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class RepositorySection extends React.Component {
|
|||||||
onContextMenu={(e) => this.handleContextButtonClick(e)}
|
onContextMenu={(e) => this.handleContextButtonClick(e)}
|
||||||
>
|
>
|
||||||
<div styleName='header-name'>
|
<div styleName='header-name'>
|
||||||
<i styleName='header-name-icon' className='fa fa-archive fa-fw'/>
|
<i className='fa fa-archive fa-fw'/>
|
||||||
<span styleName='header-name-label'>{repository.name}</span>
|
<span styleName='header-name-label'>{repository.name}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,12 @@
|
|||||||
text-align left
|
text-align left
|
||||||
font-size 14px
|
font-size 14px
|
||||||
color $ui-inactive-text-color
|
color $ui-inactive-text-color
|
||||||
|
&:hover
|
||||||
|
background-color $ui-button--hover-backgroundColor
|
||||||
&:hover .header-control-button
|
&:hover .header-control-button
|
||||||
opacity 1
|
opacity 1
|
||||||
&:active
|
&:active
|
||||||
background-color $ui-button--active-backgroundColor !important
|
background-color $ui-button--active-backgroundColor
|
||||||
color $ui-button--active-color
|
color $ui-button--active-color
|
||||||
.header-control-button, .header-control-button--show
|
.header-control-button, .header-control-button--show
|
||||||
color white
|
color white
|
||||||
@@ -22,6 +24,8 @@
|
|||||||
@extend .header
|
@extend .header
|
||||||
background-color $ui-button--active-backgroundColor
|
background-color $ui-button--active-backgroundColor
|
||||||
color $ui-button--active-color
|
color $ui-button--active-color
|
||||||
|
&:hover
|
||||||
|
background-color $ui-button--active-backgroundColor
|
||||||
.header-control-button,
|
.header-control-button,
|
||||||
.header-control-button--show
|
.header-control-button--show
|
||||||
color white
|
color white
|
||||||
@@ -124,6 +128,7 @@
|
|||||||
margin-left 0
|
margin-left 0
|
||||||
overflow ellipsis
|
overflow ellipsis
|
||||||
background-color $ui-tooltip-backgroundColor
|
background-color $ui-tooltip-backgroundColor
|
||||||
|
z-index 10
|
||||||
color white
|
color white
|
||||||
line-height 34px
|
line-height 34px
|
||||||
border-top-right-radius 5px
|
border-top-right-radius 5px
|
||||||
@@ -136,6 +141,7 @@
|
|||||||
height 33px
|
height 33px
|
||||||
top inherit
|
top inherit
|
||||||
bottom inherit
|
bottom inherit
|
||||||
|
z-index 11
|
||||||
left 43px
|
left 43px
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
overflow hidden
|
overflow hidden
|
||||||
@@ -164,6 +170,7 @@
|
|||||||
margin-left 0
|
margin-left 0
|
||||||
overflow ellipsis
|
overflow ellipsis
|
||||||
background-color $ui-tooltip-backgroundColor
|
background-color $ui-tooltip-backgroundColor
|
||||||
|
z-index 10
|
||||||
color white
|
color white
|
||||||
line-height 34px
|
line-height 34px
|
||||||
border-top-right-radius 5px
|
border-top-right-radius 5px
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
.root
|
.root
|
||||||
absolute top left
|
absolute top left
|
||||||
bottom $statusBar-height
|
bottom $statusBar-height - 1
|
||||||
width $sideNav-width
|
width $sideNav-width
|
||||||
border-right $ui-border
|
border-right $ui-border
|
||||||
|
border-bottom $ui-border
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-backgroundColor
|
||||||
user-select none
|
user-select none
|
||||||
color $ui-text-color
|
color $ui-text-color
|
||||||
@@ -88,6 +89,7 @@
|
|||||||
margin-left 0
|
margin-left 0
|
||||||
overflow hidden
|
overflow hidden
|
||||||
background-color $ui-tooltip-backgroundColor
|
background-color $ui-tooltip-backgroundColor
|
||||||
|
z-index 10
|
||||||
color white
|
color white
|
||||||
line-height 34px
|
line-height 34px
|
||||||
border-top-right-radius 5px
|
border-top-right-radius 5px
|
||||||
@@ -99,6 +101,7 @@
|
|||||||
text-align center
|
text-align center
|
||||||
&:hover .menu-button-label
|
&:hover .menu-button-label
|
||||||
width 100px
|
width 100px
|
||||||
|
// TODO: extract tooltip style to a mixin
|
||||||
.menu-button-label
|
.menu-button-label
|
||||||
position fixed
|
position fixed
|
||||||
display inline-block
|
display inline-block
|
||||||
@@ -110,6 +113,7 @@
|
|||||||
margin-left 0
|
margin-left 0
|
||||||
overflow ellipsis
|
overflow ellipsis
|
||||||
background-color $ui-tooltip-backgroundColor
|
background-color $ui-tooltip-backgroundColor
|
||||||
|
z-index 10
|
||||||
color white
|
color white
|
||||||
line-height 34px
|
line-height 34px
|
||||||
border-top-right-radius 5px
|
border-top-right-radius 5px
|
||||||
|
|||||||
@@ -74,8 +74,7 @@ class SideNav extends React.Component {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className='SideNav'
|
||||||
className='SideNav'
|
|
||||||
styleName={isFolded ? 'root-folded' : 'root'}
|
styleName={isFolded ? 'root-folded' : 'root'}
|
||||||
tabIndex='1'
|
tabIndex='1'
|
||||||
>
|
>
|
||||||
@@ -83,7 +82,7 @@ class SideNav extends React.Component {
|
|||||||
<button styleName='top-menu'
|
<button styleName='top-menu'
|
||||||
onClick={(e) => this.handleMenuButtonClick(e)}
|
onClick={(e) => this.handleMenuButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i styleName='top-menu-icon' className='fa fa-navicon fa-fw'/>
|
<i className='fa fa-navicon fa-fw'/>
|
||||||
<span styleName='top-menu-label'>Menu</span>
|
<span styleName='top-menu-label'>Menu</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -92,17 +91,13 @@ class SideNav extends React.Component {
|
|||||||
<button styleName={isHomeActive ? 'menu-button--active' : 'menu-button'}
|
<button styleName={isHomeActive ? 'menu-button--active' : 'menu-button'}
|
||||||
onClick={(e) => this.handleHomeButtonClick(e)}
|
onClick={(e) => this.handleHomeButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i styleName='menu-button-icon'
|
<i className='fa fa-home fa-fw'/>
|
||||||
className='fa fa-home fa-fw'
|
|
||||||
/>
|
|
||||||
<span styleName='menu-button-label'>Home</span>
|
<span styleName='menu-button-label'>Home</span>
|
||||||
</button>
|
</button>
|
||||||
<button styleName={isStarredActive ? 'menu-button--active' : 'menu-button'}
|
<button styleName={isStarredActive ? 'menu-button--active' : 'menu-button'}
|
||||||
onClick={(e) => this.handleStarredButtonClick(e)}
|
onClick={(e) => this.handleStarredButtonClick(e)}
|
||||||
>
|
>
|
||||||
<i styleName='menu-button-icon'
|
<i className='fa fa-star fa-fw'/>
|
||||||
className='fa fa-star fa-fw'
|
|
||||||
/>
|
|
||||||
<span styleName='menu-button-label'>Starred</span>
|
<span styleName='menu-button-label'>Starred</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -132,7 +127,13 @@ SideNav.contextTypes = {
|
|||||||
|
|
||||||
SideNav.propTypes = {
|
SideNav.propTypes = {
|
||||||
dispatch: PropTypes.func,
|
dispatch: PropTypes.func,
|
||||||
repositories: PropTypes.array
|
repositories: PropTypes.array,
|
||||||
|
config: PropTypes.shape({
|
||||||
|
isSideNavFolded: PropTypes.bool
|
||||||
|
}),
|
||||||
|
location: PropTypes.shape({
|
||||||
|
pathname: PropTypes.string
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CSSModules(SideNav, styles)
|
export default CSSModules(SideNav, styles)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
.root
|
.root
|
||||||
absolute bottom left right
|
absolute bottom left right
|
||||||
height $statusBar-height
|
height $statusBar-height - 1
|
||||||
border-top $ui-border
|
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-backgroundColor
|
||||||
|
|
||||||
.pathname
|
.pathname
|
||||||
|
|||||||
@@ -2,14 +2,13 @@
|
|||||||
absolute top right
|
absolute top right
|
||||||
background-color $ui-backgroundColor
|
background-color $ui-backgroundColor
|
||||||
left $sideNav-width
|
left $sideNav-width
|
||||||
border-bottom $ui-border
|
height $topBar-height -1
|
||||||
height 60px
|
|
||||||
clearfix()
|
clearfix()
|
||||||
|
|
||||||
.left
|
.left
|
||||||
float left
|
float left
|
||||||
height 59px
|
height $topBar-height - 1
|
||||||
line-height 60px
|
line-height $topBar-height
|
||||||
|
|
||||||
.left-search
|
.left-search
|
||||||
margin-top 12px
|
margin-top 12px
|
||||||
@@ -60,11 +59,12 @@
|
|||||||
|
|
||||||
.left-control-newPostButton-tooltip
|
.left-control-newPostButton-tooltip
|
||||||
position fixed
|
position fixed
|
||||||
|
line-height 1.4
|
||||||
background-color $ui-tooltip-backgroundColor
|
background-color $ui-tooltip-backgroundColor
|
||||||
color $ui-tooltip-text-color
|
color $ui-tooltip-text-color
|
||||||
font-size 10px
|
font-size 10px
|
||||||
margin-left -35px
|
margin-left -35px
|
||||||
margin-top 12px
|
margin-top 5px
|
||||||
padding 5px
|
padding 5px
|
||||||
z-index 1
|
z-index 1
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
|
|
||||||
.right
|
.right
|
||||||
float right
|
float right
|
||||||
height 60px
|
height $topBar-height -1
|
||||||
clearfix()
|
clearfix()
|
||||||
|
|
||||||
.right-helpButton
|
.right-helpButton
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import styles from './TopBar.styl'
|
import styles from './TopBar.styl'
|
||||||
import activityRecord from 'browser/lib/activityRecord'
|
import activityRecord from 'browser/lib/activityRecord'
|
||||||
@@ -80,7 +81,7 @@ class TopBar extends React.Component {
|
|||||||
onClick={(e) => this.handleNewPostButtonClick(e)}>
|
onClick={(e) => this.handleNewPostButtonClick(e)}>
|
||||||
<i className='fa fa-plus'/>
|
<i className='fa fa-plus'/>
|
||||||
<span styleName='left-control-newPostButton-tooltip'>
|
<span styleName='left-control-newPostButton-tooltip'>
|
||||||
New Post ({OSX ? '⌘' : '^'} + n)
|
New Post {OSX ? '⌘' : '^'} + n
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -111,4 +112,4 @@ TopBar.propTypes = {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CSSModules(TopBar, styles)
|
export default connect((x) => x)(CSSModules(TopBar, styles))
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ import _ from 'lodash'
|
|||||||
|
|
||||||
const defaultConfig = {
|
const defaultConfig = {
|
||||||
zoom: 1,
|
zoom: 1,
|
||||||
isSideNavFolded: false
|
isSideNavFolded: false,
|
||||||
|
listWidth: 250
|
||||||
}
|
}
|
||||||
|
|
||||||
function _validate (config) {
|
function validate (config) {
|
||||||
|
console.log(config)
|
||||||
if (!_.isObject(config)) return false
|
if (!_.isObject(config)) return false
|
||||||
if (!_.isNumber(config.zoom) || config.zoom < 0) return false
|
if (!_.isNumber(config.zoom) || config.zoom < 0) return false
|
||||||
if (!_.isBoolean(config.isSideNavFolded)) return false
|
if (!_.isBoolean(config.isSideNavFolded)) return false
|
||||||
|
if (!_.isNumber(config.listWidth) || config.listWidth <= 0) return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -22,7 +25,7 @@ function get () {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
config = JSON.parse(config)
|
config = JSON.parse(config)
|
||||||
if (!_validate(config)) throw new Error('INVALID CONFIG')
|
if (!validate(config)) throw new Error('INVALID CONFIG')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Boostnote resets the malformed configuration.')
|
console.warn('Boostnote resets the malformed configuration.')
|
||||||
config = defaultConfig
|
config = defaultConfig
|
||||||
@@ -35,11 +38,12 @@ function get () {
|
|||||||
function set (updates) {
|
function set (updates) {
|
||||||
let currentConfig = get()
|
let currentConfig = get()
|
||||||
let newConfig = Object.assign({}, defaultConfig, currentConfig, updates)
|
let newConfig = Object.assign({}, defaultConfig, currentConfig, updates)
|
||||||
if (!_validate(newConfig)) throw new Error('INVALID CONFIG')
|
if (!validate(newConfig)) throw new Error('INVALID CONFIG')
|
||||||
_save(newConfig)
|
_save(newConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
get,
|
get,
|
||||||
set
|
set,
|
||||||
|
validate
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import ConfigManager from 'browser/main/lib/ConfigManager'
|
|||||||
const initialRepositories = []
|
const initialRepositories = []
|
||||||
|
|
||||||
function repositories (state = initialRepositories, action) {
|
function repositories (state = initialRepositories, action) {
|
||||||
console.log(action)
|
console.info('REDUX >> ', action)
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'INIT_ALL':
|
case 'INIT_ALL':
|
||||||
return action.data.slice()
|
return action.data.slice()
|
||||||
@@ -121,6 +121,11 @@ function config (state = defaultConfig, action) {
|
|||||||
case 'SET_ZOOM':
|
case 'SET_ZOOM':
|
||||||
state.zoom = action.zoom
|
state.zoom = action.zoom
|
||||||
return Object.assign({}, state)
|
return Object.assign({}, state)
|
||||||
|
case 'SET_LIST_WIDTH':
|
||||||
|
state.listWidth = action.listWidth
|
||||||
|
return Object.assign({}, state)
|
||||||
|
case 'SET_CONFIG':
|
||||||
|
return Object.assign({}, state, action.config)
|
||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ $danger-lighten-color = #FFE5E6
|
|||||||
$statusBar-height = 24px
|
$statusBar-height = 24px
|
||||||
$sideNav-width = 200px
|
$sideNav-width = 200px
|
||||||
$sideNav--folded-width = 44px
|
$sideNav--folded-width = 44px
|
||||||
|
$topBar-height = 60px
|
||||||
|
|
||||||
// UI default
|
// UI default
|
||||||
$ui-text-color = #515151
|
$ui-text-color = #515151
|
||||||
|
|||||||
@@ -1,393 +0,0 @@
|
|||||||
noTagsColor = #999
|
|
||||||
|
|
||||||
infoButton()
|
|
||||||
display inline-block
|
|
||||||
border-radius 16.5px
|
|
||||||
cursor pointer
|
|
||||||
height 33px
|
|
||||||
width 33px
|
|
||||||
line-height 33px
|
|
||||||
margin-right 5px
|
|
||||||
font-size 18px
|
|
||||||
color inactiveTextColor
|
|
||||||
background-color white
|
|
||||||
padding 0
|
|
||||||
border 1px solid white
|
|
||||||
&:focus
|
|
||||||
border-color focusBorderColor
|
|
||||||
&:hover
|
|
||||||
color inherit
|
|
||||||
|
|
||||||
.ArticleDetail
|
|
||||||
absolute right bottom
|
|
||||||
top 60px
|
|
||||||
left 450px
|
|
||||||
padding 10px
|
|
||||||
background-color #E6E6E6
|
|
||||||
border-top 1px solid borderColor
|
|
||||||
&.empty
|
|
||||||
.ArticleDetail-empty-box
|
|
||||||
line-height 72px
|
|
||||||
font-size 42px
|
|
||||||
height 320px
|
|
||||||
display flex
|
|
||||||
align-items center
|
|
||||||
.ArticleDetail-empty-box-message
|
|
||||||
text-align center
|
|
||||||
width 100%
|
|
||||||
color inactiveTextColor
|
|
||||||
.ArticleDetail-info
|
|
||||||
height 70px
|
|
||||||
width 100%
|
|
||||||
font-size 12px
|
|
||||||
user-select none
|
|
||||||
&>.tutorial
|
|
||||||
position fixed
|
|
||||||
z-index 35
|
|
||||||
.ArticleDetail-info-folder
|
|
||||||
display inline-block
|
|
||||||
max-width 100px
|
|
||||||
overflow ellipsis
|
|
||||||
height 10px
|
|
||||||
width 150px
|
|
||||||
height 27px
|
|
||||||
outline none
|
|
||||||
background-color darken(white, 5%)
|
|
||||||
border 1px solid transparent
|
|
||||||
&:hover
|
|
||||||
background-color white
|
|
||||||
&:focus
|
|
||||||
border-color focusBorderColor
|
|
||||||
&>.tutorial
|
|
||||||
position fixed
|
|
||||||
z-index 35
|
|
||||||
.ArticleDetail-info-status
|
|
||||||
padding 0 5px
|
|
||||||
.unsaved-mark
|
|
||||||
color brandColor
|
|
||||||
.ArticleDetail-info-control
|
|
||||||
float right
|
|
||||||
clearfix
|
|
||||||
.ShareButton
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
&>button, .ShareButton-open-button
|
|
||||||
infoButton()
|
|
||||||
.tooltip
|
|
||||||
tooltip()
|
|
||||||
margin-top 30px
|
|
||||||
&:hover
|
|
||||||
.tooltip
|
|
||||||
opacity 1
|
|
||||||
&>button
|
|
||||||
float left
|
|
||||||
&:nth-child(1) .tooltip
|
|
||||||
margin-left -65px
|
|
||||||
.ArticleDetail-info-control-delete-button
|
|
||||||
.tooltip
|
|
||||||
right 5px
|
|
||||||
.ArticleDetail-info-control-save
|
|
||||||
float left
|
|
||||||
width 80px
|
|
||||||
margin-right 5px
|
|
||||||
overflow hidden
|
|
||||||
transition width 0.15s ease-in-out
|
|
||||||
border-radius 16.5px
|
|
||||||
&.hide
|
|
||||||
width 0px
|
|
||||||
opacity 0.2
|
|
||||||
.ArticleDetail-info-control-save-button
|
|
||||||
infoButton()
|
|
||||||
background-color brandColor
|
|
||||||
color white
|
|
||||||
font-size 12px
|
|
||||||
width 100%
|
|
||||||
border 1px solid brandBorderColor
|
|
||||||
white-space nowrap
|
|
||||||
.fa
|
|
||||||
font-size 18px
|
|
||||||
&:hover
|
|
||||||
color white
|
|
||||||
background-color lighten(brandColor, 15%)
|
|
||||||
&:focus
|
|
||||||
color white
|
|
||||||
background-color lighten(brandColor, 15%)
|
|
||||||
.tooltip
|
|
||||||
tooltip()
|
|
||||||
margin-top 30px
|
|
||||||
margin-left -90px
|
|
||||||
&:hover .tooltip
|
|
||||||
opacity 1
|
|
||||||
|
|
||||||
.ShareButton-open-button .tooltip
|
|
||||||
margin-left -40px
|
|
||||||
.ShareButton-dropdown
|
|
||||||
position fixed
|
|
||||||
width 185px
|
|
||||||
z-index 35
|
|
||||||
background-color #F0F0F0
|
|
||||||
padding 4px 0
|
|
||||||
border-radius 5px
|
|
||||||
right 5px
|
|
||||||
top 95px
|
|
||||||
box-shadow 0px 0px 10px 1px alpha(#bbb, 0.8)
|
|
||||||
border 1px solid #bcbcbc
|
|
||||||
&.hide
|
|
||||||
display none
|
|
||||||
&>button
|
|
||||||
background-color transparent
|
|
||||||
height 21px
|
|
||||||
width 100%
|
|
||||||
border none
|
|
||||||
padding-left 20px
|
|
||||||
text-align left
|
|
||||||
font-size 13px
|
|
||||||
font-family '.HelveticaNeueDeskInterface-Regular', sans-serif
|
|
||||||
&:hover
|
|
||||||
background-color #4297FE
|
|
||||||
color white
|
|
||||||
.ShareButton-url
|
|
||||||
height 40px
|
|
||||||
width 100%
|
|
||||||
position relative
|
|
||||||
padding 0 5px
|
|
||||||
.ShareButton-url-input
|
|
||||||
height 21px
|
|
||||||
border none
|
|
||||||
width 143px
|
|
||||||
float left
|
|
||||||
border-top-left-radius 3px
|
|
||||||
border-bottom-left-radius 3px
|
|
||||||
border 1px solid borderColor
|
|
||||||
border-right none
|
|
||||||
.ShareButton-url-button
|
|
||||||
height 21px
|
|
||||||
border none
|
|
||||||
width 30px
|
|
||||||
float left
|
|
||||||
background-color #F0F0F0
|
|
||||||
border-top-right-radius 3px
|
|
||||||
border-bottom-right-radius 3px
|
|
||||||
border 1px solid borderColor
|
|
||||||
.ShareButton-url-button-tooltip
|
|
||||||
tooltip()
|
|
||||||
right 10px
|
|
||||||
margin-top 5px
|
|
||||||
&:hover
|
|
||||||
.ShareButton-url-button-tooltip
|
|
||||||
opacity 1
|
|
||||||
&:active
|
|
||||||
background-color #4297FE
|
|
||||||
color white
|
|
||||||
.ShareButton-url-alert
|
|
||||||
padding 10px
|
|
||||||
line-height 16px
|
|
||||||
|
|
||||||
|
|
||||||
.ArticleDetail-info-row2
|
|
||||||
.tutorial
|
|
||||||
position fixed
|
|
||||||
z-index 35
|
|
||||||
font-style italic
|
|
||||||
.TagSelect
|
|
||||||
margin-top 5px
|
|
||||||
.TagSelect-tags
|
|
||||||
white-space nowrap
|
|
||||||
overflow-x auto
|
|
||||||
position relative
|
|
||||||
noSelect()
|
|
||||||
z-index 30
|
|
||||||
background-color #E6E6E6
|
|
||||||
clearfix()
|
|
||||||
.TagSelect-tags-item
|
|
||||||
background-color transparent
|
|
||||||
color white
|
|
||||||
margin 0 2px
|
|
||||||
padding 0
|
|
||||||
height 17px
|
|
||||||
float left
|
|
||||||
button.TagSelect-tags-item-remove
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
background-color transparent
|
|
||||||
border none
|
|
||||||
font-size 8px
|
|
||||||
color white
|
|
||||||
width 15px
|
|
||||||
height 17px
|
|
||||||
text-align center
|
|
||||||
line-height 12px
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
border-top solid 1px darken(brandColor, 5%)
|
|
||||||
border-bottom solid 1px darken(brandColor, 5%)
|
|
||||||
border-left solid 1px darken(brandColor, 5%)
|
|
||||||
border-right solid 1px transparent
|
|
||||||
border-radius left 2px
|
|
||||||
background-color brandColor
|
|
||||||
&:hover
|
|
||||||
background-color lighten(brandColor, 10%)
|
|
||||||
border-color lighten(brandColor, 10%)
|
|
||||||
&:focus
|
|
||||||
background-color lighten(brandColor, 10%)
|
|
||||||
border-color focusBorderColor
|
|
||||||
.TagSelect-tags-item-label
|
|
||||||
background-color brandColor
|
|
||||||
float left
|
|
||||||
font-size 12px
|
|
||||||
border-top solid 1px darken(brandColor, 5%)
|
|
||||||
border-bottom solid 1px darken(brandColor, 5%)
|
|
||||||
border-right solid 1px darken(brandColor, 5%)
|
|
||||||
line-height 15px
|
|
||||||
padding 0 5px
|
|
||||||
border-radius right 2px
|
|
||||||
input.TagSelect-input
|
|
||||||
background-color transparent
|
|
||||||
border none
|
|
||||||
border-bottom 1px solid transparent
|
|
||||||
outline none
|
|
||||||
margin 0 2px
|
|
||||||
transition 0.15s
|
|
||||||
height 18px
|
|
||||||
&:focus
|
|
||||||
border-color focusBorderColor
|
|
||||||
.TagSelect-suggest
|
|
||||||
position fixed
|
|
||||||
width 150px
|
|
||||||
max-height 150px
|
|
||||||
background-color white
|
|
||||||
z-index 50
|
|
||||||
border 1px solid borderColor
|
|
||||||
border-radius 5px
|
|
||||||
overflow-y auto
|
|
||||||
&>button
|
|
||||||
width 100%
|
|
||||||
display block
|
|
||||||
padding 0 15px
|
|
||||||
height 33px
|
|
||||||
line-height 33px
|
|
||||||
background-color transparent
|
|
||||||
border none
|
|
||||||
text-align left
|
|
||||||
font-size 14px
|
|
||||||
&:hover
|
|
||||||
background-color darken(white, 10%)
|
|
||||||
.ArticleDetail-panel
|
|
||||||
position absolute
|
|
||||||
top 70px
|
|
||||||
left 10px
|
|
||||||
right 10px
|
|
||||||
bottom 10px
|
|
||||||
overflow-x hidden
|
|
||||||
overflow-y auto
|
|
||||||
background-color white
|
|
||||||
border-radius 5px
|
|
||||||
border solid 1px lighten(borderColor, 15%)
|
|
||||||
&>.ArticleDetail-panel-header
|
|
||||||
display block
|
|
||||||
height 60px
|
|
||||||
&>.tutorial
|
|
||||||
fixed right
|
|
||||||
z-index 35
|
|
||||||
font-style italic
|
|
||||||
.ArticleDetail-panel-header-mode
|
|
||||||
z-index 30
|
|
||||||
background-color white
|
|
||||||
absolute top bottom
|
|
||||||
right 10px
|
|
||||||
display block
|
|
||||||
height 33px
|
|
||||||
margin-top 14px
|
|
||||||
width 120px
|
|
||||||
margin-right 15px
|
|
||||||
border solid 1px borderColor
|
|
||||||
border-radius 5px
|
|
||||||
transition width 0.15s
|
|
||||||
user-select none
|
|
||||||
&.idle
|
|
||||||
cursor pointer
|
|
||||||
&:hover
|
|
||||||
background-color darken(white, 5%)
|
|
||||||
.ModeIcon
|
|
||||||
padding 0 5px
|
|
||||||
line-height 33px
|
|
||||||
&.edit
|
|
||||||
border-color focusBorderColor
|
|
||||||
input
|
|
||||||
width 120px
|
|
||||||
line-height 31px
|
|
||||||
padding 0 10px
|
|
||||||
border none
|
|
||||||
outline none
|
|
||||||
background-color transparent
|
|
||||||
font-size 14px
|
|
||||||
.ModeSelect-options
|
|
||||||
position fixed
|
|
||||||
width 120px
|
|
||||||
z-index 10
|
|
||||||
border 1px solid borderColor
|
|
||||||
border-radius 5px
|
|
||||||
background-color white
|
|
||||||
max-height 250px
|
|
||||||
overflow-y auto
|
|
||||||
margin-top 5px
|
|
||||||
.ModeSelect-options-item
|
|
||||||
height 33px
|
|
||||||
line-height 33px
|
|
||||||
cursor pointer
|
|
||||||
&.active, &:hover.active
|
|
||||||
background-color brandColor
|
|
||||||
color white
|
|
||||||
.ModeIcon
|
|
||||||
width 30px
|
|
||||||
text-align center
|
|
||||||
display inline-block
|
|
||||||
&:hover
|
|
||||||
background-color darken(white, 10%)
|
|
||||||
.ArticleDetail-panel-header-title
|
|
||||||
absolute left top
|
|
||||||
right 145px
|
|
||||||
padding 0 15px
|
|
||||||
background-color transparent
|
|
||||||
input
|
|
||||||
border none
|
|
||||||
line-height 60px
|
|
||||||
width 100%
|
|
||||||
font-size 24px
|
|
||||||
outline none
|
|
||||||
.ArticleEditor
|
|
||||||
absolute left right bottom
|
|
||||||
top 60px
|
|
||||||
.ArticleDetail-panel-content-tooltip
|
|
||||||
absolute bottom right
|
|
||||||
height 24px
|
|
||||||
background-color alpha(black, 0.5)
|
|
||||||
line-height 24px
|
|
||||||
color white
|
|
||||||
padding 0 15px
|
|
||||||
opacity 0
|
|
||||||
transition 0.1s
|
|
||||||
z-index 35
|
|
||||||
&:hover .ArticleDetail-panel-content-tooltip
|
|
||||||
opacity 1
|
|
||||||
.MarkdownPreview
|
|
||||||
absolute top left right bottom
|
|
||||||
marked()
|
|
||||||
box-sizing border-box
|
|
||||||
padding 5px 15px
|
|
||||||
border-top solid 1px borderColor
|
|
||||||
overflow-y auto
|
|
||||||
user-select all
|
|
||||||
&.empty
|
|
||||||
color lighten(inactiveTextColor, 10%)
|
|
||||||
user-select none
|
|
||||||
font-size 14px
|
|
||||||
&.lineNumbered
|
|
||||||
.lineNumber
|
|
||||||
display block
|
|
||||||
.CodeEditor
|
|
||||||
absolute top left right bottom
|
|
||||||
border-top solid 1px borderColor
|
|
||||||
min-height 300px
|
|
||||||
border-bottom-left-radius 5px
|
|
||||||
border-bottom-right-radius 5px
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
articleItemHoverBgColor = darken(white, 5%)
|
|
||||||
articleItemColor = #777
|
|
||||||
|
|
||||||
.ArticleList
|
|
||||||
absolute bottom
|
|
||||||
top 60px
|
|
||||||
left 200px
|
|
||||||
width 250px
|
|
||||||
border-top 1px solid borderColor
|
|
||||||
border-right 1px solid borderColor
|
|
||||||
&:focus
|
|
||||||
border-color focusBorderColor
|
|
||||||
overflow-y auto
|
|
||||||
noSelect()
|
|
||||||
&>div
|
|
||||||
.ArticleList-item
|
|
||||||
border solid 2px transparent
|
|
||||||
position relative
|
|
||||||
min-height 110px
|
|
||||||
width 100%
|
|
||||||
cursor pointer
|
|
||||||
transition 0.1s
|
|
||||||
background-color white
|
|
||||||
padding 0 10px
|
|
||||||
font-size 12px
|
|
||||||
.ArticleList-item-top
|
|
||||||
clearfix()
|
|
||||||
padding-top 2px
|
|
||||||
line-height 18px
|
|
||||||
height 20px
|
|
||||||
color articleItemColor
|
|
||||||
font-size 11px
|
|
||||||
i
|
|
||||||
margin-right 4px
|
|
||||||
.folderName
|
|
||||||
overflow ellipsis
|
|
||||||
display inline-block
|
|
||||||
width 120px
|
|
||||||
.updatedAt
|
|
||||||
float right
|
|
||||||
line-height 18px
|
|
||||||
.unsaved-mark
|
|
||||||
color brandColor
|
|
||||||
.ArticleList-item-middle
|
|
||||||
font-size 16px
|
|
||||||
position relative
|
|
||||||
padding-top 6px
|
|
||||||
height 22px
|
|
||||||
.mode
|
|
||||||
position absolute
|
|
||||||
left 0
|
|
||||||
font-size 12px
|
|
||||||
line-height 16px
|
|
||||||
.title
|
|
||||||
position absolute
|
|
||||||
left 19px
|
|
||||||
right 0
|
|
||||||
overflow ellipsis
|
|
||||||
small
|
|
||||||
color #AAA
|
|
||||||
.ArticleList-item-middle2
|
|
||||||
padding-top 8px
|
|
||||||
pre
|
|
||||||
color lighten(inactiveTextColor, 10%)
|
|
||||||
white-space pre-wrap
|
|
||||||
overflow hidden
|
|
||||||
height 33px
|
|
||||||
line-height 14px
|
|
||||||
font-size 10px
|
|
||||||
code
|
|
||||||
font-family Monaco, Menlo, 'Ubuntu Mono', Consolas, source-code-pro, monospace
|
|
||||||
.ArticleList-item-bottom
|
|
||||||
padding-bottom 5px
|
|
||||||
.tags
|
|
||||||
color articleItemColor
|
|
||||||
line-height 18px
|
|
||||||
word-wrap break-word
|
|
||||||
clearfix()
|
|
||||||
i.fa-tags
|
|
||||||
display inline
|
|
||||||
float left
|
|
||||||
padding 2px 2px 0 0
|
|
||||||
height 14px
|
|
||||||
line-height 13px
|
|
||||||
a
|
|
||||||
background-color brandColor
|
|
||||||
float left
|
|
||||||
color white
|
|
||||||
border-radius 2px
|
|
||||||
padding 1px 5px
|
|
||||||
margin 2px
|
|
||||||
height 14px
|
|
||||||
line-height 13px
|
|
||||||
font-size 10px
|
|
||||||
opacity 0.8
|
|
||||||
&:hover
|
|
||||||
opacity 1
|
|
||||||
&:hover, &.hover
|
|
||||||
background-color articleItemHoverBgColor
|
|
||||||
&:active, &.active
|
|
||||||
background-color white
|
|
||||||
&:active, &.active
|
|
||||||
border-color brandBorderColor
|
|
||||||
.divider
|
|
||||||
border-bottom solid 1px borderColor
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
articleNavBgColor = #353535
|
|
||||||
articleCount = #999
|
|
||||||
|
|
||||||
.ArticleNavigator
|
|
||||||
background-color articleNavBgColor
|
|
||||||
absolute top bottom left
|
|
||||||
width 200px
|
|
||||||
border-right 1px solid borderColor
|
|
||||||
color white
|
|
||||||
user-select none
|
|
||||||
.userInfo
|
|
||||||
height 60px
|
|
||||||
display block
|
|
||||||
box-sizing content-box
|
|
||||||
border-bottom 1px solid borderColor
|
|
||||||
.userProfileName
|
|
||||||
color brandColor
|
|
||||||
font-size 28px
|
|
||||||
padding 6px 37px 0 10px
|
|
||||||
white-space nowrap
|
|
||||||
text-overflow ellipsis
|
|
||||||
overflow hidden
|
|
||||||
.userName
|
|
||||||
color white
|
|
||||||
padding-left 20px
|
|
||||||
margin-top 3px
|
|
||||||
.tutorial
|
|
||||||
position fixed
|
|
||||||
z-index 35
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
pointer-event none
|
|
||||||
font-style italic
|
|
||||||
transition 0.1s
|
|
||||||
&.hide
|
|
||||||
opacity 0
|
|
||||||
.settingBtn
|
|
||||||
width 22px
|
|
||||||
height 22px
|
|
||||||
line-height 22px
|
|
||||||
border-radius 11px
|
|
||||||
position absolute
|
|
||||||
top 19px
|
|
||||||
right 14px
|
|
||||||
color white
|
|
||||||
padding 0
|
|
||||||
background-color transparent
|
|
||||||
border 1px solid white
|
|
||||||
z-index 31
|
|
||||||
.tooltip
|
|
||||||
tooltip()
|
|
||||||
margin-top -5px
|
|
||||||
margin-left 10px
|
|
||||||
&:hover
|
|
||||||
.tooltip
|
|
||||||
opacity 1
|
|
||||||
&:active
|
|
||||||
background-color brandColor
|
|
||||||
border-color brandColor
|
|
||||||
.ArticleNavigator-unsaved
|
|
||||||
position absolute
|
|
||||||
top 100px
|
|
||||||
width 100%
|
|
||||||
height 225px
|
|
||||||
transition opacity 0.2s ease-in-out
|
|
||||||
&.hide
|
|
||||||
opacity 0.2
|
|
||||||
.ArticleNavigator-unsaved-header
|
|
||||||
border-bottom 1px solid alpha(borderColor, 0.5)
|
|
||||||
padding-bottom 5px
|
|
||||||
clearfix()
|
|
||||||
position relative
|
|
||||||
padding-left 10px
|
|
||||||
font-size 18px
|
|
||||||
line-height 22px
|
|
||||||
.ArticleNavigator-unsaved-list
|
|
||||||
height 165px
|
|
||||||
padding 5px 0
|
|
||||||
overflow-y scroll
|
|
||||||
.ArticleNavigator-unsaved-list-item
|
|
||||||
height 33px
|
|
||||||
padding-left 15px
|
|
||||||
clearfix()
|
|
||||||
transition 0.1s
|
|
||||||
cursor pointer
|
|
||||||
overflow hidden
|
|
||||||
&:hover
|
|
||||||
background-color alpha(white, 0.05)
|
|
||||||
&.active, &:active
|
|
||||||
background-color alpha(lighten(brandColor, 25%), 70%)
|
|
||||||
.ArticleNavigator-unsaved-list-item-label
|
|
||||||
float left
|
|
||||||
width 151px
|
|
||||||
line-height 33px
|
|
||||||
overflow ellipsis
|
|
||||||
.ArticleNavigator-unsaved-list-item-label-untitled
|
|
||||||
color inactiveTextColor
|
|
||||||
.ArticleNavigator-unsaved-list-item-discard-button
|
|
||||||
float right
|
|
||||||
width 33px
|
|
||||||
line-height 30px
|
|
||||||
height 33px
|
|
||||||
border none
|
|
||||||
background-color transparent
|
|
||||||
color white
|
|
||||||
font-size 18px
|
|
||||||
opacity 0.5
|
|
||||||
&:hover
|
|
||||||
opacity 1
|
|
||||||
.ArticleNavigator-unsaved-list-empty
|
|
||||||
height 33px
|
|
||||||
padding-left 15px
|
|
||||||
color alpha(white, 0.4)
|
|
||||||
transition 0.1s
|
|
||||||
line-height 33px
|
|
||||||
&:hover
|
|
||||||
color alpha(white, 0.6)
|
|
||||||
.ArticleNavigator-unsaved-control
|
|
||||||
absolute bottom
|
|
||||||
height 33px
|
|
||||||
border-top 1px solid alpha(borderColor, 0.5)
|
|
||||||
width 100%
|
|
||||||
.ArticleNavigator-unsaved-control-save-all-button
|
|
||||||
border none
|
|
||||||
background-color transparent
|
|
||||||
font-size 14px
|
|
||||||
color brandColor
|
|
||||||
padding-left 15px
|
|
||||||
width 100%
|
|
||||||
height 33px
|
|
||||||
text-align left
|
|
||||||
&:hover
|
|
||||||
color lighten(brandColor, 15%)
|
|
||||||
background-color alpha(white, 0.05)
|
|
||||||
&:active
|
|
||||||
color white
|
|
||||||
&:disabled
|
|
||||||
color alpha(brandColor, 0.5)
|
|
||||||
&:hover
|
|
||||||
color alpha(lighten(brandColor, 25%), 0.5)
|
|
||||||
background-color transparent
|
|
||||||
|
|
||||||
|
|
||||||
.ArticleNavigator-folders
|
|
||||||
absolute bottom
|
|
||||||
top 365px
|
|
||||||
width 100%
|
|
||||||
transition top 0.15s ease-in-out
|
|
||||||
background-color articleNavBgColor
|
|
||||||
.tutorial
|
|
||||||
position fixed
|
|
||||||
z-index 35
|
|
||||||
font-style italic
|
|
||||||
&.expand
|
|
||||||
top 100px
|
|
||||||
.ArticleNavigator-folders-header
|
|
||||||
border-bottom 1px solid alpha(borderColor, 0.5)
|
|
||||||
padding-bottom 5px
|
|
||||||
clearfix()
|
|
||||||
position relative
|
|
||||||
z-index 30
|
|
||||||
.title
|
|
||||||
float left
|
|
||||||
padding-left 10px
|
|
||||||
font-size 18px
|
|
||||||
line-height 22px
|
|
||||||
.addBtn
|
|
||||||
float right
|
|
||||||
margin-right 15px
|
|
||||||
width 22px
|
|
||||||
height 22px
|
|
||||||
font-size 10px
|
|
||||||
padding 0
|
|
||||||
line-height 22px
|
|
||||||
border 1px solid white
|
|
||||||
border-radius 11px
|
|
||||||
background-color transparent
|
|
||||||
color white
|
|
||||||
padding 0
|
|
||||||
font-weight bold
|
|
||||||
.tooltip
|
|
||||||
tooltip()
|
|
||||||
margin-top -6px
|
|
||||||
margin-left 11px
|
|
||||||
&:hover
|
|
||||||
.tooltip
|
|
||||||
opacity 1
|
|
||||||
&:active
|
|
||||||
background-color brandColor
|
|
||||||
border-color brandColor
|
|
||||||
.folderList
|
|
||||||
absolute bottom
|
|
||||||
top 33px
|
|
||||||
overflow-y auto
|
|
||||||
.folderList button
|
|
||||||
height 33px
|
|
||||||
width 199px
|
|
||||||
border none
|
|
||||||
text-align left
|
|
||||||
font-size 14px
|
|
||||||
background-color transparent
|
|
||||||
color white
|
|
||||||
padding-left 15px
|
|
||||||
overflow ellipsis
|
|
||||||
&:hover
|
|
||||||
background-color alpha(white, 0.05)
|
|
||||||
&.active, &:active
|
|
||||||
background-color alpha(lighten(brandColor, 25%), 70%)
|
|
||||||
.articleCount
|
|
||||||
color white
|
|
||||||
.articleCount
|
|
||||||
color articleCount
|
|
||||||
font-size 12px
|
|
||||||
@@ -2,9 +2,6 @@
|
|||||||
@import '../mixins/*'
|
@import '../mixins/*'
|
||||||
global-reset()
|
global-reset()
|
||||||
@import '../shared/*'
|
@import '../shared/*'
|
||||||
@import './ArticleNavigator'
|
|
||||||
@import './ArticleList'
|
|
||||||
@import './ArticleDetail'
|
|
||||||
@import './modal/*'
|
@import './modal/*'
|
||||||
@import '../theme/*'
|
@import '../theme/*'
|
||||||
|
|
||||||
@@ -89,19 +86,3 @@ textarea.block-input
|
|||||||
|
|
||||||
#content
|
#content
|
||||||
fullsize()
|
fullsize()
|
||||||
|
|
||||||
.Main
|
|
||||||
.appUpdateButton
|
|
||||||
position fixed
|
|
||||||
z-index 2000
|
|
||||||
bottom 5px
|
|
||||||
right 53px
|
|
||||||
padding 10px 15px
|
|
||||||
border none
|
|
||||||
border-radius 5px
|
|
||||||
background-color brandColor
|
|
||||||
color white
|
|
||||||
opacity 0.7
|
|
||||||
&:hover
|
|
||||||
opacity 1
|
|
||||||
background-color lighten(brandColor, 10%)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user