1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 09:46:22 +00:00

add planet create modal & switching func

This commit is contained in:
Rokt33r
2015-07-21 12:02:40 +09:00
parent 864001bdff
commit 72a08e8fec
9 changed files with 217 additions and 138 deletions

View File

@@ -1,6 +1,7 @@
var Reflux = require('reflux')
module.exports = Reflux.createActions([
'createPlanet',
'fetchPlanet',
'createSnippet',

View File

@@ -1,6 +1,8 @@
var React = require('react/addons')
var Catalyst = require('../Mixins/Catalyst')
var PlanetActions = require('../Actions/PlanetActions')
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
@@ -13,16 +15,39 @@ module.exports = React.createClass({
planetName: ''
}
},
componentDidMount: function () {
React.findDOMNode(this.refs.name).focus()
this.unsubscribe = PlanetStore.listen(this.onListen)
},
componentWillUnmount: function () {
this.unsubscribe()
},
onListen: function (res) {
if (res.status === 'planetCreated') {
this.props.close()
}
},
handleSubmit: function () {
console.log(this.state.planetName)
PlanetActions.createPlanet({
name: this.state.planetName
})
},
handleKeyDown: function (e) {
if (e.keyCode === 13 && e.metaKey) {
this.handleSubmit()
return
}
if (e.keyCode === 27) {
this.props.close()
}
},
stopPropagation: function (e) {
e.stopPropagation()
},
render: function () {
return (
<div onClick={this.stopPropagation} className='PlanetCreateModal modal'>
<input valueLink={this.linkState('planetName')} className='stripInput'/>
<div tabIndex='3' onKeyDown={this.handleKeyDown} onClick={this.stopPropagation} className='PlanetCreateModal modal'>
<input ref='name' valueLink={this.linkState('planetName')} className='nameInput stripInput' placeholder='Crate new Planet'/>
<button onClick={this.handleSubmit} className='submitButton'>
<i className='fa fa-check'/>
</button>

View File

@@ -18,11 +18,6 @@ var PlanetHeader = React.createClass({
interceptClick: function (e) {
e.stopPropagation()
},
handleKeyDown: function (e) {
if (e.keyCode === 27) {
React.findDOMNode(this.refs.search).blur()
}
},
render: function () {
var currentPlanetName = this.props.currentPlanet.name
var currentUserName = this.props.currentUser.name
@@ -39,7 +34,7 @@ var PlanetHeader = React.createClass({
<div className='headerControl'>
<span className='searchInput'>
<i className='fa fa-search'/>
<input onKeyDown={this.handleKeyDown} onChange={this.props.onSearchChange} value={this.props.search} ref='search' tabIndex='1' type='text' className='inline-input circleInput' placeholder='Search...'/>
<input onChange={this.props.onSearchChange} value={this.props.search} ref='search' tabIndex='1' type='text' className='inline-input circleInput' placeholder='Search...'/>
</span>
<a className='downloadButtton btn-primary'>Download Mac app</a>
</div>

View File

@@ -63,11 +63,14 @@ module.exports = React.createClass({
this.unsubscribe = PlanetStore.listen(this.onFetched)
PlanetActions.fetchPlanet(this.props.params.userName + '/' + this.props.params.planetName)
document.addEventListener('keydown', this.handleKeyDown)
},
componentWillUnmount: function () {
this.unsubscribe()
document.removeEventListener('keydown', this.handleKeyDown)
},
componentDidUpdate: function () {
if (this.state.currentPlanet.planetName !== this.props.params.planetName) {
PlanetActions.fetchPlanet(this.props.params.userName + '/' + this.props.params.planetName)
}
},
getFilteredIndexOfCurrentArticle: function () {
var params = this.props.params
@@ -164,7 +167,19 @@ module.exports = React.createClass({
if (this.refs.detail.props.article == null) {
var params = this.props.params
delete params.localId
this.transitionTo('planetHome', params)
var articles = this.refs.list.props.articles
if (articles.length > 0) {
console.log('need to redirect', this.refs.list.props.articles)
var article = articles[0]
params.localId = article.localId
if (article.type === 'snippet') {
this.transitionTo('snippets', params)
} else {
this.transitionTo('blueprints', params)
}
}
}
})
return
@@ -234,18 +249,31 @@ module.exports = React.createClass({
submitDeleteModal: function () {
this.setState({isDeleteModalOpen: false})
},
focus: function () {
React.findDOMNode(this).focus()
console.log('focus this')
},
handleKeyDown: function (e) {
// Bypath for modal open state
if (this.state.isLaunchModalOpen) {
if (e.keyCode === 27) this.closeLaunchModal()
if (e.keyCode === 27) {
this.closeLaunchModal()
this.focus()
}
return
}
if (this.state.isEditModalOpen) {
if (e.keyCode === 27) this.closeEditModal()
if (e.keyCode === 27) {
this.closeEditModal()
this.focus()
}
return
}
if (this.state.isDeleteModalOpen) {
if (e.keyCode === 27) this.closeDeleteModal()
if (e.keyCode === 27) {
this.closeDeleteModal()
this.focus()
}
return
}
@@ -259,17 +287,18 @@ module.exports = React.createClass({
var searchInput = React.findDOMNode(this).querySelector('.PlanetHeader .searchInput input')
if (document.activeElement === searchInput) {
console.log('fff', e.keyCode)
switch (e.keyCode) {
case 38:
searchInput.blur()
this.focus()
break
case 40:
e.preventDefault()
searchInput.blur()
this.focus()
break
case 27:
e.preventDefault()
searchInput.blur()
this.focus()
break
}
return
@@ -349,7 +378,7 @@ module.exports = React.createClass({
)) : null
return (
<div className='PlanetContainer'>
<div tabIndex='1' onKeyDown={this.handleKeyDown} className='PlanetContainer'>
<ModalBase isOpen={this.state.isLaunchModalOpen} close={this.closeLaunchModal}>
<LaunchModal submit={this.submitLaunchModal} close={this.closeLaunchModal}/>
</ModalBase>

View File

@@ -1,54 +1,12 @@
/* global localStorage */
var React = require('react/addons')
var ReactRouter = require('react-router')
var Link = ReactRouter.Link
var RouteHandler = ReactRouter.RouteHandler
var UserNavigator = require('../Components/UserNavigator')
var AuthStore = require('../Stores/AuthStore')
var UserNavigator = React.createClass({
mixins: [ReactRouter.Navigation],
propTypes: {
currentPlanet: React.PropTypes.object,
currentUser: React.PropTypes.object
},
componentDidMount: function () {
this.unsubscribe = AuthStore.listen(this.onLogout)
},
componentWillUnmount: function () {
this.unsubscribe()
},
onLogout: function () {
this.transitionTo('login')
},
render: function () {
var planets = this.props.currentUser.Planets.map(function (planet, index) {
return (
<li key={planet.id} className={this.props.currentPlanet != null && this.props.currentPlanet.name === planet.name ? 'active' : ''}>
<Link to='planet' params={{userName: this.props.currentUser.name, planetName: planet.name}} href>{planet.name[0]}</Link>
<div className='shortCut'>{index + 1}</div>
</li>
)
}.bind(this))
if (this.props.currentUser == null) {
return (
<div className='UserNavigator'>
</div>
)
}
return (
<div className='UserNavigator'>
<Link to='userHome' params={{userName: this.props.currentUser.name}} className='userConfig'>
<img width='50' height='50' src='../vendor/dummy.jpg'/>
</Link>
<ul>
{planets}
</ul>
<button className='newPlanet'><i className='fa fa-plus'/></button>
</div>
)
}
})
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
mixins: [React.addons.LinkedStateMixin, ReactRouter.Navigation],
@@ -57,9 +15,29 @@ module.exports = React.createClass({
planetName: React.PropTypes.string
})
},
getInitialState: function () {
return {
currentUser: AuthStore.getUser()
}
},
componentDidMount: function () {
this.unsubscribe = PlanetStore.listen(this.onListen)
},
componentWillUnmount: function () {
this.unsubscribe()
},
onListen: function (res) {
if (res.status === 'planetCreated') {
var currentUser = this.state.currentUser
currentUser.Planets.push(res.data)
localStorage.setItem('user', JSON.stringify(currentUser))
this.setState({currentUser: currentUser})
}
},
render: function () {
var currentPlanetName = this.props.params.planetName
var currentUser = AuthStore.getUser()
var currentUser = this.state.currentUser
// user must be logged in
if (currentUser == null) return (<div></div>)

View File

@@ -8,6 +8,7 @@ var apiUrl = 'http://localhost:8000/'
var PlanetStore = Reflux.createStore({
init: function () {
this.listenTo(PlanetActions.createPlanet, this.createPlanet)
this.listenTo(PlanetActions.fetchPlanet, this.fetchPlanet)
this.listenTo(PlanetActions.createSnippet, this.createSnippet)
this.listenTo(PlanetActions.updateSnippet, this.updateSnippet)
@@ -16,6 +17,31 @@ var PlanetStore = Reflux.createStore({
this.listenTo(PlanetActions.updateBlueprint, this.updateBlueprint)
this.listenTo(PlanetActions.deleteBlueprint, this.deleteBlueprint)
},
createPlanet: function (input) {
request
.post(apiUrl + 'planets/create')
.set({
Authorization: 'Bearer ' + localStorage.getItem('token')
})
.send(input)
.end(function (err, res) {
if (err) {
console.error(err)
this.trigger(null)
return
}
var planet = res.body
planet.Snippets = []
planet.Blueprints = []
planet.Articles = []
this.trigger({
status: 'planetCreated',
data: planet
})
}.bind(this))
},
fetchPlanet: function (planetName) {
request
.get(apiUrl + planetName)

View File

@@ -0,0 +1,95 @@
.UserContainer
.UserNavigator
background-color planetNavBgColor
absolute left top bottom
width 50px
text-align center
box-sizing border-box
a.userConfig
display block
width 50px
height 50px
background-color black
img
transition 0.1s
opacity 0.6
box-sizing border-box
&.active, &:active, &.focus, &:focus, &.hover, &:hover
img
opacity 1
ul>li
padding 10px 3px
.shortCut
margin-top 5px
color lighten(textColor, 5%)
font-size 0.8em
&.active
a
background-color planetAnchorActiveBgColor
color planetAnchorActiveColor
a
display block
width 44px
height 44px
text-align center
background-color planetAnchorBgColor
text-decoration none
color planetAnchorColor
line-height 44px
font-size 1.1em
cursor pointer
circle()
transition 0.1s
&:hover, &:active
background-color white
img
circle()
width 44px
height 44px
button.newPlanet
display block
margin 0 auto
width 30px
height 30px
circle()
border solid 1px lightButtonColor
color lightButtonColor
text-align center
font-size 1
background-image none
background-color transparent
box-sizing border-box
absolute left bottom right
bottom 15px
&:hover, &.hover, &:focus, &.focus
border-color darken(lightButtonColor, 50%)
color darken(lightButtonColor, 50%)
&:active, &.active
border-color darken(brandBorderColor, 10%)
background-color brandColor
color white
.PlanetCreateModal.modal
padding 60px 0
.nameInput
width 80%
font-size 1.3em
margin 35px auto
text-align center
.submitButton
display block
margin 0 auto
box-sizing border-box
width 55px
height 55px
border-style solid
border-width 1px
circle()
border-color brandBorderColor
background-color transparent
color brandColor
&:hover, &.hover, &:focus, &.focus
border-color darken(brandBorderColor, 30%)
color darken(brandColor, 30%)
&:active, &.active
background-color brandColor
color white

View File

@@ -90,77 +90,7 @@ textarea.block-input
resize vertical
height 125px
border-radius 5px
padding 0 10px
padding 5px 10px
#content
fullsize()
.UserNavigator
background-color planetNavBgColor
absolute left top bottom
width 50px
text-align center
box-sizing border-box
a.userConfig
display block
width 50px
height 50px
background-color black
img
transition 0.1s
opacity 0.6
box-sizing border-box
&.active, &:active, &.focus, &:focus, &.hover, &:hover
img
opacity 1
ul>li
padding 10px 3px
.shortCut
margin-top 5px
color lighten(textColor, 5%)
font-size 0.8em
&.active
a
background-color planetAnchorActiveBgColor
color planetAnchorActiveColor
a
display block
width 44px
height 44px
text-align center
background-color planetAnchorBgColor
text-decoration none
color planetAnchorColor
line-height 44px
font-size 1.1em
cursor pointer
circle()
transition 0.1s
&:hover, &:active
background-color white
img
circle()
width 44px
height 44px
button.newPlanet
display block
margin 0 auto
width 30px
height 30px
circle()
border solid 2px lightButtonColor
color lightButtonColor
text-align center
font-size 1
background-image none
background-color transparent
box-sizing border-box
absolute left bottom right
bottom 15px
&:hover, &.hover, &:focus, &.focus
border-color darken(lightButtonColor, 25%)
color darken(lightButtonColor, 25%)
&:active, &.active
border-color darken(brandBorderColor, 10%)
background-color brandColor
color white

View File

@@ -9,7 +9,7 @@
display none
.modal
width 500px
margin 25px auto 0
margin 50px auto 0
absolute top left right
background-color white
border-radius 10px