mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
add Article detail
This commit is contained in:
5
browser/main/Actions/fetchPlanet.js
Normal file
5
browser/main/Actions/fetchPlanet.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
var Reflux = require('reflux')
|
||||||
|
|
||||||
|
var fetchPlanet = Reflux.createAction()
|
||||||
|
|
||||||
|
module.exports = fetchPlanet
|
||||||
0
browser/main/Actions/fetchSnippets.js
Normal file
0
browser/main/Actions/fetchSnippets.js
Normal file
@@ -1,6 +0,0 @@
|
|||||||
var Reflux = require('reflux')
|
|
||||||
|
|
||||||
// Creating an Action
|
|
||||||
var snippetUpdate = Reflux.createAction()
|
|
||||||
|
|
||||||
module.exports = snippetUpdate
|
|
||||||
6
browser/main/Actions/updateSnippet.js
Normal file
6
browser/main/Actions/updateSnippet.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
var Reflux = require('reflux')
|
||||||
|
|
||||||
|
// Creating an Action
|
||||||
|
var updateSnippet = Reflux.createAction()
|
||||||
|
|
||||||
|
module.exports = updateSnippet
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
/* global localStorage */
|
|
||||||
var React = require('react/addons')
|
var React = require('react/addons')
|
||||||
var ReactRouter = require('react-router')
|
var ReactRouter = require('react-router')
|
||||||
var Link = ReactRouter.Link
|
var Link = ReactRouter.Link
|
||||||
@@ -35,7 +34,7 @@ module.exports = React.createClass({
|
|||||||
this.transitionTo('user', {userName: user.name})
|
this.transitionTo('user', {userName: user.name})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.transitionTo('dashboard', {userName: user.name, planetName: planet.name})
|
this.transitionTo('planetHome', {userName: user.name, planetName: planet.name})
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,33 +1,14 @@
|
|||||||
var React = require('react/addons')
|
var React = require('react/addons')
|
||||||
var RouteHandler = require('react-router').RouteHandler
|
var RouteHandler = require('react-router').RouteHandler
|
||||||
var ReactRouter = require('react-router')
|
var ReactRouter = require('react-router')
|
||||||
var Link = ReactRouter.Link
|
|
||||||
var ModalBase = require('../Components/ModalBase')
|
var ModalBase = require('../Components/ModalBase')
|
||||||
var LaunchModal = require('../Components/LaunchModal')
|
var LaunchModal = require('../Components/LaunchModal')
|
||||||
|
var CodeViewer = require('../Components/CodeViewer')
|
||||||
|
|
||||||
var currentUser = {
|
var AuthStore = require('../Stores/AuthStore')
|
||||||
name: 'testcat',
|
var PlanetStore = require('../Stores/PlanetStore')
|
||||||
email: 'testcat@example.com',
|
|
||||||
profileName: 'Test Cat'
|
|
||||||
}
|
|
||||||
|
|
||||||
var userPlanets = [
|
var fetchPlanet = require('../Actions/fetchPlanet')
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: 'myplanet',
|
|
||||||
profileName: 'TestCat'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'group1',
|
|
||||||
profileName: 'Some Group#1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: 'group2',
|
|
||||||
profileName: 'Some Group#1'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
var PlanetHeader = React.createClass({
|
var PlanetHeader = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
@@ -76,24 +57,7 @@ var PlanetHeader = React.createClass({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
var PlanetNavigator = React.createClass({
|
||||||
var PlanetMain = React.createClass({
|
|
||||||
propTypes: {
|
|
||||||
currentPlanet: React.PropTypes.object,
|
|
||||||
currentUser: React.PropTypes.object
|
|
||||||
},
|
|
||||||
render: function () {
|
|
||||||
return (
|
|
||||||
<div className='PlanetMain'>
|
|
||||||
<PlanetHeader currentPlanet={this.props.currentPlanet} currentUser={this.props.currentUser}/>
|
|
||||||
<SideNavigator currentPlanet={this.props.currentPlanet} currentUser={this.props.currentUser}/>
|
|
||||||
<PlanetBody currentPlanet={this.props.currentPlanet}/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
var SideNavigator = React.createClass({
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentPlanet: React.PropTypes.shape({
|
currentPlanet: React.PropTypes.shape({
|
||||||
name: React.PropTypes.string
|
name: React.PropTypes.string
|
||||||
@@ -119,11 +83,8 @@ var SideNavigator = React.createClass({
|
|||||||
this.setState({isLaunchModalOpen: false})
|
this.setState({isLaunchModalOpen: false})
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var currentPlanetName = this.props.currentPlanet.name
|
|
||||||
var currentUserName = this.props.currentUser.name
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='SideNavigator'>
|
<div className='PlanetNavigator'>
|
||||||
<button onClick={this.openLaunchModal} className='btn-primary btn-block'>
|
<button onClick={this.openLaunchModal} className='btn-primary btn-block'>
|
||||||
<i className='fa fa-rocket fa-fw'/> Launch
|
<i className='fa fa-rocket fa-fw'/> Launch
|
||||||
</button>
|
</button>
|
||||||
@@ -131,60 +92,159 @@ var SideNavigator = React.createClass({
|
|||||||
<LaunchModal submit={this.submitLaunchModal} close={this.closeLaunchModal}/>
|
<LaunchModal submit={this.submitLaunchModal} close={this.closeLaunchModal}/>
|
||||||
</ModalBase>
|
</ModalBase>
|
||||||
<nav>
|
<nav>
|
||||||
<Link to='dashboard' params={{userName: currentUserName, planetName: currentPlanetName}}>
|
<a>
|
||||||
<i className='fa fa-home fa-fw'/> Home
|
<i className='fa fa-home fa-fw'/> Home
|
||||||
</Link>
|
</a>
|
||||||
<Link to='snippets' params={{userName: currentUserName, planetName: currentPlanetName}}>
|
<a>
|
||||||
<i className='fa fa-code fa-fw'/> Snippets
|
<i className='fa fa-code fa-fw'/> Snippets
|
||||||
</Link>
|
</a>
|
||||||
<Link to='blueprint' params={{userName: currentUserName, planetName: currentPlanetName}}>
|
<a>
|
||||||
<i className='fa fa-file-text-o fa-fw'/> Blueprints
|
<i className='fa fa-file-text-o fa-fw'/> Blueprints
|
||||||
</Link>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
var PlanetBody = React.createClass({
|
var PlanetArticleList = React.createClass({
|
||||||
|
mixins: [ReactRouter.Navigation, ReactRouter.State],
|
||||||
|
propTypes: {
|
||||||
|
planet: React.PropTypes.shape({
|
||||||
|
Snippets: React.PropTypes.array,
|
||||||
|
Blueprints: React.PropTypes.array
|
||||||
|
})
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
|
var articles = this.props.planet.Snippets.map(function (snippet) {
|
||||||
|
var tags = snippet.Tags.map(function (tag) {
|
||||||
return (
|
return (
|
||||||
<div className='PlanetBody'>
|
<a key={tag.id} href>#{tag.name}</a>
|
||||||
<RouteHandler/>
|
)
|
||||||
|
})
|
||||||
|
var params = this.getParams()
|
||||||
|
|
||||||
|
var isActive = parseInt(params.localId, 10) === snippet.localId
|
||||||
|
|
||||||
|
var handleClick = function () {
|
||||||
|
this.transitionTo('snippets', {
|
||||||
|
userName: params.userName,
|
||||||
|
planetName: params.planetName,
|
||||||
|
localId: snippet.localId
|
||||||
|
})
|
||||||
|
}.bind(this)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li onClick={handleClick} className={isActive ? 'active' : ''} key={snippet.id}>
|
||||||
|
<div className='callSign'><i className='fa fa-code'></i> {snippet.callSign}</div>
|
||||||
|
<div className='description'>{snippet.description}</div>
|
||||||
|
<div className='updatedAt'>{snippet.updatedAt}</div>
|
||||||
|
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
}.bind(this))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='PlanetArticleList'>
|
||||||
|
<ul>
|
||||||
|
{articles}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var PlanetArticleDetail = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
snippet: React.PropTypes.object
|
||||||
|
},
|
||||||
|
render: function () {
|
||||||
|
var snippet = this.props.snippet
|
||||||
|
|
||||||
|
var tags = snippet.Tags.map(function (tag) {
|
||||||
|
return (
|
||||||
|
<a key={tag.id} href>#{tag.name}</a>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='PlanetArticleDetail'>
|
||||||
|
<div className='viewer-header'>
|
||||||
|
<i className='fa fa-code'></i> {snippet.callSign} <small className='updatedAt'>{snippet.updatedAt}</small>
|
||||||
|
<span className='control-group'>
|
||||||
|
<button className='btn-default btn-square btn-sm'><i className='fa fa-edit fa-fw'></i></button>
|
||||||
|
<button className='btn-default btn-square btn-sm'><i className='fa fa-trash fa-fw'></i></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className='viewer-body'>
|
||||||
|
<div className='viewer-detail'>
|
||||||
|
<div className='description'>{snippet.description}</div>
|
||||||
|
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
||||||
|
</div>
|
||||||
|
<div className='content'>
|
||||||
|
<CodeViewer code={snippet.content} mode={snippet.mode}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [ReactRouter.Navigation],
|
mixins: [ReactRouter.Navigation, ReactRouter.State],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
params: React.PropTypes.object,
|
params: React.PropTypes.object,
|
||||||
planetName: React.PropTypes.string
|
planetName: React.PropTypes.string
|
||||||
},
|
},
|
||||||
|
getInitialState: function () {
|
||||||
|
return {
|
||||||
|
currentPlanet: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
componentDidMount: function () {
|
||||||
|
this.unsubscribe = PlanetStore.listen(this.onFetched)
|
||||||
|
|
||||||
|
fetchPlanet(this.props.params.userName + '/' + this.props.params.planetName)
|
||||||
|
},
|
||||||
|
componentWillUnmount: function () {
|
||||||
|
this.unsubscribe()
|
||||||
|
},
|
||||||
|
onFetched: function (planet) {
|
||||||
|
this.setState({currentPlanet: planet}, function () {
|
||||||
|
if (planet.Snippets.length > 0) {
|
||||||
|
this.transitionTo('snippets', {
|
||||||
|
userName: this.props.params.userName,
|
||||||
|
planetName: this.props.params.planetName,
|
||||||
|
localId: planet.Snippets[0].localId})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var currentPlanetName = this.props.params.planetName
|
var user = AuthStore.getUser()
|
||||||
var currentPlanet = null
|
if (user == null) return (<div/>)
|
||||||
userPlanets.some(function (planet) {
|
if (this.state.currentPlanet == null) return (<div/>)
|
||||||
if (planet.name === currentPlanetName) {
|
|
||||||
currentPlanet = planet
|
var content = (<div>No selected</div>)
|
||||||
|
if (this.isActive('snippets')) {
|
||||||
|
var localId = parseInt(this.props.params.localId, 10)
|
||||||
|
|
||||||
|
this.state.currentPlanet.Snippets.some(function (_snippet) {
|
||||||
|
if (localId === _snippet.localId) {
|
||||||
|
content = (
|
||||||
|
<PlanetArticleDetail snippet={_snippet}/>
|
||||||
|
)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
if (currentPlanet == null) {
|
|
||||||
var redirectTo = userPlanets[0].name
|
|
||||||
this.transitionTo('planet', {planetName: redirectTo})
|
|
||||||
return (
|
|
||||||
<div className='PlanetContainer'>
|
|
||||||
Redirecting...
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='PlanetContainer'>
|
<div className='PlanetContainer'>
|
||||||
<PlanetMain currentPlanet={currentPlanet} currentUser={currentUser}/>
|
<PlanetHeader currentPlanet={this.state.currentPlanet} currentUser={user}/>
|
||||||
|
<PlanetNavigator currentPlanet={this.state.currentPlanet} currentUser={user}/>
|
||||||
|
<PlanetArticleList planet={this.state.currentPlanet}/>
|
||||||
|
{content}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ module.exports = React.createClass({
|
|||||||
this.transitionTo('user', {userName: user.name})
|
this.transitionTo('user', {userName: user.name})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.transitionTo('dashboard', {userName: user.name, planetName: planet.name})
|
this.transitionTo('planetHome', {userName: user.name, planetName: planet.name})
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,169 +0,0 @@
|
|||||||
var React = require('react/addons')
|
|
||||||
var Snippet = require('../Services/Snippet')
|
|
||||||
var CodeViewer = require('../Components/CodeViewer')
|
|
||||||
|
|
||||||
var SnippetList = React.createClass({
|
|
||||||
propTypes: {
|
|
||||||
snippets: React.PropTypes.array,
|
|
||||||
selectSnippet: React.PropTypes.func,
|
|
||||||
currentSnippet: React.PropTypes.object
|
|
||||||
},
|
|
||||||
itemClickHandlerFactory: function (snippet) {
|
|
||||||
return function () {
|
|
||||||
this.props.selectSnippet(snippet)
|
|
||||||
}.bind(this)
|
|
||||||
},
|
|
||||||
render: function () {
|
|
||||||
var snippets = this.props.snippets.map(function (snippet) {
|
|
||||||
var tags = snippet.Tags.map(function (tag) {
|
|
||||||
return (
|
|
||||||
<a key={tag.id} href>#{tag.name}</a>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
return (
|
|
||||||
<li className={this.props.currentSnippet.id === snippet.id ? 'active' : ''} key={snippet.id} onClick={this.itemClickHandlerFactory(snippet)}>
|
|
||||||
<div className='callSign'><i className='fa fa-code'></i> {snippet.callSign}</div>
|
|
||||||
<div className='description'>{snippet.description}</div>
|
|
||||||
<div className='updatedAt'>{snippet.updatedAt}</div>
|
|
||||||
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
|
||||||
</li>
|
|
||||||
)
|
|
||||||
}.bind(this))
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='SnippetList'>
|
|
||||||
<ul>
|
|
||||||
{snippets}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
var SnippetViewer = React.createClass({
|
|
||||||
propTypes: {
|
|
||||||
snippet: React.PropTypes.object
|
|
||||||
},
|
|
||||||
render: function () {
|
|
||||||
var snippet = this.props.snippet
|
|
||||||
var content
|
|
||||||
if (snippet != null) {
|
|
||||||
var tags = snippet.Tags.map(function (tag) {
|
|
||||||
return (
|
|
||||||
<a key={tag.id} href>#{tag.name}</a>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
content = (
|
|
||||||
<div className='SnippetViewer'>
|
|
||||||
<div className='viewer-header'>
|
|
||||||
<i className='fa fa-code'></i> {snippet.callSign} <small className='updatedAt'>{snippet.updatedAt}</small>
|
|
||||||
<span className='control-group'>
|
|
||||||
<button className='btn-default btn-square btn-sm'><i className='fa fa-edit fa-fw'></i></button>
|
|
||||||
<button className='btn-default btn-square btn-sm'><i className='fa fa-trash fa-fw'></i></button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className='viewer-body'>
|
|
||||||
<div className='viewer-detail'>
|
|
||||||
<div className='description'>{snippet.description}</div>
|
|
||||||
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
|
||||||
</div>
|
|
||||||
<div className='content'>
|
|
||||||
<CodeViewer code={snippet.content} mode={snippet.mode}/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
content = (
|
|
||||||
<div className='SnippetViewer'>
|
|
||||||
Not selected
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return content
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
var SnippetContainer = React.createClass({
|
|
||||||
propTypes: {
|
|
||||||
params: React.PropTypes.shape({
|
|
||||||
planetName: React.PropTypes.string
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getInitialState: function () {
|
|
||||||
return {
|
|
||||||
snippets: [],
|
|
||||||
curentSnippet: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
componentDidMount: function () {
|
|
||||||
Snippet.getByPlanet(this.props.params.planetName)
|
|
||||||
.then(function (snippets) {
|
|
||||||
this.setSnippets(snippets, snippets.length > 0 ? snippets[0] : null)
|
|
||||||
}.bind(this))
|
|
||||||
},
|
|
||||||
setSnippets: function (snippets, currentSnippet) {
|
|
||||||
this.setState({snippets: snippets, currentSnippet: currentSnippet})
|
|
||||||
},
|
|
||||||
selectSnippet: function (snippet) {
|
|
||||||
this.setState({currentSnippet: snippet})
|
|
||||||
},
|
|
||||||
updateSnippet: function (snippet) {
|
|
||||||
var snippets = this.state.snippets.map(function (_snippet) {
|
|
||||||
if (snippet.id === _snippet.id) {
|
|
||||||
return snippet
|
|
||||||
}
|
|
||||||
return _snippet
|
|
||||||
})
|
|
||||||
var currentSnippet = this.state.currentSnippet.id === snippet.id ? snippet : this.state.currentSnippet
|
|
||||||
|
|
||||||
this.setState({snippets: snippets, currentSnippet: currentSnippet})
|
|
||||||
},
|
|
||||||
destroySnippet: function (snippet) {
|
|
||||||
var snippets = this.state.snippets
|
|
||||||
var currentSnippet = this.state.currentSnippet
|
|
||||||
if (currentSnippet.id === snippet.id) {
|
|
||||||
var index
|
|
||||||
snippets.some(function (_snippet, _index) {
|
|
||||||
if (snippet.id === _snippet.id) {
|
|
||||||
index = _index
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (index == null) {
|
|
||||||
index = 0
|
|
||||||
} else if (index > snippet.length - 1) {
|
|
||||||
index--
|
|
||||||
} else {
|
|
||||||
index++
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snippets.length > 0) {
|
|
||||||
currentSnippet = snippets[index]
|
|
||||||
} else {
|
|
||||||
currentSnippet = {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
snippets = snippets.filter(function (_snippet, index) {
|
|
||||||
if (snippet.id === _snippet.id) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
this.setState({snippets: snippets, currentSnippet: currentSnippet})
|
|
||||||
},
|
|
||||||
render: function () {
|
|
||||||
return (
|
|
||||||
<div className='SnippetContainer'>
|
|
||||||
<SnippetList selectSnippet={this.selectSnippet} snippets={this.state.snippets} currentSnippet={this.state.currentSnippet}/>
|
|
||||||
<SnippetViewer snippet={this.state.currentSnippet}/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
module.exports = SnippetContainer
|
|
||||||
@@ -3,30 +3,7 @@ var ReactRouter = require('react-router')
|
|||||||
var Link = ReactRouter.Link
|
var Link = ReactRouter.Link
|
||||||
var RouteHandler = ReactRouter.RouteHandler
|
var RouteHandler = ReactRouter.RouteHandler
|
||||||
|
|
||||||
// Dummy
|
var AuthStore = require('../Stores/AuthStore')
|
||||||
var currentUser = {
|
|
||||||
name: 'testcat',
|
|
||||||
email: 'testcat@example.com',
|
|
||||||
profileName: 'Test Cat'
|
|
||||||
}
|
|
||||||
|
|
||||||
var userPlanets = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: 'testcat',
|
|
||||||
profileName: 'TestCat'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'group1',
|
|
||||||
profileName: 'Some Group#1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: 'group2',
|
|
||||||
profileName: 'Some Group#1'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
var UserNavigator = React.createClass({
|
var UserNavigator = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
@@ -34,10 +11,10 @@ var UserNavigator = React.createClass({
|
|||||||
currentUser: React.PropTypes.object
|
currentUser: React.PropTypes.object
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var planets = userPlanets.map(function (planet, index) {
|
var planets = this.props.currentUser.Planets.map(function (planet, index) {
|
||||||
return (
|
return (
|
||||||
<li key={planet.id} className={this.props.currentPlanet != null && this.props.currentPlanet.name === planet.name ? 'active' : ''}>
|
<li key={planet.id} className={this.props.currentPlanet != null && this.props.currentPlanet.name === planet.name ? 'active' : ''}>
|
||||||
<a href>{planet.profileName[0]}</a>
|
<Link to='planet' params={{userName: this.props.currentUser.name, planetName: planet.name}} href>{planet.name[0]}</Link>
|
||||||
<div className='shortCut'>⌘{index + 1}</div>
|
<div className='shortCut'>⌘{index + 1}</div>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
@@ -65,10 +42,16 @@ var UserNavigator = React.createClass({
|
|||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [React.addons.LinkedStateMixin, ReactRouter.Navigation],
|
mixins: [React.addons.LinkedStateMixin, ReactRouter.Navigation],
|
||||||
|
propTypes: {
|
||||||
|
params: React.PropTypes.shape({
|
||||||
|
planetName: React.PropTypes.string
|
||||||
|
})
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var currentPlanetName = this.props.params.planetName
|
var currentPlanetName = this.props.params.planetName
|
||||||
|
var currentUser = AuthStore.getUser()
|
||||||
var currentPlanet = null
|
var currentPlanet = null
|
||||||
userPlanets.some(function (planet) {
|
currentUser.Planets.some(function (planet) {
|
||||||
if (planet.name === currentPlanetName) {
|
if (planet.name === currentPlanetName) {
|
||||||
currentPlanet = planet
|
currentPlanet = planet
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ var OnlyGuest = {
|
|||||||
this.transitionTo('user', {userName: user.name})
|
this.transitionTo('user', {userName: user.name})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.transitionTo('dashboard', {userName: user.name, planetName: planet.name})
|
this.transitionTo('planetHome', {userName: user.name, planetName: planet.name})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
browser/main/Stores/PlanetStore.js
Normal file
37
browser/main/Stores/PlanetStore.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
var Reflux = require('reflux')
|
||||||
|
var request = require('superagent')
|
||||||
|
|
||||||
|
var fetchPlanet = require('../Actions/fetchPlanet')
|
||||||
|
|
||||||
|
var updateSnippet = require('../Actions/updateSnippet')
|
||||||
|
var fetchSnippets = require('../Actions/fetchSnippets')
|
||||||
|
|
||||||
|
var PlanetStore = Reflux.createStore({
|
||||||
|
init: function () {
|
||||||
|
// this.listenTo(updateSnippet, this.updateSnippet)
|
||||||
|
// this.listenTo(fetchSnippets, this.fetchSnippets)
|
||||||
|
this.listenTo(fetchPlanet, this.fetchPlanet)
|
||||||
|
},
|
||||||
|
// planetName = user.name/planet.name
|
||||||
|
fetchPlanet: function (planetName) {
|
||||||
|
request
|
||||||
|
.get('http://localhost:8000/' + planetName)
|
||||||
|
.send()
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
this.trigger(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var planet = res.body
|
||||||
|
|
||||||
|
this.trigger(planet)
|
||||||
|
}.bind(this))
|
||||||
|
},
|
||||||
|
updateSnippet: function (input) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = PlanetStore
|
||||||
@@ -15,9 +15,6 @@ var RegisterContainer = require('./Containers/RegisterContainer.jsx')
|
|||||||
var UserContainer = require('./Containers/UserContainer.jsx')
|
var UserContainer = require('./Containers/UserContainer.jsx')
|
||||||
var UserSettingContainer = require('./Containers/UserSettingContainer.jsx')
|
var UserSettingContainer = require('./Containers/UserSettingContainer.jsx')
|
||||||
var PlanetContainer = require('./Containers/PlanetContainer.jsx')
|
var PlanetContainer = require('./Containers/PlanetContainer.jsx')
|
||||||
var DashboardContainer = require('./Containers/DashboardContainer.jsx')
|
|
||||||
var SnippetContainer = require('./Containers/SnippetContainer.jsx')
|
|
||||||
var BlueprintContainer = require('./Containers/BlueprintContainer.jsx')
|
|
||||||
|
|
||||||
var routes = (
|
var routes = (
|
||||||
<Route path='/' handler={MainContainer}>
|
<Route path='/' handler={MainContainer}>
|
||||||
@@ -27,9 +24,9 @@ var routes = (
|
|||||||
<Route name='user' path=':userName' handler={UserContainer}>
|
<Route name='user' path=':userName' handler={UserContainer}>
|
||||||
<DefaultRoute name='userHome' handler={UserSettingContainer}/>
|
<DefaultRoute name='userHome' handler={UserSettingContainer}/>
|
||||||
<Route name='planet' path=':planetName' handler={PlanetContainer}>
|
<Route name='planet' path=':planetName' handler={PlanetContainer}>
|
||||||
<DefaultRoute name='dashboard' handler={DashboardContainer}/>
|
<DefaultRoute name='planetHome'/>
|
||||||
<Route name='snippets' handler={SnippetContainer}/>
|
<Route name='snippets' path='snippets/:localId'/>
|
||||||
<Route name='blueprint' handler={BlueprintContainer}/>
|
<Route name='blueprints' path='blueprints/:localId'/>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
.SideNavigator
|
|
||||||
absolute bottom left
|
|
||||||
top 65px
|
|
||||||
width 200px
|
|
||||||
border-right solid 1px highlightenBorderColor
|
|
||||||
padding 10px
|
|
||||||
box-sizing border-box
|
|
||||||
nav
|
|
||||||
a
|
|
||||||
display block
|
|
||||||
box-sizing border-box
|
|
||||||
padding 15px 15px
|
|
||||||
margin 10px 0
|
|
||||||
border-radius 10px
|
|
||||||
text-decoration none
|
|
||||||
background-color transparent
|
|
||||||
color textColor
|
|
||||||
transition 0.1s
|
|
||||||
&:hover, &.hover
|
|
||||||
background-color hoverBackgroundColor
|
|
||||||
&:active, &.active
|
|
||||||
color brandColor
|
|
||||||
|
|||||||
179
browser/styles/main/containers/PlanetContainer.styl
Normal file
179
browser/styles/main/containers/PlanetContainer.styl
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
|
||||||
|
.PlanetContainer
|
||||||
|
absolute top bottom right
|
||||||
|
left 50px
|
||||||
|
|
||||||
|
.PlanetHeader
|
||||||
|
absolute left right top
|
||||||
|
overflow-y hidden
|
||||||
|
height 65px
|
||||||
|
background-color white
|
||||||
|
border-bottom solid 1px borderColor
|
||||||
|
box-sizing border-box
|
||||||
|
padding 5px 15px
|
||||||
|
clearfix()
|
||||||
|
.planetName
|
||||||
|
line-height 30px
|
||||||
|
font-size 2em
|
||||||
|
color brandColor
|
||||||
|
line-height 55px
|
||||||
|
padding 0 20px
|
||||||
|
.menuBtn
|
||||||
|
display inline-block
|
||||||
|
position relative
|
||||||
|
top -5px
|
||||||
|
font-size 0.8em
|
||||||
|
color lightButtonColor
|
||||||
|
border solid 1px lightButtonColor
|
||||||
|
box-sizing border-box
|
||||||
|
circle()
|
||||||
|
background-image none
|
||||||
|
background-color transparent
|
||||||
|
width 30px
|
||||||
|
height 30px
|
||||||
|
text-align center
|
||||||
|
cursor pointer
|
||||||
|
transition 0.1s
|
||||||
|
transform scale(0.8)
|
||||||
|
&:focus, &.focus
|
||||||
|
outline none
|
||||||
|
&: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
|
||||||
|
.searchInput
|
||||||
|
display inline-block
|
||||||
|
position relative
|
||||||
|
top -3px
|
||||||
|
margin-left 15px
|
||||||
|
input
|
||||||
|
padding-left 32px
|
||||||
|
.fa
|
||||||
|
position absolute
|
||||||
|
top 7px
|
||||||
|
left 10px
|
||||||
|
.downloadBtn
|
||||||
|
position relative
|
||||||
|
float right
|
||||||
|
top 5px
|
||||||
|
padding 7px 25px
|
||||||
|
box-sizing border-box
|
||||||
|
line-height 30px
|
||||||
|
.dropDown
|
||||||
|
z-index 500
|
||||||
|
position fixed
|
||||||
|
background white
|
||||||
|
width 200px
|
||||||
|
border solid 1px borderColor
|
||||||
|
box-sizing border-box
|
||||||
|
margin-top -5px
|
||||||
|
margin-left 125px
|
||||||
|
box-shadow popupShadow
|
||||||
|
&.hide
|
||||||
|
visibility hidden
|
||||||
|
a
|
||||||
|
color textColor
|
||||||
|
display block
|
||||||
|
width 100%
|
||||||
|
padding 15px
|
||||||
|
box-sizing border-box
|
||||||
|
border-bottom solid 1px borderColor
|
||||||
|
text-decoration none
|
||||||
|
&:hover, &.hover
|
||||||
|
background-color hoverBackgroundColor
|
||||||
|
&:focus, &.focus
|
||||||
|
color black
|
||||||
|
&:active, &.active
|
||||||
|
color brandColor
|
||||||
|
&:last-child
|
||||||
|
border-bottom none
|
||||||
|
|
||||||
|
.PlanetNavigator
|
||||||
|
absolute bottom left
|
||||||
|
top 65px
|
||||||
|
width 200px
|
||||||
|
border-right solid 1px highlightenBorderColor
|
||||||
|
padding 10px
|
||||||
|
box-sizing border-box
|
||||||
|
nav
|
||||||
|
a
|
||||||
|
display block
|
||||||
|
box-sizing border-box
|
||||||
|
padding 15px 15px
|
||||||
|
margin 10px 0
|
||||||
|
border-radius 10px
|
||||||
|
text-decoration none
|
||||||
|
background-color transparent
|
||||||
|
color textColor
|
||||||
|
transition 0.1s
|
||||||
|
&:hover, &.hover
|
||||||
|
background-color hoverBackgroundColor
|
||||||
|
&:active, &.active
|
||||||
|
color brandColor
|
||||||
|
|
||||||
|
.PlanetArticleList
|
||||||
|
absolute bottom right
|
||||||
|
left 200px
|
||||||
|
top 65px
|
||||||
|
.tags
|
||||||
|
a
|
||||||
|
margin 0 2px
|
||||||
|
width 250px
|
||||||
|
border-right solid 1px highlightenBorderColor
|
||||||
|
|
||||||
|
&>ul
|
||||||
|
absolute top bottom left right
|
||||||
|
overflow-y auto
|
||||||
|
li
|
||||||
|
border-bottom solid 1px borderColor
|
||||||
|
padding 10px
|
||||||
|
cursor pointer
|
||||||
|
.callSign
|
||||||
|
margin-bottom 5px
|
||||||
|
font-weight 600
|
||||||
|
.description
|
||||||
|
margin-bottom 5px
|
||||||
|
.updatedAt
|
||||||
|
margin-bottom 5px
|
||||||
|
color lighten(textColor, 25%)
|
||||||
|
font-size 0.8em
|
||||||
|
&:hover, &.hover
|
||||||
|
background-color hoverBackgroundColor
|
||||||
|
&:active, &.active
|
||||||
|
background-color white
|
||||||
|
&:active, &.active
|
||||||
|
border solid 2px brandBorderColor
|
||||||
|
padding 9px 9px 8px
|
||||||
|
|
||||||
|
.PlanetArticleDetail
|
||||||
|
absolute right bottom
|
||||||
|
top 65px
|
||||||
|
left 450px
|
||||||
|
.viewer-header
|
||||||
|
height 44px
|
||||||
|
line-height 44px
|
||||||
|
padding 0 15px
|
||||||
|
border-bottom solid 1px borderColor
|
||||||
|
box-sizing border-box
|
||||||
|
small
|
||||||
|
font-size 0.5em
|
||||||
|
.control-group
|
||||||
|
float right
|
||||||
|
button
|
||||||
|
margin 0 2px
|
||||||
|
.viewer-body
|
||||||
|
absolute bottom right
|
||||||
|
left 1px
|
||||||
|
top 44px
|
||||||
|
.viewer-detail
|
||||||
|
border-bottom solid 1px borderColor
|
||||||
|
padding 10px
|
||||||
|
.description
|
||||||
|
margin-bottom 15px
|
||||||
|
.content
|
||||||
|
padding 5px 0
|
||||||
|
.ace_editor
|
||||||
|
height 500px
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
.SnippetContainer
|
|
||||||
fullsize()
|
|
||||||
.tags
|
|
||||||
a
|
|
||||||
margin 0 2px
|
|
||||||
.SnippetList
|
|
||||||
absolute top bottom left
|
|
||||||
width 250px
|
|
||||||
border-right solid 1px highlightenBorderColor
|
|
||||||
|
|
||||||
&>ul
|
|
||||||
absolute top bottom left right
|
|
||||||
overflow-y auto
|
|
||||||
li
|
|
||||||
border-bottom solid 1px borderColor
|
|
||||||
padding 10px
|
|
||||||
cursor pointer
|
|
||||||
.callSign
|
|
||||||
margin-bottom 5px
|
|
||||||
font-weight 600
|
|
||||||
.description
|
|
||||||
margin-bottom 5px
|
|
||||||
.updatedAt
|
|
||||||
margin-bottom 5px
|
|
||||||
color lighten(textColor, 25%)
|
|
||||||
font-size 0.8em
|
|
||||||
&:hover, &.hover
|
|
||||||
background-color hoverBackgroundColor
|
|
||||||
&:active, &.active
|
|
||||||
background-color white
|
|
||||||
&:active, &.active
|
|
||||||
border solid 2px brandBorderColor
|
|
||||||
padding 9px 9px 8px
|
|
||||||
|
|
||||||
.SnippetViewer
|
|
||||||
absolute top bottom right
|
|
||||||
left 250px
|
|
||||||
.viewer-header
|
|
||||||
height 44px
|
|
||||||
line-height 44px
|
|
||||||
padding 0 15px
|
|
||||||
border-bottom solid 1px borderColor
|
|
||||||
box-sizing border-box
|
|
||||||
small
|
|
||||||
font-size 0.5em
|
|
||||||
.control-group
|
|
||||||
float right
|
|
||||||
button
|
|
||||||
margin 0 2px
|
|
||||||
.viewer-body
|
|
||||||
absolute bottom right
|
|
||||||
left 1px
|
|
||||||
top 44px
|
|
||||||
.viewer-detail
|
|
||||||
border-bottom solid 1px borderColor
|
|
||||||
padding 10px
|
|
||||||
.description
|
|
||||||
margin-bottom 15px
|
|
||||||
.content
|
|
||||||
padding 5px 0
|
|
||||||
.ace_editor
|
|
||||||
height 500px
|
|
||||||
@@ -156,104 +156,3 @@ textarea.block-input
|
|||||||
border-color darken(brandBorderColor, 10%)
|
border-color darken(brandBorderColor, 10%)
|
||||||
background-color brandColor
|
background-color brandColor
|
||||||
color white
|
color white
|
||||||
|
|
||||||
.PlanetContainer
|
|
||||||
absolute top bottom right
|
|
||||||
left 50px
|
|
||||||
|
|
||||||
.PlanetMain
|
|
||||||
fullsize()
|
|
||||||
|
|
||||||
.PlanetHeader
|
|
||||||
absolute left right top
|
|
||||||
overflow-y hidden
|
|
||||||
height 65px
|
|
||||||
background-color white
|
|
||||||
border-bottom solid 1px borderColor
|
|
||||||
box-sizing border-box
|
|
||||||
padding 5px 15px
|
|
||||||
clearfix()
|
|
||||||
.planetName
|
|
||||||
line-height 30px
|
|
||||||
font-size 2em
|
|
||||||
color brandColor
|
|
||||||
line-height 55px
|
|
||||||
padding 0 20px
|
|
||||||
.menuBtn
|
|
||||||
display inline-block
|
|
||||||
position relative
|
|
||||||
top -5px
|
|
||||||
font-size 0.8em
|
|
||||||
color lightButtonColor
|
|
||||||
border solid 1px lightButtonColor
|
|
||||||
box-sizing border-box
|
|
||||||
circle()
|
|
||||||
background-image none
|
|
||||||
background-color transparent
|
|
||||||
width 30px
|
|
||||||
height 30px
|
|
||||||
text-align center
|
|
||||||
cursor pointer
|
|
||||||
transition 0.1s
|
|
||||||
transform scale(0.8)
|
|
||||||
&:focus, &.focus
|
|
||||||
outline none
|
|
||||||
&: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
|
|
||||||
.searchInput
|
|
||||||
display inline-block
|
|
||||||
position relative
|
|
||||||
top -3px
|
|
||||||
margin-left 15px
|
|
||||||
input
|
|
||||||
padding-left 32px
|
|
||||||
.fa
|
|
||||||
position absolute
|
|
||||||
top 7px
|
|
||||||
left 10px
|
|
||||||
.downloadBtn
|
|
||||||
position relative
|
|
||||||
float right
|
|
||||||
top 5px
|
|
||||||
padding 7px 25px
|
|
||||||
box-sizing border-box
|
|
||||||
line-height 30px
|
|
||||||
.dropDown
|
|
||||||
z-index 500
|
|
||||||
position fixed
|
|
||||||
background white
|
|
||||||
width 200px
|
|
||||||
border solid 1px borderColor
|
|
||||||
box-sizing border-box
|
|
||||||
margin-top -5px
|
|
||||||
margin-left 125px
|
|
||||||
box-shadow popupShadow
|
|
||||||
&.hide
|
|
||||||
visibility hidden
|
|
||||||
a
|
|
||||||
color textColor
|
|
||||||
display block
|
|
||||||
width 100%
|
|
||||||
padding 15px
|
|
||||||
box-sizing border-box
|
|
||||||
border-bottom solid 1px borderColor
|
|
||||||
text-decoration none
|
|
||||||
&:hover, &.hover
|
|
||||||
background-color hoverBackgroundColor
|
|
||||||
&:focus, &.focus
|
|
||||||
color black
|
|
||||||
&:active, &.active
|
|
||||||
color brandColor
|
|
||||||
&:last-child
|
|
||||||
border-bottom none
|
|
||||||
|
|
||||||
|
|
||||||
.PlanetBody
|
|
||||||
absolute bottom right
|
|
||||||
left 200px
|
|
||||||
top 65px
|
|
||||||
|
|||||||
Reference in New Issue
Block a user