mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
refactor file structure
This commit is contained in:
53
browser/main/modals/DeleteArticleModal.js
Normal file
53
browser/main/modals/DeleteArticleModal.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import React, { PropTypes } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import store from '../store'
|
||||
|
||||
const electron = require('electron')
|
||||
const ipc = electron.ipcRenderer
|
||||
|
||||
export default class DeleteArticleModal extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.confirmHandler = (e) => this.handleYesButtonClick()
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
ReactDOM.findDOMNode(this.refs.no).focus()
|
||||
ipc.on('modal-confirm', this.confirmHandler)
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
ipc.removeListener('modal-confirm', this.confirmHandler)
|
||||
}
|
||||
|
||||
handleNoButtonClick (e) {
|
||||
this.props.close()
|
||||
}
|
||||
|
||||
handleYesButtonClick (e) {
|
||||
// store.dispatch(destroyArticle(this.props.articleKey))
|
||||
this.props.close()
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='DeleteArticleModal modal'>
|
||||
<div className='title'><i className='fa fa-fw fa-trash'/> Delete an article.</div>
|
||||
|
||||
<div className='message'>Do you really want to delete?</div>
|
||||
|
||||
<div className='control'>
|
||||
<button ref='no' onClick={(e) => this.handleNoButtonClick(e)}><i className='fa fa-fw fa-close'/> No</button>
|
||||
<button ref='yes' onClick={(e) => this.handleYesButtonClick(e)} className='danger'><i className='fa fa-fw fa-check'/> Yes</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
DeleteArticleModal.propTypes = {
|
||||
action: PropTypes.object,
|
||||
articleKey: PropTypes.string,
|
||||
close: PropTypes.func
|
||||
}
|
||||
193
browser/main/modals/NewRepositoryModal.js
Normal file
193
browser/main/modals/NewRepositoryModal.js
Normal file
@@ -0,0 +1,193 @@
|
||||
import React, { PropTypes } from 'react'
|
||||
import CSSModules from 'browser/lib/CSSModules'
|
||||
import styles from './NewRepositoryModal.styl'
|
||||
import Repository from 'browser/lib/Repository'
|
||||
import store from 'browser/main/store'
|
||||
|
||||
const electron = require('electron')
|
||||
const remote = electron.remote
|
||||
|
||||
function browseFolder () {
|
||||
let dialog = remote.dialog
|
||||
|
||||
let defaultPath = remote.app.getPath('home')
|
||||
return new Promise((resolve, reject) => {
|
||||
dialog.showOpenDialog({
|
||||
title: 'Select Directory',
|
||||
defaultPath,
|
||||
properties: ['openDirectory', 'createDirectory']
|
||||
}, function (targetPaths) {
|
||||
if (targetPaths == null) return resolve('')
|
||||
resolve(targetPaths[0])
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
class NewRepositoryModal extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
name: '',
|
||||
path: '',
|
||||
isPathSectionFocused: false,
|
||||
error: null,
|
||||
isBrowsingPath: false
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.refs.nameInput.focus()
|
||||
}
|
||||
|
||||
handleCloseButtonClick (e) {
|
||||
this.props.close()
|
||||
}
|
||||
|
||||
handlePathFocus (e) {
|
||||
this.setState({
|
||||
isPathSectionFocused: true
|
||||
})
|
||||
}
|
||||
|
||||
handlePathBlur (e) {
|
||||
if (e.relatedTarget !== this.refs.pathInput && e.relatedTarget !== this.refs.browseButton) {
|
||||
this.setState({
|
||||
isPathSectionFocused: false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handleBrowseButtonClick (e) {
|
||||
this.setState({
|
||||
isBrowsingPath: true
|
||||
}, () => {
|
||||
browseFolder()
|
||||
.then((targetPath) => {
|
||||
this.setState({
|
||||
path: targetPath,
|
||||
isBrowsingPath: false
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('BrowseFAILED')
|
||||
console.error(err)
|
||||
this.setState({
|
||||
isBrowsingPath: false
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
handleConfirmButtonClick (e) {
|
||||
let targetPath = this.state.path
|
||||
let name = this.state.name
|
||||
|
||||
let repository = new Repository({
|
||||
name: name,
|
||||
path: targetPath
|
||||
})
|
||||
|
||||
repository
|
||||
.mount()
|
||||
.then(() => repository.load())
|
||||
.then((data) => {
|
||||
store.dispatch({
|
||||
type: 'ADD_REPOSITORY',
|
||||
repository: data
|
||||
})
|
||||
this.props.close()
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
this.setState({
|
||||
error: err.message
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
handleChange (e) {
|
||||
let name = this.refs.nameInput.value
|
||||
let path = this.refs.pathInput.value
|
||||
this.setState({
|
||||
name,
|
||||
path
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='NewRepositoryModal'
|
||||
styleName='root'
|
||||
>
|
||||
<div styleName='header'>
|
||||
<div styleName='header-title'>New Repository</div>
|
||||
<button styleName='header-closeButton'
|
||||
onClick={(e) => this.handleCloseButtonClick(e)}
|
||||
>
|
||||
<i className='fa fa-times'/>
|
||||
</button>
|
||||
</div>
|
||||
<div styleName='body'>
|
||||
<div styleName='body-section'>
|
||||
<div styleName='body-section-label'>Repository Name</div>
|
||||
<input styleName='body-section-input'
|
||||
ref='nameInput'
|
||||
value={this.state.name}
|
||||
onChange={(e) => this.handleChange(e)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div styleName='body-section'>
|
||||
<div styleName='body-section-label'>Repository Path</div>
|
||||
<div styleName={!this.state.isPathSectionFocused ? 'body-section-path' : 'body-section-path--focus'}>
|
||||
<input styleName='body-section-path-input'
|
||||
ref='pathInput'
|
||||
value={this.state.path}
|
||||
style={styles.body_section_path_input}
|
||||
onFocus={(e) => this.handlePathFocus(e)}
|
||||
onBlur={(e) => this.handlePathBlur(e)}
|
||||
disabled={this.state.isBrowsingPath}
|
||||
onChange={(e) => this.handleChange(e)}
|
||||
/>
|
||||
<button styleName='body-section-path-button'
|
||||
onClick={(e) => this.handleBrowseButtonClick(e)}
|
||||
onFocus={(e) => this.handlePathFocus(e)}
|
||||
onBlur={(e) => this.handlePathBlur(e)}
|
||||
disabled={this.state.isBrowsingPath}
|
||||
>
|
||||
...
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
this.state.error != null && (
|
||||
<div styleName='body-error'>
|
||||
{this.state.error}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
<div styleName='footer'>
|
||||
<button styleName='footer-cancelButton'
|
||||
onClick={(e) => this.handleCloseButtonClick(e)}
|
||||
>
|
||||
<i className='fa fa-times'/> Cancel
|
||||
</button>
|
||||
<button styleName='footer-confirmButton'
|
||||
onClick={(e) => this.handleConfirmButtonClick(e)}
|
||||
>
|
||||
<i className='fa fa-check'/> Confirm
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
NewRepositoryModal.propTypes = {
|
||||
close: PropTypes.func
|
||||
}
|
||||
|
||||
export default CSSModules(NewRepositoryModal, styles)
|
||||
133
browser/main/modals/NewRepositoryModal.styl
Normal file
133
browser/main/modals/NewRepositoryModal.styl
Normal file
@@ -0,0 +1,133 @@
|
||||
$modal-width = 550px
|
||||
$modal-header-color = #F2F2F2
|
||||
$body-button-background-color = #2BAC8F
|
||||
|
||||
.root
|
||||
modal()
|
||||
width $modal-width
|
||||
height 310px
|
||||
|
||||
.header
|
||||
height 50px
|
||||
background-color $modal-header-color
|
||||
|
||||
.header-title
|
||||
font-size 24px
|
||||
line-height 50px
|
||||
padding-left 15px
|
||||
|
||||
.header-closeButton
|
||||
position absolute
|
||||
top 8.5px
|
||||
right 8.5px
|
||||
width 33px
|
||||
height 33px
|
||||
font-size 20px
|
||||
background-color transparent
|
||||
border none
|
||||
color #AAA
|
||||
&:hover
|
||||
color #4D4D4D
|
||||
|
||||
.body
|
||||
absolute left right
|
||||
top 50px
|
||||
bottom 50px
|
||||
padding 35px 0
|
||||
|
||||
.body-section
|
||||
height 33px
|
||||
margin-bottom 15px
|
||||
position relative
|
||||
|
||||
.body-section-label
|
||||
absolute top bottom left
|
||||
width 175px
|
||||
text-align right
|
||||
line-height 33px
|
||||
padding-right 15px
|
||||
|
||||
.body-section-input
|
||||
absolute top bottom
|
||||
left 175px
|
||||
width 315px
|
||||
padding 0 10px
|
||||
border $default-border
|
||||
border-radius 5px
|
||||
outline none
|
||||
&:focus
|
||||
border $active-border
|
||||
|
||||
.body-section-path
|
||||
absolute top bottom
|
||||
left 175px
|
||||
width 315px
|
||||
padding 0 10px
|
||||
border $default-border
|
||||
border-radius 5px
|
||||
outline none
|
||||
overflow hidden
|
||||
|
||||
.body-section-path--focus
|
||||
@extend .body-section-path
|
||||
border $active-border
|
||||
|
||||
.body-section-path-input
|
||||
absolute top left bottom
|
||||
width 265px
|
||||
border none
|
||||
outline none
|
||||
padding 0 10px
|
||||
|
||||
.body-section-path-button
|
||||
absolute top right bottom
|
||||
width 50px
|
||||
border none
|
||||
border-left $default-border
|
||||
outline none
|
||||
color white
|
||||
background-color $body-button-background-color
|
||||
transition 0.15s
|
||||
&:hover
|
||||
background-color lighten($body-button-background-color, 7%)
|
||||
&:disabled
|
||||
background-color lighten(gray, 15%)
|
||||
|
||||
.body-error
|
||||
height 33px
|
||||
margin 35px auto 0
|
||||
width 320px
|
||||
border-radius 5px
|
||||
text-align center
|
||||
line-height 33px
|
||||
color $danger-color
|
||||
background-color $danger-lighten-color
|
||||
|
||||
.footer
|
||||
absolute left right bottom
|
||||
height 50px
|
||||
|
||||
.footer-cancelButton
|
||||
position absolute
|
||||
height 33px
|
||||
right 85.5px
|
||||
width 72px
|
||||
top 8.5px
|
||||
border-radius 5px
|
||||
border $default-border
|
||||
background-color darken(white, 0.03)
|
||||
&:hover
|
||||
background-color white
|
||||
|
||||
.footer-confirmButton
|
||||
position absolute
|
||||
height 33px
|
||||
right 8.5px
|
||||
width 72px
|
||||
top 8.5px
|
||||
color white
|
||||
border-radius 5px
|
||||
border none
|
||||
background-color #2BAC8F
|
||||
&:hover
|
||||
background-color lighten($body-button-background-color, 7%)
|
||||
244
browser/main/modals/Preferences/AppSettingTab.js
Normal file
244
browser/main/modals/Preferences/AppSettingTab.js
Normal file
@@ -0,0 +1,244 @@
|
||||
import React, { PropTypes } from 'react'
|
||||
import linkState from 'browser/lib/linkState'
|
||||
import fetchConfig from 'browser/lib/fetchConfig'
|
||||
import hljsTheme from 'browser/lib/hljsThemes'
|
||||
|
||||
const electron = require('electron')
|
||||
const ipc = electron.ipcRenderer
|
||||
const remote = electron.remote
|
||||
const ace = window.ace
|
||||
|
||||
const OSX = global.process.platform === 'darwin'
|
||||
|
||||
export default class AppSettingTab extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
let keymap = Object.assign({}, remote.getGlobal('keymap'))
|
||||
let config = Object.assign({}, fetchConfig())
|
||||
let userName = props.user != null ? props.user.name : null
|
||||
|
||||
this.state = {
|
||||
user: {
|
||||
name: userName,
|
||||
alert: null
|
||||
},
|
||||
userAlert: null,
|
||||
keymap: keymap,
|
||||
keymapAlert: null,
|
||||
config: config,
|
||||
configAlert: null
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.handleSettingDone = () => {
|
||||
this.setState({keymapAlert: {
|
||||
type: 'success',
|
||||
message: 'Successfully done!'
|
||||
}})
|
||||
}
|
||||
this.handleSettingError = (err) => {
|
||||
this.setState({keymapAlert: {
|
||||
type: 'error',
|
||||
message: err.message != null ? err.message : 'Error occurs!'
|
||||
}})
|
||||
}
|
||||
ipc.addListener('APP_SETTING_DONE', this.handleSettingDone)
|
||||
ipc.addListener('APP_SETTING_ERROR', this.handleSettingError)
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
ipc.removeListener('APP_SETTING_DONE', this.handleSettingDone)
|
||||
ipc.removeListener('APP_SETTING_ERROR', this.handleSettingError)
|
||||
}
|
||||
|
||||
submitHotKey () {
|
||||
ipc.send('hotkeyUpdated', this.state.keymap)
|
||||
}
|
||||
|
||||
submitConfig () {
|
||||
ipc.send('configUpdated', this.state.config)
|
||||
}
|
||||
|
||||
handleSaveButtonClick (e) {
|
||||
this.submitHotKey()
|
||||
}
|
||||
|
||||
handleConfigSaveButtonClick (e) {
|
||||
this.submitConfig()
|
||||
}
|
||||
|
||||
handleKeyDown (e) {
|
||||
if (e.keyCode === 13) {
|
||||
this.submitHotKey()
|
||||
}
|
||||
}
|
||||
|
||||
handleConfigKeyDown (e) {
|
||||
if (e.keyCode === 13) {
|
||||
this.submitConfig()
|
||||
}
|
||||
}
|
||||
|
||||
handleLineNumberingClick (e) {
|
||||
let config = this.state.config
|
||||
|
||||
config['preview-line-number'] = e.target.checked
|
||||
this.setState({
|
||||
config
|
||||
})
|
||||
}
|
||||
|
||||
handleDisableDirectWriteClick (e) {
|
||||
let config = this.state.config
|
||||
config['disable-direct-write'] = e.target.checked
|
||||
this.setState({
|
||||
config
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
let keymapAlert = this.state.keymapAlert
|
||||
let keymapAlertElement = keymapAlert != null
|
||||
? <p className={`alert ${keymapAlert.type}`}>
|
||||
{keymapAlert.message}
|
||||
</p>
|
||||
: null
|
||||
let aceThemeList = ace.require('ace/ext/themelist')
|
||||
let hljsThemeList = hljsTheme()
|
||||
|
||||
return (
|
||||
<div className='AppSettingTab content'>
|
||||
<div className='section'>
|
||||
<div className='sectionTitle'>Editor</div>
|
||||
<div className='sectionInput'>
|
||||
<label>Editor Font Size</label>
|
||||
<input valueLink={this.linkState('config.editor-font-size')} onKeyDown={(e) => this.handleConfigKeyDown(e)} type='text'/>
|
||||
</div>
|
||||
<div className='sectionInput'>
|
||||
<label>Editor Font Family</label>
|
||||
<input valueLink={this.linkState('config.editor-font-family')} onKeyDown={(e) => this.handleConfigKeyDown(e)} type='text'/>
|
||||
</div>
|
||||
<div className='sectionMultiSelect'>
|
||||
<label>Editor Indent Style</label>
|
||||
<div className='sectionMultiSelect-input'>
|
||||
type
|
||||
<select valueLink={this.linkState('config.editor-indent-type')}>
|
||||
<option value='space'>Space</option>
|
||||
<option value='tab'>Tab</option>
|
||||
</select>
|
||||
size
|
||||
<select valueLink={this.linkState('config.editor-indent-size')}>
|
||||
<option value='2'>2</option>
|
||||
<option value='4'>4</option>
|
||||
<option value='8'>8</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className='sectionTitle'>Preview</div>
|
||||
<div className='sectionInput'>
|
||||
<label>Preview Font Size</label>
|
||||
<input valueLink={this.linkState('config.preview-font-size')} onKeyDown={(e) => this.handleConfigKeyDown(e)} type='text'/>
|
||||
</div>
|
||||
<div className='sectionInput'>
|
||||
<label>Preview Font Family</label>
|
||||
<input valueLink={this.linkState('config.preview-font-family')} onKeyDown={(e) => this.handleConfigKeyDown(e)} type='text'/>
|
||||
</div>
|
||||
<div className='sectionSelect'>
|
||||
<label>Switching Preview</label>
|
||||
<select valueLink={this.linkState('config.switch-preview')}>
|
||||
<option value='blur'>When Editor Blurred</option>
|
||||
<option value='rightclick'>When Right Clicking</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className='sectionCheck'>
|
||||
<label><input onChange={e => this.handleLineNumberingClick(e)} checked={this.state.config['preview-line-number']} type='checkbox'/>Code block line numbering</label>
|
||||
</div>
|
||||
{
|
||||
global.process.platform === 'win32'
|
||||
? (
|
||||
<div className='sectionCheck'>
|
||||
<label><input onChange={e => this.handleDisableDirectWriteClick(e)} checked={this.state.config['disable-direct-write']} disabled={OSX} type='checkbox'/>Disable Direct Write<span className='sectionCheck-warn'>It will be applied after restarting</span></label>
|
||||
</div>
|
||||
)
|
||||
: null
|
||||
}
|
||||
<div className='sectionTitle'>Theme</div>
|
||||
<div className='sectionSelect'>
|
||||
<label>UI Theme</label>
|
||||
<select valueLink={this.linkState('config.theme-ui')}>
|
||||
<option value='light'>Light</option>
|
||||
<option value='dark'>Dark</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className='sectionSelect'>
|
||||
<label>Code block Theme</label>
|
||||
<select valueLink={this.linkState('config.theme-code')}>
|
||||
{
|
||||
hljsThemeList.map((theme) => {
|
||||
return (<option value={theme.name} key={theme.name}>{theme.caption}</option>)
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div className='sectionSelect'>
|
||||
<label>Editor Theme</label>
|
||||
<select valueLink={this.linkState('config.theme-syntax')}>
|
||||
{
|
||||
aceThemeList.themes.map((theme) => {
|
||||
return (<option value={theme.name} key={theme.name}>{theme.caption}</option>)
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div className='sectionConfirm'>
|
||||
<button onClick={(e) => this.handleConfigSaveButtonClick(e)}>Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='section'>
|
||||
<div className='sectionTitle'>Hotkey</div>
|
||||
<div className='sectionInput'>
|
||||
<label>Toggle Main</label>
|
||||
<input onKeyDown={(e) => this.handleKeyDown(e)} valueLink={this.linkState('keymap.toggleMain')} type='text'/>
|
||||
</div>
|
||||
<div className='sectionInput'>
|
||||
<label>Toggle Finder(popup)</label>
|
||||
<input onKeyDown={(e) => this.handleKeyDown(e)} valueLink={this.linkState('keymap.toggleFinder')} type='text'/>
|
||||
</div>
|
||||
<div className='sectionConfirm'>
|
||||
<button onClick={(e) => this.handleSaveButtonClick(e)}>Save</button>
|
||||
{keymapAlertElement}
|
||||
</div>
|
||||
<div className='description'>
|
||||
<ul>
|
||||
<li><code>0</code> to <code>9</code></li>
|
||||
<li><code>A</code> to <code>Z</code></li>
|
||||
<li><code>F1</code> to <code>F24</code></li>
|
||||
<li>Punctuations like <code>~</code>, <code>!</code>, <code>@</code>, <code>#</code>, <code>$</code>, etc.</li>
|
||||
<li><code>Plus</code></li>
|
||||
<li><code>Space</code></li>
|
||||
<li><code>Backspace</code></li>
|
||||
<li><code>Delete</code></li>
|
||||
<li><code>Insert</code></li>
|
||||
<li><code>Return</code> (or <code>Enter</code> as alias)</li>
|
||||
<li><code>Up</code>, <code>Down</code>, <code>Left</code> and <code>Right</code></li>
|
||||
<li><code>Home</code> and <code>End</code></li>
|
||||
<li><code>PageUp</code> and <code>PageDown</code></li>
|
||||
<li><code>Escape</code> (or <code>Esc</code> for short)</li>
|
||||
<li><code>VolumeUp</code>, <code>VolumeDown</code> and <code>VolumeMute</code></li>
|
||||
<li><code>MediaNextTrack</code>, <code>MediaPreviousTrack</code>, <code>MediaStop</code> and <code>MediaPlayPause</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
AppSettingTab.prototype.linkState = linkState
|
||||
AppSettingTab.propTypes = {
|
||||
user: PropTypes.shape({
|
||||
name: PropTypes.string
|
||||
}),
|
||||
dispatch: PropTypes.func
|
||||
}
|
||||
24
browser/main/modals/Preferences/ContactTab.js
Normal file
24
browser/main/modals/Preferences/ContactTab.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import linkState from 'browser/lib/linkState'
|
||||
import ExternalLink from 'browser/components/ExternalLink'
|
||||
|
||||
export default class ContactTab extends React.Component {
|
||||
componentDidMount () {
|
||||
let titleInput = ReactDOM.findDOMNode(this.refs.title)
|
||||
if (titleInput != null) titleInput.focus()
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='ContactTab content'>
|
||||
<div className='title'>Contact</div>
|
||||
<p>
|
||||
- Issues: <ExternalLink href='https://github.com/BoostIO/Boostnote/issues'>https://github.com/BoostIO/Boostnote/issues</ExternalLink>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ContactTab.prototype.linkState = linkState
|
||||
97
browser/main/modals/Preferences/index.js
Normal file
97
browser/main/modals/Preferences/index.js
Normal file
@@ -0,0 +1,97 @@
|
||||
import React, { PropTypes } from 'react'
|
||||
import { connect, Provider } from 'react-redux'
|
||||
import linkState from 'browser/lib/linkState'
|
||||
import store from 'browser/main/store'
|
||||
import AppSettingTab from './AppSettingTab'
|
||||
import ContactTab from './ContactTab'
|
||||
import { closeModal } from 'browser/lib/modal'
|
||||
|
||||
const APP = 'APP'
|
||||
const CONTACT = 'CONTACT'
|
||||
|
||||
class Preferences extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
currentTab: APP
|
||||
}
|
||||
}
|
||||
|
||||
switchTeam (teamId) {
|
||||
this.setState({currentTeamId: teamId})
|
||||
}
|
||||
|
||||
handleNavButtonClick (tab) {
|
||||
return (e) => {
|
||||
this.setState({currentTab: tab})
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
let content = this.renderContent()
|
||||
|
||||
let tabs = [
|
||||
{target: APP, label: 'Preferences'},
|
||||
{target: CONTACT, label: 'Contact'}
|
||||
]
|
||||
|
||||
let navButtons = tabs.map((tab) => (
|
||||
<button key={tab.target} onClick={(e) => this.handleNavButtonClick(tab.target)(e)} className={this.state.currentTab === tab.target ? 'active' : ''}>{tab.label}</button>
|
||||
))
|
||||
|
||||
return (
|
||||
<div className='Preferences modal'>
|
||||
<div className='header'>
|
||||
<div className='title'>Setting</div>
|
||||
<button onClick={(e) => closeModal()} className='closeBtn'>Done</button>
|
||||
</div>
|
||||
|
||||
<div className='nav'>
|
||||
{navButtons}
|
||||
</div>
|
||||
|
||||
{content}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderContent () {
|
||||
let { user, dispatch } = this.props
|
||||
|
||||
switch (this.state.currentTab) {
|
||||
case CONTACT:
|
||||
return (
|
||||
<ContactTab/>
|
||||
)
|
||||
case APP:
|
||||
default:
|
||||
return (
|
||||
<AppSettingTab
|
||||
user={user}
|
||||
dispatch={dispatch}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Preferences.propTypes = {
|
||||
user: PropTypes.shape({
|
||||
name: PropTypes.string
|
||||
}),
|
||||
dispatch: PropTypes.func
|
||||
}
|
||||
|
||||
Preferences.prototype.linkState = linkState
|
||||
|
||||
let RootComponent = connect((x) => x)(Preferences)
|
||||
export default class PreferencesModal extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<RootComponent/>
|
||||
</Provider>
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user