1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 17:56:25 +00:00

refactor file structure

This commit is contained in:
Rokt33r
2016-05-12 20:45:21 +09:00
parent c851f8f006
commit 18b6d8289f
22 changed files with 43 additions and 470 deletions

View File

@@ -7,7 +7,7 @@ import TagSelect from 'browser/components/TagSelect'
import ModeSelect from 'browser/components/ModeSelect' import ModeSelect from 'browser/components/ModeSelect'
import ShareButton from './ShareButton' import ShareButton from './ShareButton'
import { openModal, isModalOpen } from 'browser/lib/modal' import { openModal, isModalOpen } from 'browser/lib/modal'
import DeleteArticleModal from '../../modal/DeleteArticleModal' import DeleteArticleModal from '../modals/DeleteArticleModal'
import ArticleEditor from './ArticleEditor' import ArticleEditor from './ArticleEditor'
const electron = require('electron') const electron = require('electron')
const ipc = electron.ipcRenderer const ipc = electron.ipcRenderer

View File

@@ -3,7 +3,6 @@ import ReactDOM from 'react-dom'
import ModeIcon from 'browser/components/ModeIcon' import ModeIcon from 'browser/components/ModeIcon'
import moment from 'moment' import moment from 'moment'
import FolderMark from 'browser/components/FolderMark' import FolderMark from 'browser/components/FolderMark'
import TagLink from './TagLink'
import _ from 'lodash' import _ from 'lodash'
const electron = require('electron') const electron = require('electron')
@@ -129,55 +128,7 @@ export default class ArticleList extends React.Component {
} }
render () { render () {
let articles = [] let articleElements = []
let folders = []
let articleElements = articles.map((article) => {
let originalArticle = article
let tagElements = Array.isArray(article.tags) && article.tags.length > 0
? article.tags.slice().map((tag) => {
return (<TagLink key={tag} tag={tag}/>)
})
: (<span>Not tagged yet</span>)
let folder = _.findWhere(folders, {key: article.FolderKey})
let folderChanged = originalArticle.FolderKey !== article.FolderKey
let originalFolder = folderChanged ? _.findWhere(folders, {key: originalArticle.FolderKey}) : null
let title = article.title.trim().length === 0
? <small>(Untitled)</small>
: article.title
return (
<div key={'article-' + article.key}>
<div onClick={(e) => this.handleArticleClick(article)(e)} className={'ArticleList-item' + (article.key === 'ACTIVE_POST_KEY' ? ' active' : '')}>
<div className='ArticleList-item-top'>
{folder != null
? folderChanged
? <span className='folderName'>
<FolderMark color={originalFolder.color}/>{originalFolder.name}
->
<FolderMark color={folder.color}/>{folder.name}
</span>
: <span className='folderName'>
<FolderMark color={folder.color}/>{folder.name}
</span>
: <span><FolderMark color={-1}/>Unknown</span>
}
<span className='updatedAt'>{moment(article.updatedAt).fromNow()}</span>
</div>
<div className='ArticleList-item-middle'>
<ModeIcon className='mode' mode={article.mode}/> <div className='title' children={title}/>
</div>
<div className='ArticleList-item-middle2'>
<pre><code children={article.content.trim().length === 0 ? '(Empty content)' : article.content.substring(0, 50)}/></pre>
</div>
<div className='ArticleList-item-bottom'>
<div className='tags'><i className='fa fa-fw fa-tags'/>{tagElements}</div>
</div>
</div>
<div className='divider'></div>
</div>
)
})
return ( return (
<div tabIndex='3' onKeyDown={(e) => this.handleArticleListKeyDown(e)} className='ArticleList'> <div tabIndex='3' onKeyDown={(e) => this.handleArticleListKeyDown(e)} className='ArticleList'>

View File

@@ -1,15 +0,0 @@
import React, { PropTypes } from 'react'
export default class TagLink extends React.Component {
handleClick (e) {
}
render () {
return (
<a onClick={(e) => this.handleClick(e)}>{this.props.tag}</a>
)
}
}
TagLink.propTypes = {
tag: PropTypes.string
}

View File

@@ -1,104 +0,0 @@
import React, { PropTypes} from 'react'
import { connect } from 'react-redux'
import ReactDOM from 'react-dom'
import SideNav from './SideNav'
import ArticleTopBar from './ArticleTopBar'
import ArticleList from './ArticleList'
import ArticleDetail from './ArticleDetail'
import { isModalOpen, closeModal } from 'browser/lib/modal'
import Repository from 'browser/lib/Repository'
const electron = require('electron')
const remote = electron.remote
const OSX = global.process.platform === 'darwin'
class HomePage extends React.Component {
componentDidMount () {
let { dispatch } = this.props
// Bind directly to window
// this.keyHandler = (e) => this.handleKeyDown(e)
// window.addEventListener('keydown', this.keyHandler)
// Reload all data
Repository.loadAll()
.then((allData) => {
dispatch({type: 'INIT_ALL', data: allData})
})
}
componentWillUnmount () {
window.removeEventListener('keydown', this.keyHandler)
}
handleKeyDown (e) {
// if (isModalOpen()) {
// if (e.keyCode === 13 && (OSX ? e.metaKey : e.ctrlKey)) {
// remote.getCurrentWebContents().send('modal-confirm')
// }
// if (e.keyCode === 27) closeModal()
// return
// }
// let { dispatch } = this.props
// let { top, list } = this.refs
// let listElement = ReactDOM.findDOMNode(list)
// if (status.isTutorialOpen) {
// // dispatch(toggleTutorial())
// e.preventDefault()
// return
// }
// if (e.keyCode === 13 && top.isInputFocused()) {
// listElement.focus()
// return
// }
// if (e.keyCode === 27 && top.isInputFocused()) {
// // if (status.search.length > 0) top.escape()
// // else listElement.focus()
// return
// }
// // Search inputがfocusされていたら大体のキー入力は無視される。
// if (e.keyCode === 27) {
// if (document.activeElement !== listElement) {
// listElement.focus()
// } else {
// top.focusInput()
// }
// return
// }
}
render () {
return (
<div className='HomePage'>
<SideNav
ref='nav'
{...this.props}
/>
<ArticleTopBar
ref='top'
{...this.props}
/>
<ArticleList
ref='list'
{...this.props}
/>
<ArticleDetail
ref='detail'
{...this.props}
/>
</div>
)
}
}
HomePage.propTypes = {
dispatch: PropTypes.func,
repositories: PropTypes.array
}
export default connect((x) => x)(HomePage)

View File

@@ -1,18 +1,30 @@
const electron = require('electron') const electron = require('electron')
import { connect } from 'react-redux'
const ipc = electron.ipcRenderer const ipc = electron.ipcRenderer
import React, { PropTypes } from 'react' import React, { PropTypes } from 'react'
import HomePage from './HomePage' import SideNav from './SideNav'
import ArticleTopBar from './ArticleTopBar'
import ArticleList from './ArticleList'
import ArticleDetail from './ArticleDetail'
import Repository from 'browser/lib/Repository'
export default class MainContainer extends React.Component { class Main extends React.Component {
constructor (props) { constructor (props) {
super(props) super(props)
this.state = {updateAvailable: false} this.state = {updateAvailable: false}
} }
componentDidMount () { componentDidMount () {
let { dispatch } = this.props
ipc.on('update-available', function (message) { ipc.on('update-available', function (message) {
this.setState({updateAvailable: true}) this.setState({updateAvailable: true})
}.bind(this)) }.bind(this))
// Reload all data
Repository.loadAll()
.then((allData) => {
dispatch({type: 'INIT_ALL', data: allData})
})
} }
updateApp () { updateApp () {
@@ -27,12 +39,31 @@ export default class MainContainer extends React.Component {
{this.state.updateAvailable ? ( {this.state.updateAvailable ? (
<button onClick={this.updateApp} className='appUpdateButton'><i className='fa fa-cloud-download'/> Update available!</button> <button onClick={this.updateApp} className='appUpdateButton'><i className='fa fa-cloud-download'/> Update available!</button>
) : null} ) : null}
<HomePage {...this.props}/>
<SideNav
ref='nav'
{...this.props}
/>
<ArticleTopBar
ref='top'
{...this.props}
/>
<ArticleList
ref='list'
{...this.props}
/>
<ArticleDetail
ref='detail'
{...this.props}
/>
</div> </div>
) )
} }
} }
MainContainer.propTypes = { Main.propTypes = {
children: PropTypes.element dispatch: PropTypes.func,
repositories: PropTypes.array
} }
export default connect((x) => x)(Main)

View File

@@ -2,9 +2,9 @@ import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
import styles from './SideNav.styl' import styles from './SideNav.styl'
import { openModal } from 'browser/lib/modal' import { openModal } from 'browser/lib/modal'
import Preferences from '../../modal/Preferences' import Preferences from '../modals/Preferences'
import RepositorySection from './RepositorySection' import RepositorySection from './RepositorySection'
import NewRepositoryModal from '../../modal/NewRepositoryModal' import NewRepositoryModal from '../modals/NewRepositoryModal'
const electron = require('electron') const electron = require('electron')
const { remote } = electron const { remote } = electron

View File

@@ -1,106 +0,0 @@
import React, { PropTypes } from 'react'
import ReactDOM from 'react-dom'
import linkState from 'browser/lib/linkState'
import store from '../store'
import FolderMark from 'browser/components/FolderMark'
export default class CreateNewFolder extends React.Component {
constructor (props) {
super(props)
this.state = {
name: '',
color: Math.round(Math.random() * 7),
alert: null
}
}
componentDidMount () {
ReactDOM.findDOMNode(this.refs.folderName).focus()
}
handleCloseButton (e) {
this.props.close()
}
handleConfirmButton (e) {
this.setState({alert: null}, () => {
let { close } = this.props
let { name, color } = this.state
let input = {
name,
color
}
try {
// store.dispatch(createFolder(input))
} catch (e) {
this.setState({alert: {
type: 'error',
message: e.message
}})
return
}
close()
})
}
handleColorClick (colorIndex) {
return (e) => {
this.setState({
color: colorIndex
})
}
}
handleKeyDown (e) {
if (e.keyCode === 13) {
this.handleConfirmButton()
}
}
render () {
let alert = this.state.alert
let alertElement = alert != null ? (
<p className={`alert ${alert.type}`}>
{alert.message}
</p>
) : null
let colorIndexes = []
for (let i = 0; i < 8; i++) {
colorIndexes.push(i)
}
let colorElements = colorIndexes.map((index) => {
let className = 'option'
if (index === this.state.color) className += ' active'
return (
<span className={className} key={index} onClick={(e) => this.handleColorClick(index)(e)}>
<FolderMark color={index}/>
</span>
)
})
return (
<div className='CreateNewFolder modal'>
<button onClick={(e) => this.handleCloseButton(e)} className='closeBtn'><i className='fa fa-fw fa-times'/></button>
<div className='title'>Create new folder</div>
<input ref='folderName' onKeyDown={(e) => this.handleKeyDown(e)} className='ipt' type='text' valueLink={this.linkState('name')} placeholder='Enter folder name'/>
<div className='colorSelect'>
{colorElements}
</div>
{alertElement}
<button onClick={(e) => this.handleConfirmButton(e)} className='confirmBtn'>Create</button>
</div>
)
}
}
CreateNewFolder.propTypes = {
close: PropTypes.func
}
CreateNewFolder.prototype.linkState = linkState

View File

@@ -1,184 +0,0 @@
import React, { PropTypes } from 'react'
import linkState from 'browser/lib/linkState'
import FolderMark from 'browser/components/FolderMark'
import store from '../../store'
const IDLE = 'IDLE'
const EDIT = 'EDIT'
const DELETE = 'DELETE'
export default class FolderRow extends React.Component {
constructor (props) {
super(props)
this.state = {
mode: IDLE
}
}
handleUpClick (e) {
let { index } = this.props
if (index > 0) {
// store.dispatch(replaceFolder(index, index - 1))
}
}
handleDownClick (e) {
let { index, count } = this.props
if (index < count - 1) {
// store.dispatch(replaceFolder(index, index + 1))
}
}
handleCancelButtonClick (e) {
this.setState({
mode: IDLE
})
}
handleEditButtonClick (e) {
this.setState({
mode: EDIT,
name: this.props.folder.name,
color: this.props.folder.color,
isColorEditing: false
})
}
handleDeleteButtonClick (e) {
this.setState({mode: DELETE})
}
handleNameInputKeyDown (e) {
if (e.keyCode === 13) {
this.handleSaveButtonClick()
}
}
handleColorSelectClick (e) {
this.setState({
isColorEditing: true
})
}
handleColorButtonClick (index) {
return (e) => {
this.setState({
color: index,
isColorEditing: false
})
}
}
handleSaveButtonClick (e) {
let { folder, setAlert } = this.props
setAlert(null, () => {
let input = {
name: this.state.name,
color: this.state.color
}
folder = Object.assign({}, folder, input)
try {
// store.dispatch(updateFolder(folder))
this.setState({
mode: IDLE
})
} catch (e) {
console.error(e)
setAlert({
type: 'error',
message: e.message
})
}
})
}
handleDeleteConfirmButtonClick (e) {
let { folder } = this.props
// store.dispatch(destroyFolder(folder.key))
}
render () {
let folder = this.props.folder
switch (this.state.mode) {
case EDIT:
let colorIndexes = []
for (let i = 0; i < 8; i++) {
colorIndexes.push(i)
}
let colorOptions = colorIndexes.map((index) => {
let className = this.state.color === index
? 'active'
: null
return (
<button onClick={(e) => this.handleColorButtonClick(index)(e)} className={className} key={index}>
<FolderMark color={index}/>
</button>
)
})
return (
<div className='FolderRow edit'>
<div className='folderColor'>
<button onClick={(e) => this.handleColorSelectClick(e)} className='select'>
<FolderMark color={this.state.color}/>
</button>
{this.state.isColorEditing
? <div className='options'>
<div className='label'>Color select</div>
{colorOptions}
</div>
: null
}
</div>
<div className='folderName'>
<input onKeyDown={(e) => this.handleNameInputKeyDown(e)} valueLink={this.linkState('name')} type='text'/>
</div>
<div className='folderControl'>
<button onClick={(e) => this.handleSaveButtonClick(e)} className='primary'>Save</button>
<button onClick={(e) => this.handleCancelButtonClick(e)}>Cancel</button>
</div>
</div>
)
case DELETE:
return (
<div className='FolderRow delete'>
<div className='folderDeleteLabel'>Are you sure to delete <strong>{folder.name}</strong> folder?</div>
<div className='folderControl'>
<button onClick={(e) => this.handleDeleteConfirmButtonClick(e)} className='primary'>Sure</button>
<button onClick={(e) => this.handleCancelButtonClick(e)}>Cancel</button>
</div>
</div>
)
case IDLE:
default:
return (
<div className='FolderRow'>
<div className='sortBtns'>
<button onClick={(e) => this.handleUpClick(e)}><i className='fa fa-sort-up fa-fw'/></button>
<button onClick={(e) => this.handleDownClick(e)}><i className='fa fa-sort-down fa-fw'/></button>
</div>
<div className='folderColor'><FolderMark color={folder.color}/></div>
<div className='folderName'>{folder.name}</div>
<div className='folderControl'>
<button onClick={(e) => this.handleEditButtonClick(e)}><i className='fa fa-fw fa-edit'/></button>
<button onClick={(e) => this.handleDeleteButtonClick(e)}><i className='fa fa-fw fa-close'/></button>
</div>
</div>
)
}
}
}
FolderRow.propTypes = {
folder: PropTypes.shape(),
index: PropTypes.number,
count: PropTypes.number,
setAlert: PropTypes.func
}
FolderRow.prototype.linkState = linkState

View File

@@ -1,9 +1,9 @@
import React, { PropTypes } from 'react' import React, { PropTypes } from 'react'
import { connect, Provider } from 'react-redux' import { connect, Provider } from 'react-redux'
import linkState from 'browser/lib/linkState' import linkState from 'browser/lib/linkState'
import store from '../store' import store from 'browser/main/store'
import AppSettingTab from './Preference/AppSettingTab' import AppSettingTab from './AppSettingTab'
import ContactTab from './Preference/ContactTab' import ContactTab from './ContactTab'
import { closeModal } from 'browser/lib/modal' import { closeModal } from 'browser/lib/modal'
const APP = 'APP' const APP = 'APP'