mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-14 10:16:26 +00:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06a54d451c | ||
|
|
e317075815 | ||
|
|
45541a255b | ||
|
|
3ab423d695 | ||
|
|
345d7b427a | ||
|
|
de6d6b692e | ||
|
|
b2845e2284 | ||
|
|
47383c347c | ||
|
|
4bda84d69c | ||
|
|
b510aa11f5 | ||
|
|
8dab6d5e04 | ||
|
|
85f833c865 | ||
|
|
15133d00c7 | ||
|
|
b93990d10b | ||
|
|
a0bcb8edbe | ||
|
|
bfdf691bed | ||
|
|
f60856b998 | ||
|
|
3308eeaf82 | ||
|
|
19930a2472 | ||
|
|
e75d95b1fc | ||
|
|
4319711dc6 | ||
|
|
9712be909d | ||
|
|
04060ce252 | ||
|
|
da066fe694 | ||
|
|
3b7215b36a | ||
|
|
b88d5cfb06 | ||
|
|
8ab96cf2fb | ||
|
|
63af2fd8b1 | ||
|
|
fcf26f7844 | ||
|
|
657ebc99df | ||
|
|
9500f9a8c9 | ||
|
|
a05bba15e7 | ||
|
|
3b907627f7 | ||
|
|
2284fd41b9 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
|||||||
[submodule "browser/ace"]
|
[submodule "browser/ace"]
|
||||||
path = browser/ace
|
path = browser/ace
|
||||||
url = https://github.com/ajaxorg/ace-builds.git
|
url = https://github.com/ajaxorg/ace-builds.git
|
||||||
|
[submodule "browser/electron-stylus"]
|
||||||
|
path = browser/electron-stylus
|
||||||
|
url = https://github.com/Rokt33r/electron-stylus.git
|
||||||
|
|||||||
BIN
Lato-Regular.ttf
Normal file
BIN
Lato-Regular.ttf
Normal file
Binary file not shown.
BIN
Lato-Regular.woff
Normal file
BIN
Lato-Regular.woff
Normal file
Binary file not shown.
BIN
Lato-Regular.woff2
Normal file
BIN
Lato-Regular.woff2
Normal file
Binary file not shown.
1
browser/electron-stylus
Submodule
1
browser/electron-stylus
Submodule
Submodule browser/electron-stylus added at 6d86de7c66
@@ -2,10 +2,9 @@ var React = require('react/addons')
|
|||||||
|
|
||||||
var CodeViewer = require('../../main/Components/CodeViewer')
|
var CodeViewer = require('../../main/Components/CodeViewer')
|
||||||
|
|
||||||
var Markdown = require('../../main/Mixins/Markdown')
|
var MarkdownPreview = require('../../main/Components/MarkdownPreview')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [Markdown],
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentArticle: React.PropTypes.object
|
currentArticle: React.PropTypes.object
|
||||||
},
|
},
|
||||||
@@ -28,7 +27,7 @@ module.exports = React.createClass({
|
|||||||
<div className='FinderDetail'>
|
<div className='FinderDetail'>
|
||||||
<div className='header'><i className='fa fa-file-text-o fa-fw'/> {article.title}</div>
|
<div className='header'><i className='fa fa-file-text-o fa-fw'/> {article.title}</div>
|
||||||
<div className='content'>
|
<div className='content'>
|
||||||
<div className='marked' dangerouslySetInnerHTML={{__html: ' ' + this.markdown(article.content)}}></div>
|
<MarkdownPreview className='marked' content={article.content}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,6 +8,17 @@
|
|||||||
|
|
||||||
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css" media="screen" title="no title" charset="utf-8">
|
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css" media="screen" title="no title" charset="utf-8">
|
||||||
<link rel="shortcut icon" href="favicon.ico">
|
<link rel="shortcut icon" href="favicon.ico">
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Lato';
|
||||||
|
src: url('../../Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
|
||||||
|
url('../../Lato-Regular.woff') format('woff'), /* Modern Browsers */
|
||||||
|
url('../../Lato-Regular.ttf') format('truetype');
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('mousewheel', function(e) {
|
document.addEventListener('mousewheel', function(e) {
|
||||||
if(e.deltaY % 1 !== 0) {
|
if(e.deltaY % 1 !== 0) {
|
||||||
@@ -47,14 +58,13 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
require('electron-stylus')(__dirname + '/../styles/finder/index.styl')
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="content"></div>
|
<div id="content"></div>
|
||||||
<script src="../ace/src-min/ace.js"></script>
|
<script src="../ace/src-min/ace.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
require('../electron-stylus')(__dirname + '/../styles/finder/index.styl', 'finderCss')
|
||||||
require('node-jsx').install({ harmony: true, extension: '.jsx' })
|
require('node-jsx').install({ harmony: true, extension: '.jsx' })
|
||||||
require('./index.jsx')
|
require('./index.jsx')
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ var Finder = React.createClass({
|
|||||||
document.addEventListener('keydown', this.handleKeyDown)
|
document.addEventListener('keydown', this.handleKeyDown)
|
||||||
document.addEventListener('click', this.handleClick)
|
document.addEventListener('click', this.handleClick)
|
||||||
window.addEventListener('focus', this.handleFinderFocus)
|
window.addEventListener('focus', this.handleFinderFocus)
|
||||||
|
this.handleFinderFocus()
|
||||||
},
|
},
|
||||||
componentWillUnmount: function () {
|
componentWillUnmount: function () {
|
||||||
document.removeEventListener('keydown', this.handleKeyDown)
|
document.removeEventListener('keydown', this.handleKeyDown)
|
||||||
|
|||||||
@@ -4,12 +4,20 @@ var version = remote.getGlobal('version')
|
|||||||
var React = require('react/addons')
|
var React = require('react/addons')
|
||||||
|
|
||||||
var ExternalLink = require('../Mixins/ExternalLink')
|
var ExternalLink = require('../Mixins/ExternalLink')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [ExternalLink],
|
mixins: [ExternalLink, KeyCaster('aboutModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
close: React.PropTypes.func
|
close: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
onKeyCast: function (e) {
|
||||||
|
switch (e.status) {
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
<div className='AboutModal modal'>
|
<div className='AboutModal modal'>
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ var LinkedState = require('../Mixins/LinkedState')
|
|||||||
|
|
||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var UserStore = require('../Stores/UserStore')
|
var UserStore = require('../Stores/UserStore')
|
||||||
|
|
||||||
var getOptions = function (input, callback) {
|
var getOptions = function (input, callback) {
|
||||||
@@ -26,7 +28,7 @@ var getOptions = function (input, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [LinkedState],
|
mixins: [LinkedState, KeyCaster('addMemberModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
team: React.PropTypes.object,
|
team: React.PropTypes.object,
|
||||||
close: React.PropTypes.func
|
close: React.PropTypes.func
|
||||||
@@ -37,20 +39,35 @@ module.exports = React.createClass({
|
|||||||
role: 'member'
|
role: 'member'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSubmit: function () {
|
onKeyCast: function (e) {
|
||||||
Hq
|
switch (e.status) {
|
||||||
.addMember(this.props.team.name, {
|
case 'closeModal':
|
||||||
userName: this.state.userName,
|
|
||||||
role: this.state.role
|
|
||||||
})
|
|
||||||
.then(function (res) {
|
|
||||||
console.log(res.body)
|
|
||||||
UserStore.Actions.addMember(res.body)
|
|
||||||
this.props.close()
|
this.props.close()
|
||||||
}.bind(this))
|
break
|
||||||
.catch(function (err) {
|
case 'submitAddMemberModal':
|
||||||
console.error(err)
|
this.handleSubmit()
|
||||||
})
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSubmit: function () {
|
||||||
|
this.setState({errorMessage: null}, function () {
|
||||||
|
Hq
|
||||||
|
.addMember(this.props.team.name, {
|
||||||
|
userName: this.state.userName,
|
||||||
|
role: this.state.role
|
||||||
|
})
|
||||||
|
.then(function (res) {
|
||||||
|
console.log(res.body)
|
||||||
|
UserStore.Actions.addMember(res.body)
|
||||||
|
this.props.close()
|
||||||
|
}.bind(this))
|
||||||
|
.catch(function (err) {
|
||||||
|
console.error(err)
|
||||||
|
if (err.status === 403) {
|
||||||
|
this.setState({errorMessage: err.response.body.message})
|
||||||
|
}
|
||||||
|
}.bind(this))
|
||||||
|
})
|
||||||
},
|
},
|
||||||
handleChange: function (value) {
|
handleChange: function (value) {
|
||||||
this.setState({userName: value})
|
this.setState({userName: value})
|
||||||
@@ -76,6 +93,8 @@ module.exports = React.createClass({
|
|||||||
role
|
role
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{this.state.errorMessage != null ? (<p className='errorAlert'>{this.state.errorMessage}</p>) : null}
|
||||||
|
|
||||||
<button onClick={this.handleSubmit} className='submitButton'><i className='fa fa-check'/></button>
|
<button onClick={this.handleSubmit} className='submitButton'><i className='fa fa-check'/></button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,19 +2,26 @@ var React = require('react')
|
|||||||
|
|
||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var PlanetStore = require('../Stores/PlanetStore')
|
var PlanetStore = require('../Stores/PlanetStore')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
mixins: [KeyCaster('codeDeleteModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
planet: React.PropTypes.object,
|
planet: React.PropTypes.object,
|
||||||
code: React.PropTypes.object,
|
code: React.PropTypes.object,
|
||||||
close: React.PropTypes.func
|
close: React.PropTypes.func
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
onKeyCast: function (e) {
|
||||||
React.findDOMNode(this).focus()
|
switch (e.status) {
|
||||||
},
|
case 'submitCodeDeleteModal':
|
||||||
stopPropagation: function (e) {
|
this.submit()
|
||||||
e.stopPropagation()
|
break
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
}
|
||||||
},
|
},
|
||||||
submit: function () {
|
submit: function () {
|
||||||
var planet = this.props.planet
|
var planet = this.props.planet
|
||||||
|
|||||||
@@ -7,13 +7,19 @@ module.exports = React.createClass({
|
|||||||
code: React.PropTypes.object,
|
code: React.PropTypes.object,
|
||||||
planet: React.PropTypes.object
|
planet: React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
componentDidMount: function () {
|
||||||
|
// TODO: Hacked!! should fix later
|
||||||
|
setTimeout(function () {
|
||||||
|
React.findDOMNode(this.refs.form.refs.description).focus()
|
||||||
|
}.bind(this), 1)
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
<div className='CodeEditModal modal'>
|
<div className='CodeEditModal modal'>
|
||||||
<div className='modal-header'>
|
<div className='modal-header'>
|
||||||
<h1>Edit Code</h1>
|
<h1>Edit Code</h1>
|
||||||
</div>
|
</div>
|
||||||
<CodeForm code={this.props.code} planet={this.props.planet} close={this.props.close}/>
|
<CodeForm ref='form' code={this.props.code} planet={this.props.planet} close={this.props.close}/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ module.exports = React.createClass({
|
|||||||
propTypes: {
|
propTypes: {
|
||||||
code: React.PropTypes.string,
|
code: React.PropTypes.string,
|
||||||
mode: React.PropTypes.string,
|
mode: React.PropTypes.string,
|
||||||
|
className: React.PropTypes.string,
|
||||||
onChange: React.PropTypes.func
|
onChange: React.PropTypes.func
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
@@ -52,7 +53,7 @@ module.exports = React.createClass({
|
|||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
<div ref='target'></div>
|
<div ref='target' className={this.props.className}></div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ var Select = require('react-select')
|
|||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
var LinkedState = require('../Mixins/LinkedState')
|
var LinkedState = require('../Mixins/LinkedState')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var PlanetStore = require('../Stores/PlanetStore')
|
var PlanetStore = require('../Stores/PlanetStore')
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ var getOptions = function (input, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [LinkedState],
|
mixins: [LinkedState, KeyCaster('codeForm')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
planet: React.PropTypes.object,
|
planet: React.PropTypes.object,
|
||||||
close: React.PropTypes.func,
|
close: React.PropTypes.func,
|
||||||
@@ -55,6 +56,16 @@ module.exports = React.createClass({
|
|||||||
code: code
|
code: code
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onKeyCast: function (e) {
|
||||||
|
switch (e.status) {
|
||||||
|
case 'submitCodeForm':
|
||||||
|
this.submit()
|
||||||
|
break
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
handleModeChange: function (selected) {
|
handleModeChange: function (selected) {
|
||||||
var code = this.state.code
|
var code = this.state.code
|
||||||
code.mode = selected
|
code.mode = selected
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ var ace = window.ace
|
|||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
code: React.PropTypes.string,
|
code: React.PropTypes.string,
|
||||||
mode: React.PropTypes.string
|
mode: React.PropTypes.string,
|
||||||
|
className: React.PropTypes.string
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
var el = React.findDOMNode(this.refs.target)
|
var el = React.findDOMNode(this.refs.target)
|
||||||
@@ -46,7 +47,7 @@ module.exports = React.createClass({
|
|||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
<div ref='target'></div>
|
<div ref='target' className={this.props.className}></div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
var React = require('react')
|
var React = require('react')
|
||||||
|
|
||||||
var LinkedState = require('../Mixins/LinkedState')
|
var LinkedState = require('../Mixins/LinkedState')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [LinkedState],
|
mixins: [LinkedState, KeyCaster('contactModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
close: React.PropTypes.func
|
close: React.PropTypes.func
|
||||||
},
|
},
|
||||||
@@ -18,6 +19,23 @@ module.exports = React.createClass({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onKeyCast: function (e) {
|
||||||
|
switch (e.status) {
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
case 'submitContactModal':
|
||||||
|
if (this.state.isSent) {
|
||||||
|
this.props.close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.sendEmail()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
|
componentDidMount: function () {
|
||||||
|
React.findDOMNode(this.refs.title).focus()
|
||||||
|
},
|
||||||
sendEmail: function () {
|
sendEmail: function () {
|
||||||
Hq.sendEmail(this.state.mail)
|
Hq.sendEmail(this.state.mail)
|
||||||
.then(function (res) {
|
.then(function (res) {
|
||||||
@@ -36,7 +54,7 @@ module.exports = React.createClass({
|
|||||||
<div className='contactForm'>
|
<div className='contactForm'>
|
||||||
<div className='modal-body'>
|
<div className='modal-body'>
|
||||||
<div className='formField'>
|
<div className='formField'>
|
||||||
<input valueLink={this.linkState('mail.title')} placeholder='Title'/>
|
<input ref='title' valueLink={this.linkState('mail.title')} placeholder='Title'/>
|
||||||
</div>
|
</div>
|
||||||
<div className='formField'>
|
<div className='formField'>
|
||||||
<textarea valueLink={this.linkState('mail.content')} placeholder='Content'/>
|
<textarea valueLink={this.linkState('mail.content')} placeholder='Content'/>
|
||||||
|
|||||||
@@ -5,17 +5,19 @@ var React = require('react/addons')
|
|||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
var LinkedState = require('../Mixins/LinkedState')
|
var LinkedState = require('../Mixins/LinkedState')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var UserStore = require('../Stores/UserStore')
|
var UserStore = require('../Stores/UserStore')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [LinkedState],
|
mixins: [LinkedState, KeyCaster('editProfileModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
user: React.PropTypes.shape({
|
user: React.PropTypes.shape({
|
||||||
name: React.PropTypes.string,
|
name: React.PropTypes.string,
|
||||||
profileName: React.PropTypes.string,
|
profileName: React.PropTypes.string,
|
||||||
email: React.PropTypes.string
|
email: React.PropTypes.string
|
||||||
})
|
}),
|
||||||
|
close: React.PropTypes.func
|
||||||
},
|
},
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
var user = this.props.user
|
var user = this.props.user
|
||||||
@@ -34,6 +36,13 @@ module.exports = React.createClass({
|
|||||||
passwordSubmitStatus: null
|
passwordSubmitStatus: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onKeyCast: function (e) {
|
||||||
|
switch (e.status) {
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
selectTab: function (tabName) {
|
selectTab: function (tabName) {
|
||||||
return function () {
|
return function () {
|
||||||
this.setState({currentTab: tabName})
|
this.setState({currentTab: tabName})
|
||||||
|
|||||||
@@ -71,16 +71,6 @@ module.exports = React.createClass({
|
|||||||
openPlanetCreateModal: function () {
|
openPlanetCreateModal: function () {
|
||||||
this.openModal(PlanetCreateModal, {transitionTo: this.transitionTo})
|
this.openModal(PlanetCreateModal, {transitionTo: this.transitionTo})
|
||||||
},
|
},
|
||||||
handleKeyDown: function (e) {
|
|
||||||
if (this.state.currentUser == null) return
|
|
||||||
if (e.metaKey && e.keyCode > 48 && e.keyCode < 58) {
|
|
||||||
var planet = this.state.currentUser.Planets[e.keyCode - 49]
|
|
||||||
if (planet != null) {
|
|
||||||
this.transitionTo('planet', {userName: planet.userName, planetName: planet.name})
|
|
||||||
}
|
|
||||||
e.preventDefault()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toggleProfilePopup: function () {
|
toggleProfilePopup: function () {
|
||||||
this.openProfilePopup()
|
this.openProfilePopup()
|
||||||
},
|
},
|
||||||
@@ -96,6 +86,10 @@ module.exports = React.createClass({
|
|||||||
handleLogoutClick: function () {
|
handleLogoutClick: function () {
|
||||||
this.openModal(LogoutModal, {transitionTo: this.transitionTo})
|
this.openModal(LogoutModal, {transitionTo: this.transitionTo})
|
||||||
},
|
},
|
||||||
|
switchPlanetByIndex: function (index) {
|
||||||
|
var planetProps = this.refs.planets.props.children[index - 1].props
|
||||||
|
this.transitionTo('planet', {userName: planetProps.userName, planetName: planetProps.planetName})
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var params = this.getParams()
|
var params = this.getParams()
|
||||||
|
|
||||||
@@ -110,12 +104,12 @@ module.exports = React.createClass({
|
|||||||
return team.Planets == null ? planets : planets.concat(team.Planets)
|
return team.Planets == null ? planets : planets.concat(team.Planets)
|
||||||
}, []))).map(function (planet, index) {
|
}, []))).map(function (planet, index) {
|
||||||
return (
|
return (
|
||||||
<li key={planet.id} className={params.userName === planet.userName && params.planetName === planet.name ? 'active' : ''}>
|
<li userName={planet.userName} planetName={planet.name} key={planet.id} className={params.userName === planet.userName && params.planetName === planet.name ? 'active' : ''}>
|
||||||
<Link to='planet' params={{userName: planet.userName, planetName: planet.name}}>
|
<Link to='planet' params={{userName: planet.userName, planetName: planet.name}}>
|
||||||
{planet.name[0]}
|
{planet.name[0]}
|
||||||
<div className='planetTooltip'>{planet.userName}/{planet.name}</div>
|
<div className='planetTooltip'>{planet.userName}/{planet.name}</div>
|
||||||
</Link>
|
</Link>
|
||||||
<div className='shortCut'>⌘{index + 1}</div>
|
{index < 9 ? (<div className='shortCut'>⌘{index + 1}</div>) : null}
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -128,12 +122,12 @@ module.exports = React.createClass({
|
|||||||
<ProfileImage size='55' email={this.state.currentUser.email}/>
|
<ProfileImage size='55' email={this.state.currentUser.email}/>
|
||||||
</button>
|
</button>
|
||||||
{popup}
|
{popup}
|
||||||
<ul className='planetList'>
|
<ul ref='planets' className='planetList'>
|
||||||
{planets}
|
{planets}
|
||||||
</ul>
|
</ul>
|
||||||
<button onClick={this.openPlanetCreateModal} className='newPlanet'>
|
<button onClick={this.openPlanetCreateModal} className='newPlanet'>
|
||||||
<i className='fa fa-plus'/>
|
<i className='fa fa-plus'/>
|
||||||
<div className='newPlanetTooltip'>Create new planet</div>
|
<div className='tooltip'>Create new planet</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -143,7 +137,6 @@ module.exports = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<li key={'user-' + team.id}>
|
<li key={'user-' + team.id}>
|
||||||
<Link to='userHome' params={{userName: team.name}} className='userName'>{team.profileName} ({team.name})</Link>
|
<Link to='userHome' params={{userName: team.name}} className='userName'>{team.profileName} ({team.name})</Link>
|
||||||
<div className='userSetting'><i className='fa fa-gear'/></div>
|
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -157,7 +150,6 @@ module.exports = React.createClass({
|
|||||||
<ul className='profileGroupList'>
|
<ul className='profileGroupList'>
|
||||||
<li>
|
<li>
|
||||||
<Link to='userHome' params={{userName: this.state.currentUser.name}} className='userName'>Profile ({this.state.currentUser.name})</Link>
|
<Link to='userHome' params={{userName: this.state.currentUser.name}} className='userName'>Profile ({this.state.currentUser.name})</Link>
|
||||||
<div className='userSetting'><i className='fa fa-gear'/></div>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,34 +15,52 @@ module.exports = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
|
var codeButton = React.findDOMNode(this.refs.codeButton)
|
||||||
|
codeButton.addEventListener('keydown', this.handleKeyDown)
|
||||||
|
React.findDOMNode(this.refs.noteButton).addEventListener('keydown', this.handleKeyDown)
|
||||||
|
codeButton.focus()
|
||||||
},
|
},
|
||||||
stopPropagation: function (e) {
|
componentWillUnmount: function () {
|
||||||
e.stopPropagation()
|
React.findDOMNode(this.refs.codeButton).removeEventListener('keydown', this.handleKeyDown)
|
||||||
},
|
React.findDOMNode(this.refs.noteButton).removeEventListener('keydown', this.handleKeyDown)
|
||||||
selectCodeTab: function () {
|
|
||||||
this.setState({currentTab: 'code'})
|
|
||||||
},
|
|
||||||
selectNoteTab: function () {
|
|
||||||
this.setState({currentTab: 'note'})
|
|
||||||
},
|
},
|
||||||
handleKeyDown: function (e) {
|
handleKeyDown: function (e) {
|
||||||
if (e.keyCode === 37 && e.metaKey) {
|
if (e.keyCode === 37 && e.metaKey) {
|
||||||
this.selectCodeTab()
|
this.selectCodeTab()
|
||||||
|
e.stopPropagation()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if (e.keyCode === 39 && e.metaKey) {
|
if (e.keyCode === 39 && e.metaKey) {
|
||||||
this.selectNoteTab()
|
this.selectNoteTab()
|
||||||
|
e.stopPropagation()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if (e.keyCode === 9) {
|
||||||
|
if (this.state.currentTab === 'code') React.findDOMNode(this.refs.form.refs.description).focus()
|
||||||
|
else React.findDOMNode(this.refs.form.refs.title).focus()
|
||||||
|
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectCodeTab: function () {
|
||||||
|
this.setState({currentTab: 'code'}, function () {
|
||||||
|
React.findDOMNode(this.refs.codeButton).focus()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
selectNoteTab: function () {
|
||||||
|
this.setState({currentTab: 'note'}, function () {
|
||||||
|
React.findDOMNode(this.refs.noteButton).focus()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var modalBody
|
var modalBody
|
||||||
if (this.state.currentTab === 'code') {
|
if (this.state.currentTab === 'code') {
|
||||||
modalBody = (
|
modalBody = (
|
||||||
<CodeForm planet={this.props.planet} transitionTo={this.props.transitionTo} close={this.props.close}/>
|
<CodeForm ref='form' planet={this.props.planet} transitionTo={this.props.transitionTo} close={this.props.close}/>
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
modalBody = (
|
modalBody = (
|
||||||
<NoteForm planet={this.props.planet} transitionTo={this.props.transitionTo} close={this.props.close}/>
|
<NoteForm ref='form' planet={this.props.planet} transitionTo={this.props.transitionTo} close={this.props.close}/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +68,8 @@ module.exports = React.createClass({
|
|||||||
<div className='LaunchModal modal'>
|
<div className='LaunchModal modal'>
|
||||||
<div className='modal-header'>
|
<div className='modal-header'>
|
||||||
<div className='modal-tab'>
|
<div className='modal-tab'>
|
||||||
<button className={this.state.currentTab === 'code' ? 'btn-primary active' : 'btn-default'} onClick={this.selectCodeTab}>Code</button><button className={this.state.currentTab === 'note' ? 'btn-primary active' : 'btn-default'} onClick={this.selectNoteTab}>Note</button>
|
<button ref='codeButton' className={this.state.currentTab === 'code' ? 'btn-primary active' : 'btn-default'} onClick={this.selectCodeTab}>Code</button>
|
||||||
|
<button ref='noteButton' className={this.state.currentTab === 'note' ? 'btn-primary active' : 'btn-default'} onClick={this.selectNoteTab}>Note</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{modalBody}
|
{modalBody}
|
||||||
|
|||||||
@@ -2,11 +2,24 @@
|
|||||||
|
|
||||||
var React = require('react')
|
var React = require('react')
|
||||||
|
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
mixins: [KeyCaster('logoutModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
transitionTo: React.PropTypes.func,
|
transitionTo: React.PropTypes.func,
|
||||||
close: React.PropTypes.func
|
close: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
onKeyCast: function (e) {
|
||||||
|
switch (e.status) {
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
case 'submitLogoutModal':
|
||||||
|
this.logout()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
logout: function () {
|
logout: function () {
|
||||||
localStorage.removeItem('currentUser')
|
localStorage.removeItem('currentUser')
|
||||||
localStorage.removeItem('token')
|
localStorage.removeItem('token')
|
||||||
|
|||||||
@@ -2,16 +2,26 @@ var React = require('react')
|
|||||||
|
|
||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var PlanetStore = require('../Stores/PlanetStore')
|
var PlanetStore = require('../Stores/PlanetStore')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
mixins: [KeyCaster('noteDeleteModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
planet: React.PropTypes.object,
|
planet: React.PropTypes.object,
|
||||||
note: React.PropTypes.object,
|
note: React.PropTypes.object,
|
||||||
close: React.PropTypes.func
|
close: React.PropTypes.func
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
onKeyCast: function (e) {
|
||||||
React.findDOMNode(this).focus()
|
switch (e.status) {
|
||||||
|
case 'submitNoteDeleteModal':
|
||||||
|
this.submit()
|
||||||
|
break
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
}
|
||||||
},
|
},
|
||||||
submit: function () {
|
submit: function () {
|
||||||
var planet = this.props.planet
|
var planet = this.props.planet
|
||||||
|
|||||||
@@ -8,13 +8,19 @@ module.exports = React.createClass({
|
|||||||
note: React.PropTypes.object,
|
note: React.PropTypes.object,
|
||||||
planet: React.PropTypes.object
|
planet: React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
componentDidMount: function () {
|
||||||
|
// TODO: Hacked!! should fix later
|
||||||
|
setTimeout(function () {
|
||||||
|
React.findDOMNode(this.refs.form.refs.title).focus()
|
||||||
|
}.bind(this), 1)
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
<div className='NoteEditModal modal'>
|
<div className='NoteEditModal modal'>
|
||||||
<div className='modal-header'>
|
<div className='modal-header'>
|
||||||
<h1>Edit Note</h1>
|
<h1>Edit Note</h1>
|
||||||
</div>
|
</div>
|
||||||
<NoteForm note={this.props.note} planet={this.props.planet} close={this.props.close}/>
|
<NoteForm ref='form' note={this.props.note} planet={this.props.planet} close={this.props.close}/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
var React = require('react/addons')
|
var React = require('react/addons')
|
||||||
var ReactRouter = require('react-router')
|
|
||||||
var Select = require('react-select')
|
var Select = require('react-select')
|
||||||
|
|
||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
var LinkedState = require('../Mixins/LinkedState')
|
var LinkedState = require('../Mixins/LinkedState')
|
||||||
var Markdown = require('../Mixins/Markdown')
|
var Markdown = require('../Mixins/Markdown')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var PlanetStore = require('../Stores/PlanetStore')
|
var PlanetStore = require('../Stores/PlanetStore')
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ var EDIT_MODE = 0
|
|||||||
var PREVIEW_MODE = 1
|
var PREVIEW_MODE = 1
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [LinkedState, Markdown],
|
mixins: [LinkedState, Markdown, KeyCaster('noteForm')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
planet: React.PropTypes.object,
|
planet: React.PropTypes.object,
|
||||||
close: React.PropTypes.func,
|
close: React.PropTypes.func,
|
||||||
@@ -58,8 +58,15 @@ module.exports = React.createClass({
|
|||||||
mode: EDIT_MODE
|
mode: EDIT_MODE
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
onKeyCast: function (e) {
|
||||||
React.findDOMNode(this.refs.title).focus()
|
switch (e.status) {
|
||||||
|
case 'submitNoteForm':
|
||||||
|
this.submit()
|
||||||
|
break
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleTagsChange: function (selected, all) {
|
handleTagsChange: function (selected, all) {
|
||||||
var note = this.state.note
|
var note = this.state.note
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
var React = require('react/addons')
|
var React = require('react/addons')
|
||||||
var moment = require('moment')
|
var moment = require('moment')
|
||||||
|
|
||||||
var CodeViewer = require('../Components/CodeViewer')
|
var CodeViewer = require('./CodeViewer')
|
||||||
|
var CodeEditModal = require('./CodeEditModal')
|
||||||
var CodeEditModal = require('../Components/CodeEditModal')
|
var CodeDeleteModal = require('./CodeDeleteModal')
|
||||||
var CodeDeleteModal = require('../Components/CodeDeleteModal')
|
var NoteEditModal = require('./NoteEditModal')
|
||||||
var NoteEditModal = require('../Components/NoteEditModal')
|
var NoteDeleteModal = require('./NoteDeleteModal')
|
||||||
var NoteDeleteModal = require('../Components/NoteDeleteModal')
|
var MarkdownPreview = require('./MarkdownPreview')
|
||||||
var MarkdownPreview = require('../Components/MarkdownPreview')
|
var ProfileImage = require('./ProfileImage')
|
||||||
|
|
||||||
var Modal = require('../Mixins/Modal')
|
var Modal = require('../Mixins/Modal')
|
||||||
var ForceUpdate = require('../Mixins/ForceUpdate')
|
var ForceUpdate = require('../Mixins/ForceUpdate')
|
||||||
@@ -25,6 +25,7 @@ module.exports = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
openEditModal: function () {
|
openEditModal: function () {
|
||||||
|
if (this.props.article == null) return
|
||||||
switch (this.props.article.type) {
|
switch (this.props.article.type) {
|
||||||
case 'code' :
|
case 'code' :
|
||||||
this.openModal(CodeEditModal, {code: this.props.article, planet: this.props.planet})
|
this.openModal(CodeEditModal, {code: this.props.article, planet: this.props.planet})
|
||||||
@@ -34,6 +35,7 @@ module.exports = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
openDeleteModal: function () {
|
openDeleteModal: function () {
|
||||||
|
if (this.props.article == null) return
|
||||||
switch (this.props.article.type) {
|
switch (this.props.article.type) {
|
||||||
case 'code' :
|
case 'code' :
|
||||||
this.openModal(CodeDeleteModal, {code: this.props.article, planet: this.props.planet})
|
this.openModal(CodeDeleteModal, {code: this.props.article, planet: this.props.planet})
|
||||||
@@ -61,36 +63,61 @@ module.exports = React.createClass({
|
|||||||
if (article.type === 'code') {
|
if (article.type === 'code') {
|
||||||
return (
|
return (
|
||||||
<div className='PlanetArticleDetail codeDetail'>
|
<div className='PlanetArticleDetail codeDetail'>
|
||||||
<div className='viewer-header'>
|
<div className='detailHeader'>
|
||||||
<i className='fa fa-code fa-fw'></i> {article.callSign} <small className='updatedAt'>{moment(article.updatedAt).fromNow()}</small>
|
<div className='itemLeft'>
|
||||||
<span className='control-group'>
|
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
||||||
<button onClick={this.openEditModal} className='btn-default btn-square btn-sm'><i className='fa fa-edit fa-fw'></i></button>
|
<i className='fa fa-code fa-fw'></i>
|
||||||
<button onClick={this.openDeleteModal} className='btn-default btn-square btn-sm'><i className='fa fa-trash fa-fw'></i></button>
|
</div>
|
||||||
</span>
|
|
||||||
</div>
|
<div className='itemRight'>
|
||||||
<div className='viewer-body'>
|
<div className='itemInfo'>{moment(article.updatedAt).fromNow()} by <span className='userProfileName'>{article.User.profileName}</span></div>
|
||||||
<div className='viewer-detail'>
|
|
||||||
<div className='description'>{article.description}</div>
|
<div className='description'>{article.description}</div>
|
||||||
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='content'>
|
|
||||||
<CodeViewer code={article.content} mode={article.mode}/>
|
<span className='itemControl'>
|
||||||
</div>
|
<button id='articleEditButton' onClick={this.openEditModal} className='editButton'>
|
||||||
|
<i className='fa fa-edit fa-fw'></i>
|
||||||
|
<div className='tooltip'>Edit</div>
|
||||||
|
</button>
|
||||||
|
<button onClick={this.openDeleteModal} className='deleteButton'>
|
||||||
|
<i className='fa fa-trash fa-fw'></i>
|
||||||
|
<div className='tooltip'>Delete</div>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className='detailBody'>
|
||||||
|
<CodeViewer className='content' code={article.content} mode={article.mode}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className='PlanetArticleDetail noteDetail'>
|
<div className='PlanetArticleDetail noteDetail'>
|
||||||
<div className='viewer-header'>
|
<div className='detailHeader'>
|
||||||
<i className='fa fa-file-text-o fa-fw'></i> {article.title} <small className='updatedAt'>{moment(article.updatedAt).fromNow()}</small>
|
<div className='itemLeft'>
|
||||||
<span className='control-group'>
|
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
||||||
<button onClick={this.openEditModal} className='btn-default btn-square btn-sm'><i className='fa fa-edit fa-fw'></i></button>
|
<i className='fa fa-file-text-o fa-fw'></i>
|
||||||
<button onClick={this.openDeleteModal} className='btn-default btn-square btn-sm'><i className='fa fa-trash fa-fw'></i></button>
|
</div>
|
||||||
|
|
||||||
|
<div className='itemRight'>
|
||||||
|
<div className='itemInfo'>{moment(article.updatedAt).fromNow()} by <span className='userProfileName'>{article.User.profileName}</span></div>
|
||||||
|
<div className='description'>{article.title}</div>
|
||||||
|
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className='itemControl'>
|
||||||
|
<button id='articleEditButton' onClick={this.openEditModal} className='editButton'>
|
||||||
|
<i className='fa fa-edit fa-fw'></i>
|
||||||
|
<div className='tooltip'>Edit</div>
|
||||||
|
</button>
|
||||||
|
<button onClick={this.openDeleteModal} className='deleteButton'>
|
||||||
|
<i className='fa fa-trash fa-fw'></i>
|
||||||
|
<div className='tooltip'>Delete</div>
|
||||||
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='viewer-body'>
|
<div className='detailBody'>
|
||||||
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
|
||||||
<MarkdownPreview className='content' content={article.content}/>
|
<MarkdownPreview className='content' content={article.content}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,6 +13,33 @@ module.exports = React.createClass({
|
|||||||
articles: React.PropTypes.array,
|
articles: React.PropTypes.array,
|
||||||
showOnlyWithTag: React.PropTypes.func
|
showOnlyWithTag: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
handleArticleClikck: function (article) {
|
||||||
|
if (article.type === 'code') {
|
||||||
|
return function (e) {
|
||||||
|
var params = this.getParams()
|
||||||
|
|
||||||
|
document.getElementById('articleEditButton').focus()
|
||||||
|
this.transitionTo('codes', {
|
||||||
|
userName: params.userName,
|
||||||
|
planetName: params.planetName,
|
||||||
|
localId: article.localId
|
||||||
|
})
|
||||||
|
}.bind(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (article.type === 'note') {
|
||||||
|
return function (e) {
|
||||||
|
var params = this.getParams()
|
||||||
|
|
||||||
|
document.getElementById('articleEditButton').focus()
|
||||||
|
this.transitionTo('notes', {
|
||||||
|
userName: params.userName,
|
||||||
|
planetName: params.planetName,
|
||||||
|
localId: article.localId
|
||||||
|
})
|
||||||
|
}.bind(this)
|
||||||
|
}
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var articles = this.props.articles.map(function (article) {
|
var articles = this.props.articles.map(function (article) {
|
||||||
var tags = article.Tags.length > 0 ? article.Tags.map(function (tag) {
|
var tags = article.Tags.length > 0 ? article.Tags.map(function (tag) {
|
||||||
@@ -25,28 +52,17 @@ module.exports = React.createClass({
|
|||||||
var params = this.getParams()
|
var params = this.getParams()
|
||||||
var isActive = article.type === 'code' ? this.isActive('codes') && parseInt(params.localId, 10) === article.localId : this.isActive('notes') && parseInt(params.localId, 10) === article.localId
|
var isActive = article.type === 'code' ? this.isActive('codes') && parseInt(params.localId, 10) === article.localId : this.isActive('notes') && parseInt(params.localId, 10) === article.localId
|
||||||
|
|
||||||
var handleClick
|
|
||||||
|
|
||||||
if (article.type === 'code') {
|
if (article.type === 'code') {
|
||||||
|
|
||||||
handleClick = function () {
|
|
||||||
this.transitionTo('codes', {
|
|
||||||
userName: params.userName,
|
|
||||||
planetName: params.planetName,
|
|
||||||
localId: article.localId
|
|
||||||
})
|
|
||||||
}.bind(this)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li onClick={handleClick} key={'code-' + article.id}>
|
<li onClick={this.handleArticleClikck(article)} key={'code-' + article.id}>
|
||||||
<div className={'articleItem' + (isActive ? ' active' : '')}>
|
<div className={'articleItem' + (isActive ? ' active' : '')}>
|
||||||
<div className='itemLeft'>
|
<div className='itemLeft'>
|
||||||
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
||||||
<i className='fa fa-code fa-fw'></i>
|
<i className='fa fa-code fa-fw'></i>
|
||||||
</div>
|
</div>
|
||||||
<div className='itemRight'>
|
<div className='itemRight'>
|
||||||
<div className='updatedAt'>{moment(article.updatedAt).fromNow()}</div>
|
<div className='itemInfo'>{moment(article.updatedAt).fromNow()} by <span className='userProfileName'>{article.User.profileName}</span></div>
|
||||||
<div className='description'>{article.description.length > 50 ? article.description.substring(0, 50) + ' …' : article.description}</div>
|
<div className='description'>{article.description}</div>
|
||||||
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -55,16 +71,8 @@ module.exports = React.createClass({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClick = function () {
|
|
||||||
this.transitionTo('notes', {
|
|
||||||
userName: params.userName,
|
|
||||||
planetName: params.planetName,
|
|
||||||
localId: article.localId
|
|
||||||
})
|
|
||||||
}.bind(this)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li onClick={handleClick} key={'note-' + article.id}>
|
<li onClick={this.handleArticleClikck(article)} key={'note-' + article.id}>
|
||||||
<div className={'articleItem blueprintItem' + (isActive ? ' active' : '')}>
|
<div className={'articleItem blueprintItem' + (isActive ? ' active' : '')}>
|
||||||
<div className='itemLeft'>
|
<div className='itemLeft'>
|
||||||
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
|
||||||
@@ -72,7 +80,7 @@ module.exports = React.createClass({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='itemRight'>
|
<div className='itemRight'>
|
||||||
<div className='updatedAt'>{moment(article.updatedAt).fromNow()}</div>
|
<div className='itemInfo'>{moment(article.updatedAt).fromNow()} by <span className='userProfileName'>{article.User.profileName}</span></div>
|
||||||
<div className='description'>{article.title}</div>
|
<div className='description'>{article.title}</div>
|
||||||
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -85,7 +93,7 @@ module.exports = React.createClass({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='PlanetArticleList'>
|
<div className='PlanetArticleList'>
|
||||||
<ul>
|
<ul ref='articles'>
|
||||||
{articles}
|
{articles}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ var React = require('react/addons')
|
|||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
var LinkedState = require('../Mixins/LinkedState')
|
var LinkedState = require('../Mixins/LinkedState')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var PlanetStore = require('../Stores/PlanetStore')
|
var PlanetStore = require('../Stores/PlanetStore')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [LinkedState],
|
mixins: [LinkedState, KeyCaster('planetCreateModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
ownerName: React.PropTypes.string,
|
ownerName: React.PropTypes.string,
|
||||||
transitionTo: React.PropTypes.func,
|
transitionTo: React.PropTypes.func,
|
||||||
@@ -24,33 +25,57 @@ module.exports = React.createClass({
|
|||||||
name: '',
|
name: '',
|
||||||
public: true
|
public: true
|
||||||
},
|
},
|
||||||
ownerName: ownerName
|
ownerName: ownerName,
|
||||||
|
error: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
React.findDOMNode(this.refs.name).focus()
|
React.findDOMNode(this.refs.name).focus()
|
||||||
},
|
},
|
||||||
onListen: function (res) {
|
onKeyCast: function (e) {
|
||||||
if (res.status === 'planetCreated') {
|
switch (e.status) {
|
||||||
this.props.close()
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
case 'submitPlanetCreateModal':
|
||||||
|
this.handleSubmit()
|
||||||
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSubmit: function () {
|
handleSubmit: function () {
|
||||||
Hq.createPlanet(this.state.ownerName, this.state.planet)
|
this.setState({error: null}, function () {
|
||||||
.then(function (res) {
|
Hq.createPlanet(this.state.ownerName, this.state.planet)
|
||||||
var planet = res.body
|
.then(function (res) {
|
||||||
|
var planet = res.body
|
||||||
|
|
||||||
PlanetStore.Actions.update(planet)
|
PlanetStore.Actions.update(planet)
|
||||||
|
|
||||||
if (this.props.transitionTo != null) {
|
if (this.props.transitionTo != null) {
|
||||||
this.props.transitionTo('planetHome', {userName: planet.userName, planetName: planet.name})
|
this.props.transitionTo('planetHome', {userName: planet.userName, planetName: planet.name})
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.close()
|
this.props.close()
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
})
|
|
||||||
|
if (err.status == null) return this.setState({error: {message: 'Check your network connection'}})
|
||||||
|
|
||||||
|
switch (err.status) {
|
||||||
|
case 403:
|
||||||
|
this.setState({error: err.response.body})
|
||||||
|
break
|
||||||
|
case 422:
|
||||||
|
this.setState({error: {message: 'Planet name should be Alphanumeric with _, -'}})
|
||||||
|
break
|
||||||
|
case 409:
|
||||||
|
this.setState({error: {message: 'The entered name already in use'}})
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
this.setState({error: {message: 'Unexpected error occured! please try again'}})
|
||||||
|
}
|
||||||
|
}.bind(this))
|
||||||
|
})
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var teamOptions = this.state.user.Teams.map(function (team) {
|
var teamOptions = this.state.user.Teams.map(function (team) {
|
||||||
@@ -75,6 +100,8 @@ module.exports = React.createClass({
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{this.state.error != null ? (<p className='errorAlert'>{this.state.error.message != null ? this.state.error.message : 'Error message undefined'}</p>) : null}
|
||||||
|
|
||||||
<button onClick={this.handleSubmit} className='submitButton'>
|
<button onClick={this.handleSubmit} className='submitButton'>
|
||||||
<i className='fa fa-check'/>
|
<i className='fa fa-check'/>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -21,7 +21,22 @@ module.exports = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
React.findDOMNode(this.refs.search).focus()
|
var search = React.findDOMNode(this.refs.search)
|
||||||
|
search.addEventListener('keydown', this.handleSearchKeyDown)
|
||||||
|
},
|
||||||
|
componentWillUnmount: function () {
|
||||||
|
var search = React.findDOMNode(this.refs.search)
|
||||||
|
search.removeEventListener('keydown', this.handleSearchKeyDown)
|
||||||
|
},
|
||||||
|
handleSearchKeyDown: function (e) {
|
||||||
|
if (e.keyCode === 38 || e.keyCode === 40) {
|
||||||
|
var search = React.findDOMNode(this.refs.search)
|
||||||
|
search.blur()
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
if (e.keyCode !== 27 && (e.keyCode !== 13 || !e.metaKey)) {
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
openPlanetSettingModal: function () {
|
openPlanetSettingModal: function () {
|
||||||
this.openModal(PlanetSettingModal, {planet: this.props.currentPlanet})
|
this.openModal(PlanetSettingModal, {planet: this.props.currentPlanet})
|
||||||
@@ -42,12 +57,13 @@ module.exports = React.createClass({
|
|||||||
{this.props.currentPlanet.public ? null : (
|
{this.props.currentPlanet.public ? null : (
|
||||||
<div className='private'>
|
<div className='private'>
|
||||||
<i className='fa fa-lock'/>
|
<i className='fa fa-lock'/>
|
||||||
<div className='privateTooltip'>Private planet</div>
|
<div className='tooltip'>Private planet</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<button onClick={this.openPlanetSettingModal} className='menuBtn'>
|
<button onClick={this.openPlanetSettingModal} className='planetSettingButton'>
|
||||||
<i className='fa fa-chevron-down'></i>
|
<i className='fa fa-chevron-down'></i>
|
||||||
|
<div className='tooltip'>Planet setting</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className='headerControl'>
|
<div className='headerControl'>
|
||||||
@@ -55,9 +71,13 @@ module.exports = React.createClass({
|
|||||||
<i className='fa fa-search'/>
|
<i className='fa fa-search'/>
|
||||||
<input onChange={this.props.onSearchChange} value={this.props.search} ref='search' type='text' className='inline-input circleInput' placeholder='Search...'/>
|
<input onChange={this.props.onSearchChange} value={this.props.search} ref='search' type='text' className='inline-input circleInput' placeholder='Search...'/>
|
||||||
</div>
|
</div>
|
||||||
<button onClick={this.refresh} className='refreshButton'><i className='fa fa-refresh'/></button>
|
<button onClick={this.refresh} className='refreshButton'>
|
||||||
|
<i className='fa fa-refresh'/>
|
||||||
|
<div className='tooltip'>Refresh planet</div>
|
||||||
|
</button>
|
||||||
<a onClick={this.openExternal} href='http://b00st.io' className='logo'>
|
<a onClick={this.openExternal} href='http://b00st.io' className='logo'>
|
||||||
<img width='44' height='44' src='resources/favicon-230x230.png'/>
|
<img width='44' height='44' src='resources/favicon-230x230.png'/>
|
||||||
|
<div className='tooltip'>Boost official page</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,29 +3,47 @@ var ReactRouter = require('react-router')
|
|||||||
var Navigation = ReactRouter.Navigation
|
var Navigation = ReactRouter.Navigation
|
||||||
|
|
||||||
var Modal = require('../Mixins/Modal')
|
var Modal = require('../Mixins/Modal')
|
||||||
|
|
||||||
var LaunchModal = require('../Components/LaunchModal')
|
var LaunchModal = require('../Components/LaunchModal')
|
||||||
|
|
||||||
var PlanetNavigator = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [Modal, Navigation],
|
mixins: [Modal, Navigation],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
planet: React.PropTypes.shape({
|
planet: React.PropTypes.shape({
|
||||||
name: React.PropTypes.string
|
name: React.PropTypes.string,
|
||||||
|
Owner: React.PropTypes.shape({
|
||||||
|
id: React.PropTypes.number,
|
||||||
|
userType: React.PropTypes.string
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
search: React.PropTypes.string,
|
search: React.PropTypes.string,
|
||||||
toggleCodeFilter: React.PropTypes.func,
|
toggleCodeFilter: React.PropTypes.func,
|
||||||
toggleNoteFilter: React.PropTypes.func
|
toggleNoteFilter: React.PropTypes.func,
|
||||||
|
currentUser: React.PropTypes.shape({
|
||||||
|
id: React.PropTypes.number,
|
||||||
|
userType: React.PropTypes.string,
|
||||||
|
Teams: React.PropTypes.array
|
||||||
|
})
|
||||||
},
|
},
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
return {
|
return {
|
||||||
isLaunchModalOpen: false
|
isLaunchModalOpen: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
submitLaunchModal: function (ret) {
|
|
||||||
this.setState({isLaunchModalOpen: false})
|
|
||||||
},
|
|
||||||
openLaunchModal: function () {
|
openLaunchModal: function () {
|
||||||
this.openModal(LaunchModal, {planet: this.props.planet, transitionTo: this.transitionTo})
|
this.openModal(LaunchModal, {planet: this.props.planet, transitionTo: this.transitionTo})
|
||||||
},
|
},
|
||||||
|
isMyPlanet: function () {
|
||||||
|
if (this.props.currentUser == null) return false
|
||||||
|
if (this.props.planet.Owner.userType === 'person' && this.props.planet.Owner.id !== this.props.currentUser.id) return false
|
||||||
|
if (this.props.planet.Owner.userType === 'team' && !this.props.currentUser.Teams.some(function (team) {
|
||||||
|
if (team.id === this.props.planet.Owner.id) return true
|
||||||
|
return false
|
||||||
|
}.bind(this))) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var keywords = this.props.search.split(' ')
|
var keywords = this.props.search.split(' ')
|
||||||
var usingCodeFilter = keywords.some(function (keyword) {
|
var usingCodeFilter = keywords.some(function (keyword) {
|
||||||
@@ -39,9 +57,11 @@ var PlanetNavigator = React.createClass({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='PlanetNavigator'>
|
<div className='PlanetNavigator'>
|
||||||
<button onClick={this.openLaunchModal} className='launchButton btn-primary btn-block'>
|
{this.isMyPlanet() ? (
|
||||||
<i className='fa fa-rocket fa-fw'/> Launch
|
<button onClick={this.openLaunchModal} className='launchButton btn-primary btn-block'>
|
||||||
</button>
|
<i className='fa fa-rocket fa-fw'/> Launch
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
<nav className='articleFilters'>
|
<nav className='articleFilters'>
|
||||||
<a className={usingCodeFilter && !usingNoteFilter ? 'active' : ''} onClick={this.props.toggleCodeFilter}>
|
<a className={usingCodeFilter && !usingNoteFilter ? 'active' : ''} onClick={this.props.toggleCodeFilter}>
|
||||||
<i className='fa fa-code fa-fw'/> Codes
|
<i className='fa fa-code fa-fw'/> Codes
|
||||||
@@ -54,5 +74,3 @@ var PlanetNavigator = React.createClass({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = PlanetNavigator
|
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ var React = require('react/addons')
|
|||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
var LinkedState = require('../Mixins/LinkedState')
|
var LinkedState = require('../Mixins/LinkedState')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var PlanetStore = require('../Stores/PlanetStore')
|
var PlanetStore = require('../Stores/PlanetStore')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [LinkedState],
|
mixins: [LinkedState, KeyCaster('planetSettingModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
close: React.PropTypes.func,
|
close: React.PropTypes.func,
|
||||||
planet: React.PropTypes.shape({
|
planet: React.PropTypes.shape({
|
||||||
@@ -35,6 +36,13 @@ module.exports = React.createClass({
|
|||||||
deleteConfirmation: ''
|
deleteConfirmation: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onKeyCast: function (e) {
|
||||||
|
switch (e.status) {
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
activePlanetProfile: function () {
|
activePlanetProfile: function () {
|
||||||
this.setState({currentTab: 'profile'})
|
this.setState({currentTab: 'profile'})
|
||||||
},
|
},
|
||||||
@@ -50,18 +58,44 @@ module.exports = React.createClass({
|
|||||||
handleSavePlanetProfile: function (e) {
|
handleSavePlanetProfile: function (e) {
|
||||||
var planet = this.props.planet
|
var planet = this.props.planet
|
||||||
|
|
||||||
this.setState({profileSubmitStatus: 'sending'}, function () {
|
this.setState({profileFormStatus: 'sending', profileFormError: null}, function () {
|
||||||
Hq.updatePlanet(planet.userName, planet.name, this.state.planet)
|
Hq.updatePlanet(planet.userName, planet.name, this.state.planet)
|
||||||
.then(function (res) {
|
.then(function (res) {
|
||||||
var planet = res.body
|
var planet = res.body
|
||||||
|
console.log(planet)
|
||||||
this.setState({profileSubmitStatus: 'done'})
|
this.setState({profileFormStatus: 'done'})
|
||||||
|
|
||||||
PlanetStore.Actions.update(planet)
|
PlanetStore.Actions.update(planet)
|
||||||
|
this.props.close()
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
this.setState({profileSubmitStatus: 'error'})
|
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
var newState = {
|
||||||
|
profileFormStatus: 'error'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err.status == null) {
|
||||||
|
newState.profileFormError = {message: 'Check your network connection'}
|
||||||
|
return this.setState(newState)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (err.status) {
|
||||||
|
case 403:
|
||||||
|
newState.profileFormError = err.response.body
|
||||||
|
this.setState(newState)
|
||||||
|
break
|
||||||
|
case 422:
|
||||||
|
newState.profileFormError = {message: 'Planet name should be Alphanumeric with _, -'}
|
||||||
|
this.setState(newState)
|
||||||
|
break
|
||||||
|
case 409:
|
||||||
|
newState.profileFormError = {message: 'The entered name already in use'}
|
||||||
|
this.setState(newState)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
newState.profileFormError = {message: 'Undefined error please try again'}
|
||||||
|
this.setState(newState)
|
||||||
|
}
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -122,11 +156,11 @@ module.exports = React.createClass({
|
|||||||
<div className='formConfirm'>
|
<div className='formConfirm'>
|
||||||
<button onClick={this.handleSavePlanetProfile} className='saveButton btn-primary'>Save</button>
|
<button onClick={this.handleSavePlanetProfile} className='saveButton btn-primary'>Save</button>
|
||||||
|
|
||||||
<div className={'alertInfo' + (this.state.profileSubmitStatus === 'sending' ? '' : ' hide')}>on Sending...</div>
|
<div className={'alertInfo' + (this.state.profileFormStatus === 'sending' ? '' : ' hide')}>on Sending...</div>
|
||||||
|
|
||||||
<div className={'alertError' + (this.state.profileSubmitStatus === 'error' ? '' : ' hide')}>Connection failed.. Try again.</div>
|
<div className={'alertError' + (this.state.profileFormStatus === 'error' ? '' : ' hide')}>{this.state.profileFormError != null ? this.state.profileFormError.message : 'Unexpected error occured! please try again'}</div>
|
||||||
|
|
||||||
<div className={'alertSuccess' + (this.state.profileSubmitStatus === 'done' ? '' : ' hide')}>Successfully done!!</div>
|
<div className={'alertSuccess' + (this.state.profileFormStatus === 'done' ? '' : ' hide')}>Successfully done!!</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ var React = require('react/addons')
|
|||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
var LinkedState = require('../Mixins/LinkedState')
|
var LinkedState = require('../Mixins/LinkedState')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var UserStore = require('../Stores/UserStore')
|
var UserStore = require('../Stores/UserStore')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [LinkedState],
|
mixins: [LinkedState, KeyCaster('teamCreateModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
user: React.PropTypes.shape({
|
user: React.PropTypes.shape({
|
||||||
name: React.PropTypes.string
|
name: React.PropTypes.string
|
||||||
@@ -21,33 +22,62 @@ module.exports = React.createClass({
|
|||||||
return {
|
return {
|
||||||
team: {
|
team: {
|
||||||
name: ''
|
name: ''
|
||||||
}
|
},
|
||||||
|
error: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
componentDidMount: function () {
|
||||||
|
React.findDOMNode(this.refs.teamName).focus()
|
||||||
|
},
|
||||||
|
onKeyCast: function (e) {
|
||||||
|
switch (e.status) {
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
case 'submitTeamCreateModal':
|
||||||
|
this.handleSubmit()
|
||||||
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSubmit: function () {
|
handleSubmit: function () {
|
||||||
Hq.createTeam(this.props.user.name, this.state.team)
|
this.setState({error: null}, function () {
|
||||||
.then(function (res) {
|
Hq.createTeam(this.props.user.name, this.state.team)
|
||||||
var currentUser = JSON.parse(localStorage.getItem('currentUser'))
|
.then(function (res) {
|
||||||
var team = res.body
|
var currentUser = JSON.parse(localStorage.getItem('currentUser'))
|
||||||
|
var team = res.body
|
||||||
|
|
||||||
currentUser.Teams.push(team)
|
currentUser.Teams.push(team)
|
||||||
localStorage.setItem('currentUser', JSON.stringify(currentUser))
|
localStorage.setItem('currentUser', JSON.stringify(currentUser))
|
||||||
UserStore.Actions.update(currentUser)
|
UserStore.Actions.update(currentUser)
|
||||||
|
|
||||||
if (this.props.transitionTo != null) {
|
if (this.props.transitionTo != null) {
|
||||||
this.props.transitionTo('userHome', {userName: team.name})
|
this.props.transitionTo('userHome', {userName: team.name})
|
||||||
}
|
}
|
||||||
this.props.close()
|
this.props.close()
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
})
|
|
||||||
|
if (err.status == null) return this.setState({error: {message: 'Check your network connection'}})
|
||||||
|
|
||||||
|
switch (err.status) {
|
||||||
|
case 422:
|
||||||
|
this.setState({error: {message: 'Team name should be Alphanumeric with _, -'}})
|
||||||
|
break
|
||||||
|
case 409:
|
||||||
|
this.setState({error: {message: 'The entered name already in use'}})
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
this.setState({error: {message: 'Error message undefined'}})
|
||||||
|
}
|
||||||
|
}.bind(this))
|
||||||
|
})
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
<div className='TeamCreateModal modal'>
|
<div className='TeamCreateModal modal'>
|
||||||
<input valueLink={this.linkState('team.name')} className='nameInput stripInput' placeholder='Create new team'/>
|
<input ref='teamName' valueLink={this.linkState('team.name')} className='nameInput stripInput' placeholder='Create new team'/>
|
||||||
|
{this.state.error != null ? (<p className='errorAlert'>{this.state.error.message != null ? this.state.error.message : 'Unintended error occured'}</p>) : null}
|
||||||
<button onClick={this.handleSubmit} className='submitButton'>
|
<button onClick={this.handleSubmit} className='submitButton'>
|
||||||
<i className='fa fa-check'/>
|
<i className='fa fa-check'/>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ var Hq = require('../Services/Hq')
|
|||||||
|
|
||||||
var LinkedState = require('../Mixins/LinkedState')
|
var LinkedState = require('../Mixins/LinkedState')
|
||||||
var Helper = require('../Mixins/Helper')
|
var Helper = require('../Mixins/Helper')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var UserStore = require('../Stores/UserStore')
|
var UserStore = require('../Stores/UserStore')
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ var getOptions = function (input, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [LinkedState, Reflux.listenTo(UserStore, 'onUserChange'), Helper],
|
mixins: [LinkedState, Reflux.listenTo(UserStore, 'onUserChange'), Helper, KeyCaster('teamSettingsModal')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
team: React.PropTypes.shape({
|
team: React.PropTypes.shape({
|
||||||
id: React.PropTypes.number,
|
id: React.PropTypes.number,
|
||||||
@@ -38,7 +39,8 @@ module.exports = React.createClass({
|
|||||||
profileName: React.PropTypes.string,
|
profileName: React.PropTypes.string,
|
||||||
email: React.PropTypes.string,
|
email: React.PropTypes.string,
|
||||||
Members: React.PropTypes.array
|
Members: React.PropTypes.array
|
||||||
})
|
}),
|
||||||
|
close: React.PropTypes.func
|
||||||
},
|
},
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
var team = this.props.team
|
var team = this.props.team
|
||||||
@@ -55,6 +57,13 @@ module.exports = React.createClass({
|
|||||||
updatingMember: false
|
updatingMember: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onKeyCast: function (e) {
|
||||||
|
switch (e.status) {
|
||||||
|
case 'closeModal':
|
||||||
|
this.props.close()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
onUserChange: function (res) {
|
onUserChange: function (res) {
|
||||||
var member
|
var member
|
||||||
switch (res.status) {
|
switch (res.status) {
|
||||||
@@ -264,7 +273,7 @@ module.exports = React.createClass({
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
Maximum numbr of members is 5 on Beta version. Please contact us if you want futher use.
|
Maximum number of members is 5 on Beta version. Please contact us if you want futher use.
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,21 +7,33 @@ var State = ReactRouter.State
|
|||||||
var Navigation = ReactRouter.Navigation
|
var Navigation = ReactRouter.Navigation
|
||||||
|
|
||||||
var AuthFilter = require('../Mixins/AuthFilter')
|
var AuthFilter = require('../Mixins/AuthFilter')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var HomeNavigator = require('../Components/HomeNavigator')
|
var HomeNavigator = require('../Components/HomeNavigator')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [AuthFilter.OnlyUser, State, Navigation],
|
mixins: [AuthFilter.OnlyUser, State, Navigation, KeyCaster('homeContainer')],
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
if (this.isActive('homeEmpty')) {
|
if (this.isActive('homeEmpty')) {
|
||||||
var user = JSON.parse(localStorage.getItem('currentUser'))
|
var user = JSON.parse(localStorage.getItem('currentUser'))
|
||||||
|
if (user.Planets != null && user.Planets.length > 0) {
|
||||||
|
this.transitionTo('planet', {userName: user.name, planetName: user.Planets[0].name})
|
||||||
|
return
|
||||||
|
}
|
||||||
this.transitionTo('userHome', {userName: user.name})
|
this.transitionTo('userHome', {userName: user.name})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onKeyCast: function (e) {
|
||||||
|
switch (e.status) {
|
||||||
|
case 'switchPlanet':
|
||||||
|
this.refs.navigator.switchPlanetByIndex(e.data)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
<div className='HomeContainer'>
|
<div className='HomeContainer'>
|
||||||
<HomeNavigator/>
|
<HomeNavigator ref='navigator'/>
|
||||||
<RouteHandler/>
|
<RouteHandler/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -96,7 +96,10 @@ module.exports = React.createClass({
|
|||||||
{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}
|
||||||
<button onClick={this.openContactModal} className='contactButton'><i className='fa fa-paper-plane-o'/></button>
|
<button onClick={this.openContactModal} className='contactButton'>
|
||||||
|
<i className='fa fa-paper-plane-o'/>
|
||||||
|
<div className='tooltip'>Contact us</div>
|
||||||
|
</button>
|
||||||
<RouteHandler/>
|
<RouteHandler/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,12 +14,13 @@ var Hq = require('../Services/Hq')
|
|||||||
var Modal = require('../Mixins/Modal')
|
var Modal = require('../Mixins/Modal')
|
||||||
var ArticleFilter = require('../Mixins/ArticleFilter')
|
var ArticleFilter = require('../Mixins/ArticleFilter')
|
||||||
var Helper = require('../Mixins/Helper')
|
var Helper = require('../Mixins/Helper')
|
||||||
|
var KeyCaster = require('../Mixins/KeyCaster')
|
||||||
|
|
||||||
var UserStore = require('../Stores/UserStore')
|
var UserStore = require('../Stores/UserStore')
|
||||||
var PlanetStore = require('../Stores/PlanetStore')
|
var PlanetStore = require('../Stores/PlanetStore')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [ReactRouter.Navigation, ReactRouter.State, Modal, Reflux.listenTo(UserStore, 'onUserChange'), Reflux.listenTo(PlanetStore, 'onPlanetChange'), ArticleFilter, Helper],
|
mixins: [ReactRouter.Navigation, ReactRouter.State, Modal, Reflux.listenTo(UserStore, 'onUserChange'), Reflux.listenTo(PlanetStore, 'onPlanetChange'), ArticleFilter, Helper, KeyCaster('planetContainer')],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
params: React.PropTypes.object,
|
params: React.PropTypes.object,
|
||||||
planetName: React.PropTypes.string
|
planetName: React.PropTypes.string
|
||||||
@@ -62,6 +63,28 @@ module.exports = React.createClass({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onKeyCast: function (e) {
|
||||||
|
switch (e.status) {
|
||||||
|
case 'openLaunchModal':
|
||||||
|
this.refs.navigator.openLaunchModal()
|
||||||
|
break
|
||||||
|
case 'selectNextArticle':
|
||||||
|
this.selectNextArticle()
|
||||||
|
break
|
||||||
|
case 'selectPriorArticle':
|
||||||
|
this.selectPriorArticle()
|
||||||
|
break
|
||||||
|
case 'toggleFocusSearchInput':
|
||||||
|
this.toggleFocusSearchInput()
|
||||||
|
break
|
||||||
|
case 'openEditModal':
|
||||||
|
this.refs.detail.openEditModal()
|
||||||
|
break
|
||||||
|
case 'openDeleteModal':
|
||||||
|
this.refs.detail.openDeleteModal()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
onPlanetChange: function (res) {
|
onPlanetChange: function (res) {
|
||||||
if (this.state.planet == null) return
|
if (this.state.planet == null) return
|
||||||
|
|
||||||
@@ -207,6 +230,18 @@ module.exports = React.createClass({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var listElement = this.refs.list.refs.articles.getDOMNode()
|
||||||
|
var articleElement = listElement.querySelectorAll('li')[index]
|
||||||
|
|
||||||
|
var overflowBelow = listElement.clientHeight + listElement.scrollTop < articleElement.offsetTop + articleElement.clientHeight
|
||||||
|
if (overflowBelow) {
|
||||||
|
listElement.scrollTop = articleElement.offsetTop + articleElement.clientHeight - listElement.clientHeight
|
||||||
|
}
|
||||||
|
var overflowAbove = listElement.scrollTop > articleElement.offsetTop
|
||||||
|
if (overflowAbove) {
|
||||||
|
listElement.scrollTop = articleElement.offsetTop
|
||||||
|
}
|
||||||
|
|
||||||
if (article.type === 'code') {
|
if (article.type === 'code') {
|
||||||
params.localId = article.localId
|
params.localId = article.localId
|
||||||
this.transitionTo('codes', params)
|
this.transitionTo('codes', params)
|
||||||
@@ -237,9 +272,17 @@ module.exports = React.createClass({
|
|||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
this.selectArticleByListIndex(index - 1)
|
this.selectArticleByListIndex(index - 1)
|
||||||
} else {
|
} else {
|
||||||
React.findDOMNode(this).querySelector('.PlanetHeader .searchInput input').focus()
|
React.findDOMNode(this.refs.header.refs.search).focus()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
toggleFocusSearchInput: function () {
|
||||||
|
var search = React.findDOMNode(this.refs.header.refs.search)
|
||||||
|
if (document.activeElement === search) {
|
||||||
|
React.findDOMNode(this.refs.header.refs.search).blur()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
React.findDOMNode(this.refs.header.refs.search).focus()
|
||||||
|
},
|
||||||
handleSearchChange: function (e) {
|
handleSearchChange: function (e) {
|
||||||
this.setState({search: e.target.value}, function () {
|
this.setState({search: e.target.value}, function () {
|
||||||
this.selectArticleByListIndex(0)
|
this.selectArticleByListIndex(0)
|
||||||
@@ -309,9 +352,6 @@ module.exports = React.createClass({
|
|||||||
this.setState({search: '#' + tag})
|
this.setState({search: '#' + tag})
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
},
|
},
|
||||||
focus: function () {
|
|
||||||
React.findDOMNode(this).focus()
|
|
||||||
},
|
|
||||||
render: function () {
|
render: function () {
|
||||||
if (this.state.planet == null) return (<div/>)
|
if (this.state.planet == null) return (<div/>)
|
||||||
|
|
||||||
@@ -346,6 +386,7 @@ module.exports = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<div className='PlanetContainer'>
|
<div className='PlanetContainer'>
|
||||||
<PlanetHeader
|
<PlanetHeader
|
||||||
|
ref='header'
|
||||||
search={this.state.search}
|
search={this.state.search}
|
||||||
fetchPlanet={this.fetchPlanet}
|
fetchPlanet={this.fetchPlanet}
|
||||||
onSearchChange={this.handleSearchChange}
|
onSearchChange={this.handleSearchChange}
|
||||||
@@ -358,7 +399,8 @@ module.exports = React.createClass({
|
|||||||
showAll={this.showAll}
|
showAll={this.showAll}
|
||||||
toggleCodeFilter={this.toggleCodeFilter}
|
toggleCodeFilter={this.toggleCodeFilter}
|
||||||
toggleNoteFilter={this.toggleNoteFilter}
|
toggleNoteFilter={this.toggleNoteFilter}
|
||||||
planet={this.state.planet}/>
|
planet={this.state.planet}
|
||||||
|
currentUser={this.state.currentUser}/>
|
||||||
|
|
||||||
<PlanetArticleList showOnlyWithTag={this.applyTagFilter} ref='list' articles={filteredArticles}/>
|
<PlanetArticleList showOnlyWithTag={this.applyTagFilter} ref='list' articles={filteredArticles}/>
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ var Link = ReactRouter.Link
|
|||||||
|
|
||||||
var AuthFilter = require('../Mixins/AuthFilter')
|
var AuthFilter = require('../Mixins/AuthFilter')
|
||||||
var LinkedState = require('../Mixins/LinkedState')
|
var LinkedState = require('../Mixins/LinkedState')
|
||||||
|
var ExternalLink = require('../Mixins/ExternalLink')
|
||||||
var Hq = require('../Services/Hq')
|
var Hq = require('../Services/Hq')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [LinkedState, ReactRouter.Navigation, AuthFilter.OnlyGuest],
|
mixins: [LinkedState, ReactRouter.Navigation, AuthFilter.OnlyGuest, ExternalLink],
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
return {
|
return {
|
||||||
user: {},
|
user: {},
|
||||||
@@ -129,7 +130,7 @@ module.exports = React.createClass({
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<p className='alert'>会員登録することで、当サイトの利用規約及びCookieの使用を含むデータに関するポリシーに同意するものとします。</p>
|
<p className='alert'>会員登録することで、<a onClick={this.openExternal} href='http://boostio.github.io/regulations.html'>当サイトの利用規約</a>及び<a onClick={this.openExternal} href='http://boostio.github.io/privacypolicies.html'>Cookieの使用を含むデータに関するポリシー</a>に同意するものとします。</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ module.exports = React.createClass({
|
|||||||
return this.renderUserHome(currentUser)
|
return this.renderUserHome(currentUser)
|
||||||
}
|
}
|
||||||
} else if (this.isActive('planet') && user != null && user.userType === 'team') {
|
} else if (this.isActive('planet') && user != null && user.userType === 'team') {
|
||||||
console.log(user.Members)
|
|
||||||
var members = user.Members.map(function (member) {
|
var members = user.Members.map(function (member) {
|
||||||
return (
|
return (
|
||||||
<li key={'user-' + member.id}><Link to='userHome' params={{userName: member.name}}>
|
<li key={'user-' + member.id}><Link to='userHome' params={{userName: member.name}}>
|
||||||
@@ -224,7 +223,9 @@ module.exports = React.createClass({
|
|||||||
renderTeamHome: function (currentUser) {
|
renderTeamHome: function (currentUser) {
|
||||||
var user = this.state.user
|
var user = this.state.user
|
||||||
|
|
||||||
var isOwner = true
|
var isOwner = user.Members == null ? false : user.Members.some(function (member) {
|
||||||
|
return member.id === currentUser.id && member.TeamMember.role === 'owner'
|
||||||
|
})
|
||||||
|
|
||||||
var userPlanets = user.Planets.map(function (planet) {
|
var userPlanets = user.Planets.map(function (planet) {
|
||||||
return (
|
return (
|
||||||
@@ -258,7 +259,7 @@ module.exports = React.createClass({
|
|||||||
<div className='userName'>{user.name}</div>
|
<div className='userName'>{user.name}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onClick={this.openTeamSettingsModal} className='editProfileButton'>Team settings</button>
|
{isOwner ? (<button onClick={this.openTeamSettingsModal} className='editProfileButton'>Team settings</button>) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className='memberList'>
|
<div className='memberList'>
|
||||||
<div className='memberLabel'>{members.length} {members.length > 1 ? 'Members' : 'Member'}</div>
|
<div className='memberLabel'>{members.length} {members.length > 1 ? 'Members' : 'Member'}</div>
|
||||||
@@ -317,7 +318,7 @@ module.exports = React.createClass({
|
|||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
<div key={'user-' + team.id} className='planetGroup'>
|
<div key={'user-' + team.id} className='planetGroup'>
|
||||||
<div className='planetGroupLabel'>{team.name}</div>
|
<div className='planetGroupLabel'>{team.profileName} <small>@{team.name}</small></div>
|
||||||
<ul className='planets'>
|
<ul className='planets'>
|
||||||
{planets}
|
{planets}
|
||||||
{isOwner ? (<li><button onClick={this.openPlanetCreateModalWithOwnerName(team.name)} className='createPlanetButton'><i className='fa fa-plus-square-o'/> Create new planet</button></li>) : null}
|
{isOwner ? (<li><button onClick={this.openPlanetCreateModalWithOwnerName(team.name)} className='createPlanetButton'><i className='fa fa-plus-square-o'/> Create new planet</button></li>) : null}
|
||||||
@@ -352,7 +353,7 @@ module.exports = React.createClass({
|
|||||||
<div className='planetList'>
|
<div className='planetList'>
|
||||||
<div className='planetLabel'>{planetCount} {planetCount > 1 ? 'Planets' : 'Planet'}</div>
|
<div className='planetLabel'>{planetCount} {planetCount > 1 ? 'Planets' : 'Planet'}</div>
|
||||||
<div className='planetGroup'>
|
<div className='planetGroup'>
|
||||||
<div className='planetGroupLabel'>{user.profileName}</div>
|
<div className='planetGroupLabel'>{user.profileName} <small>@{user.name}</small></div>
|
||||||
<ul className='planets'>
|
<ul className='planets'>
|
||||||
{userPlanets}
|
{userPlanets}
|
||||||
{isOwner ? (<li><button onClick={this.openPlanetCreateModalWithOwnerName(user.name)} className='createPlanetButton'><i className='fa fa-plus-square-o'/> Create new planet</button></li>) : null}
|
{isOwner ? (<li><button onClick={this.openPlanetCreateModalWithOwnerName(user.name)} className='createPlanetButton'><i className='fa fa-plus-square-o'/> Create new planet</button></li>) : null}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
function deleteItemFromTargetArray (item, targetArray) {
|
function deleteItemFromTargetArray (item, targetArray) {
|
||||||
|
if (targetArray == null) targetArray = []
|
||||||
targetArray.some(function (_item, index) {
|
targetArray.some(function (_item, index) {
|
||||||
if (_item.id === item.id) {
|
if (_item.id === item.id) {
|
||||||
targetArray.splice(index, 1)
|
targetArray.splice(index, 1)
|
||||||
@@ -11,6 +12,8 @@ function deleteItemFromTargetArray (item, targetArray) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateItemToTargetArray (item, targetArray) {
|
function updateItemToTargetArray (item, targetArray) {
|
||||||
|
if (targetArray == null) targetArray = []
|
||||||
|
|
||||||
var isNew = !targetArray.some(function (_item, index) {
|
var isNew = !targetArray.some(function (_item, index) {
|
||||||
if (_item.id === item.id) {
|
if (_item.id === item.id) {
|
||||||
targetArray.splice(index, 1, item)
|
targetArray.splice(index, 1, item)
|
||||||
|
|||||||
100
browser/main/Mixins/KeyCaster.js
Normal file
100
browser/main/Mixins/KeyCaster.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
var Reflux = require('reflux')
|
||||||
|
|
||||||
|
var state = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var keyDown = Reflux.createAction()
|
||||||
|
|
||||||
|
var KeyStore = Reflux.createStore({
|
||||||
|
init: function () {
|
||||||
|
this.listenTo(keyDown, this.onKeyDown)
|
||||||
|
document.addEventListener('keydown', function (e) {
|
||||||
|
keyDown(e)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setState: function (newState, cb) {
|
||||||
|
for (var key in newState) {
|
||||||
|
state[key] = newState[key]
|
||||||
|
}
|
||||||
|
if (typeof cb === 'function') cb()
|
||||||
|
},
|
||||||
|
onKeyDown: function (e) {
|
||||||
|
/*
|
||||||
|
Modals
|
||||||
|
*/
|
||||||
|
if (state.codeForm || state.noteForm || state.noteDeleteModal || state.codeDeleteModal || state.addMemberModal || state.aboutModal || state.editProfileModal || state.contactModal || state.teamCreateModal || state.planetCreateModal || state.planetSettingModal || state.teamSettingsModal || state.logoutModal) {
|
||||||
|
// ESC
|
||||||
|
if (e.keyCode === 27) this.cast('closeModal')
|
||||||
|
|
||||||
|
// Cmd + Enter
|
||||||
|
if (e.keyCode === 13 && e.metaKey) {
|
||||||
|
if (state.codeForm) this.cast('submitCodeForm')
|
||||||
|
if (state.noteForm) this.cast('submitNoteForm')
|
||||||
|
if (state.codeDeleteModal) this.cast('submitCodeDeleteModal')
|
||||||
|
if (state.noteDeleteModal) this.cast('submitNoteDeleteModal')
|
||||||
|
if (state.addMemberModal) this.cast('submitAddMemberModal')
|
||||||
|
if (state.contactModal) this.cast('submitContactModal')
|
||||||
|
if (state.teamCreateModal) this.cast('submitTeamCreateModal')
|
||||||
|
if (state.planetCreateModal) this.cast('submitPlanetCreateModal')
|
||||||
|
if (state.logoutModal) this.cast('submitLogoutModal')
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
PlanetContainer
|
||||||
|
*/
|
||||||
|
if (state.planetContainer) {
|
||||||
|
// Cmd + Enter, A
|
||||||
|
if ((e.keyCode === 13 && e.metaKey) || e.keyCode === 65) this.cast('openLaunchModal')
|
||||||
|
|
||||||
|
// Esc
|
||||||
|
if (e.keyCode === 27) this.cast('toggleFocusSearchInput')
|
||||||
|
|
||||||
|
// Up
|
||||||
|
if (e.keyCode === 38) this.cast('selectPriorArticle')
|
||||||
|
|
||||||
|
// Down
|
||||||
|
if (e.keyCode === 40) this.cast('selectNextArticle')
|
||||||
|
|
||||||
|
// E
|
||||||
|
if (e.keyCode === 69) this.cast('openEditModal')
|
||||||
|
|
||||||
|
// D
|
||||||
|
if (e.keyCode === 68) this.cast('openDeleteModal')
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
HomeContainer
|
||||||
|
*/
|
||||||
|
if (state.homeContainer) {
|
||||||
|
if (e.keyCode > 48 && e.keyCode < 58 && e.metaKey) {
|
||||||
|
this.cast('switchPlanet', e.keyCode - 48)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cast: function (status, data) {
|
||||||
|
this.trigger({
|
||||||
|
status: status,
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = function (stateKey) {
|
||||||
|
return {
|
||||||
|
mixins: [Reflux.listenTo(KeyStore, 'onKeyCast')],
|
||||||
|
componentDidMount: function () {
|
||||||
|
var newState = {}
|
||||||
|
newState[stateKey] = true
|
||||||
|
KeyStore.setState(newState)
|
||||||
|
},
|
||||||
|
componentWillUnmount: function () {
|
||||||
|
var newState = {}
|
||||||
|
newState[stateKey] = false
|
||||||
|
KeyStore.setState(newState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,6 +35,9 @@ module.exports = {
|
|||||||
fetchUser: function (userName) {
|
fetchUser: function (userName) {
|
||||||
return request
|
return request
|
||||||
.get(apiUrl + 'resources/' + userName)
|
.get(apiUrl + 'resources/' + userName)
|
||||||
|
.set({
|
||||||
|
Authorization: 'Bearer ' + localStorage.getItem('token')
|
||||||
|
})
|
||||||
},
|
},
|
||||||
updateUser: function (userName, input) {
|
updateUser: function (userName, input) {
|
||||||
return request
|
return request
|
||||||
@@ -79,6 +82,9 @@ module.exports = {
|
|||||||
fetchPlanet: function (userName, planetName) {
|
fetchPlanet: function (userName, planetName) {
|
||||||
return request
|
return request
|
||||||
.get(apiUrl + 'resources/' + userName + '/planets/' + planetName)
|
.get(apiUrl + 'resources/' + userName + '/planets/' + planetName)
|
||||||
|
.set({
|
||||||
|
Authorization: 'Bearer ' + localStorage.getItem('token')
|
||||||
|
})
|
||||||
},
|
},
|
||||||
updatePlanet: function (userName, planetName, input) {
|
updatePlanet: function (userName, planetName, input) {
|
||||||
return request
|
return request
|
||||||
|
|||||||
@@ -53,6 +53,14 @@ module.exports = Reflux.createStore({
|
|||||||
localStorage.setItem('currentUser', JSON.stringify(currentUser))
|
localStorage.setItem('currentUser', JSON.stringify(currentUser))
|
||||||
UserStore.Actions.update(currentUser)
|
UserStore.Actions.update(currentUser)
|
||||||
|
|
||||||
|
planet.Codes.forEach(function (code) {
|
||||||
|
code.type = 'code'
|
||||||
|
})
|
||||||
|
|
||||||
|
planet.Notes.forEach(function (note) {
|
||||||
|
note.type = 'note'
|
||||||
|
})
|
||||||
|
|
||||||
// Update the planet
|
// Update the planet
|
||||||
localStorage.setItem('planet-' + planet.id, JSON.stringify(planet))
|
localStorage.setItem('planet-' + planet.id, JSON.stringify(planet))
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,55 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script>
|
|
||||||
var version = require('remote').getGlobal('version')
|
|
||||||
document.title = 'Boost ' + ((version == null || version.length === 0) ? 'DEV version' : 'v' + version)
|
|
||||||
</script>
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css" media="screen" title="no title" charset="utf-8">
|
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css" media="screen" title="no title" charset="utf-8">
|
||||||
<link rel="shortcut icon" href="favicon.ico">
|
<link rel="shortcut icon" href="favicon.ico">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Lato';
|
||||||
|
src: url('../../Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
|
||||||
|
url('../../Lato-Regular.woff') format('woff'), /* Modern Browsers */
|
||||||
|
url('../../Lato-Regular.ttf') format('truetype');
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
}
|
||||||
|
#loadingCover{
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 65px 0;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
#loadingCover img{
|
||||||
|
display: block;
|
||||||
|
margin: 75px auto 5px;
|
||||||
|
width: 160px;
|
||||||
|
height: 160px;
|
||||||
|
}
|
||||||
|
#loadingCover .message{
|
||||||
|
font-size: 30px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-weight: 100;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="loadingCover">
|
||||||
|
<img src="resources/favicon-230x230.png">
|
||||||
|
<div class='message'>Loading...</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content"></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
if (!Object.assign) {
|
if (!Object.assign) {
|
||||||
Object.defineProperty(Object, 'assign', {
|
Object.defineProperty(Object, 'assign', {
|
||||||
@@ -45,13 +84,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
require('electron-stylus')(__dirname + '/../styles/main/index.styl')
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="content"></div>
|
|
||||||
<script src="../ace/src-min/ace.js"></script>
|
<script src="../ace/src-min/ace.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
var version = require('remote').getGlobal('version')
|
||||||
|
document.title = 'Boost ' + ((version == null || version.length === 0) ? 'DEV version' : 'v' + version)
|
||||||
|
require('../electron-stylus')(__dirname + '/../styles/main/index.styl', 'mainCss')
|
||||||
require('node-jsx').install({ harmony: true, extension: '.jsx' })
|
require('node-jsx').install({ harmony: true, extension: '.jsx' })
|
||||||
require('./index.jsx')
|
require('./index.jsx')
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -34,7 +34,13 @@ var routes = (
|
|||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
)
|
)
|
||||||
|
var loadingCover = document.getElementById('loadingCover')
|
||||||
|
|
||||||
ReactRouter.run(routes, ReactRouter.HashLocation, function (Root) {
|
ReactRouter.run(routes, ReactRouter.HashLocation, function (Root) {
|
||||||
React.render(<Root/>, document.getElementById('content'))
|
React.render(<Root/>, document.getElementById('content'))
|
||||||
|
|
||||||
|
if (loadingCover != null) {
|
||||||
|
loadingCover.parentNode.removeChild(loadingCover)
|
||||||
|
loadingCover = null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ body
|
|||||||
border solid 2px transparent
|
border solid 2px transparent
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
cursor pointer
|
cursor pointer
|
||||||
|
white-space nowrap
|
||||||
|
overflow-x hidden
|
||||||
|
text-overflow ellipsis
|
||||||
.divider
|
.divider
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
border-bottom solid 1px borderColor
|
border-bottom solid 1px borderColor
|
||||||
@@ -65,6 +68,9 @@ body
|
|||||||
border-bottom solid 1px borderColor
|
border-bottom solid 1px borderColor
|
||||||
line-height 44px
|
line-height 44px
|
||||||
font-size 1.3em
|
font-size 1.3em
|
||||||
|
white-space nowrap
|
||||||
|
text-overflow ellipsis
|
||||||
|
overflow-x hidden
|
||||||
.content
|
.content
|
||||||
.ace_editor, .marked
|
.ace_editor, .marked
|
||||||
position absolute
|
position absolute
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ articleListWidth= 275px
|
|||||||
margin 0 2px
|
margin 0 2px
|
||||||
text-decoration underline
|
text-decoration underline
|
||||||
cursor pointer
|
cursor pointer
|
||||||
font-size 0.9em
|
font-size 0.95em
|
||||||
&.noTag
|
&.noTag
|
||||||
color inactiveTextColor
|
color inactiveTextColor
|
||||||
font-size 0.8em
|
font-size 0.8em
|
||||||
@@ -64,40 +64,35 @@ articleListWidth= 275px
|
|||||||
color inactiveColor
|
color inactiveColor
|
||||||
&:hover
|
&:hover
|
||||||
color textColor
|
color textColor
|
||||||
.privateTooltip
|
.tooltip
|
||||||
position fixed
|
tooltip()
|
||||||
z-index popupZIndex
|
|
||||||
background-color transparentify(invBackgroundColor, 80%)
|
|
||||||
color invTextColor
|
|
||||||
padding 10px
|
|
||||||
font-size 0.9em
|
|
||||||
line-height 0.9em
|
|
||||||
border-radius 5px
|
|
||||||
white-space nowrap
|
|
||||||
opacity 0
|
|
||||||
transition 0.1s
|
|
||||||
pointer-events none
|
|
||||||
margin-left -30px
|
margin-left -30px
|
||||||
&:hover .privateTooltip
|
&:hover .tooltip
|
||||||
opacity 1
|
opacity 1
|
||||||
|
|
||||||
|
|
||||||
.menuBtn
|
.planetSettingButton
|
||||||
position absolute
|
position absolute
|
||||||
top 12px
|
top 15px
|
||||||
right 5px
|
right 5px
|
||||||
font-size 1em
|
font-size 0.8em
|
||||||
btnDefault()
|
btnDefault()
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
circle()
|
circle()
|
||||||
width 33px
|
width 26px
|
||||||
height 33px
|
height 26px
|
||||||
text-align center
|
text-align center
|
||||||
cursor pointer
|
cursor pointer
|
||||||
transition 0.1s
|
transition 0.1s
|
||||||
transform scale(0.8)
|
|
||||||
&:focus, &.focus
|
&:focus, &.focus
|
||||||
outline none
|
outline none
|
||||||
|
.tooltip
|
||||||
|
tooltip()
|
||||||
|
margin-top 11px
|
||||||
|
margin-left -36px
|
||||||
|
&:hover .tooltip
|
||||||
|
opacity 1
|
||||||
|
|
||||||
.headerControl
|
.headerControl
|
||||||
noSelect()
|
noSelect()
|
||||||
absolute top bottom right
|
absolute top bottom right
|
||||||
@@ -118,10 +113,11 @@ articleListWidth= 275px
|
|||||||
.refreshButton
|
.refreshButton
|
||||||
display block
|
display block
|
||||||
position absolute
|
position absolute
|
||||||
top 12px
|
top 15px
|
||||||
right 55px
|
right 55px
|
||||||
width 28px
|
width 26px
|
||||||
height 28px
|
height 26px
|
||||||
|
font-size 0.8em
|
||||||
btnDefault()
|
btnDefault()
|
||||||
circle()
|
circle()
|
||||||
text-align center
|
text-align center
|
||||||
@@ -129,16 +125,28 @@ articleListWidth= 275px
|
|||||||
transition 0.1s
|
transition 0.1s
|
||||||
&:focus, &.focus
|
&:focus, &.focus
|
||||||
outline none
|
outline none
|
||||||
|
.tooltip
|
||||||
|
tooltip()
|
||||||
|
margin-top 11px
|
||||||
|
margin-left -39px
|
||||||
|
&:hover .tooltip
|
||||||
|
opacity 1
|
||||||
.logo
|
.logo
|
||||||
display block
|
display block
|
||||||
position absolute
|
position absolute
|
||||||
top 4px
|
top 4px
|
||||||
right 10px
|
right 10px
|
||||||
cursor pointer
|
cursor pointer
|
||||||
transition 0.1s
|
img
|
||||||
opacity 0.9
|
transition 0.1s
|
||||||
&:hover, &.hover
|
opacity 0.9
|
||||||
|
&:hover img, &:hover .tooltip
|
||||||
opacity 1
|
opacity 1
|
||||||
|
.tooltip
|
||||||
|
tooltip()
|
||||||
|
margin-top -5px
|
||||||
|
margin-left -67px
|
||||||
|
|
||||||
|
|
||||||
.PlanetNavigator
|
.PlanetNavigator
|
||||||
absolute bottom left
|
absolute bottom left
|
||||||
@@ -178,33 +186,51 @@ articleListWidth= 275px
|
|||||||
overflow-y auto
|
overflow-y auto
|
||||||
li
|
li
|
||||||
.articleItem
|
.articleItem
|
||||||
user-select none
|
noSelect()
|
||||||
border solid 2px transparent
|
border solid 2px transparent
|
||||||
padding 10px
|
position relative
|
||||||
|
height 94px
|
||||||
|
width 100%
|
||||||
cursor pointer
|
cursor pointer
|
||||||
transition 0.1s
|
transition 0.1s
|
||||||
clearfix()
|
|
||||||
.itemLeft
|
.itemLeft
|
||||||
float left
|
position absolute
|
||||||
width 25px
|
top 4px
|
||||||
|
bottom 4px
|
||||||
|
width 38px
|
||||||
|
padding 3px 0 3px 3px
|
||||||
text-align center
|
text-align center
|
||||||
.profileImage
|
.profileImage
|
||||||
margin-bottom 5px
|
margin-bottom 5px
|
||||||
|
circle()
|
||||||
.fa
|
.fa
|
||||||
line-height 25px
|
line-height 25px
|
||||||
.itemRight
|
.itemRight
|
||||||
float left
|
position absolute
|
||||||
width 225px
|
top 4px
|
||||||
|
bottom 4px
|
||||||
|
right 2px
|
||||||
|
left 40px
|
||||||
overflow-x hidden
|
overflow-x hidden
|
||||||
padding-left 10px
|
padding 3px 10px 3px 3px
|
||||||
.updatedAt
|
.itemInfo
|
||||||
margin-bottom 10px
|
margin 5px 0 13px
|
||||||
color lighten(textColor, 25%)
|
color lighten(textColor, 25%)
|
||||||
font-size 0.7em
|
font-size 0.7em
|
||||||
|
.userProfileName
|
||||||
|
color brandColor
|
||||||
|
font-size 1.2em
|
||||||
.description
|
.description
|
||||||
line-height 120%
|
line-height 120%
|
||||||
margin-bottom 15px
|
margin-bottom 10px
|
||||||
font-size 1em
|
font-size 1em
|
||||||
|
overflow-x hidden
|
||||||
|
white-space nowrap
|
||||||
|
text-overflow ellipsis
|
||||||
|
.tags
|
||||||
|
position absolute
|
||||||
|
bottom 5px
|
||||||
|
font-size 0.9em
|
||||||
&:hover, &.hover
|
&:hover, &.hover
|
||||||
background-color hoverBackgroundColor
|
background-color hoverBackgroundColor
|
||||||
&:active, &.active
|
&:active, &.active
|
||||||
@@ -218,57 +244,89 @@ articleListWidth= 275px
|
|||||||
absolute right bottom
|
absolute right bottom
|
||||||
top 55px
|
top 55px
|
||||||
left navigationWidth + articleListWidth
|
left navigationWidth + articleListWidth
|
||||||
&>.viewer-header
|
.detailHeader
|
||||||
height 44px
|
border solid 2px transparent
|
||||||
line-height 44px
|
position relative
|
||||||
padding 0 15px
|
height 105px
|
||||||
box-sizing border-box
|
width 100%
|
||||||
font-size 1.2em
|
transition 0.1s
|
||||||
small
|
.itemLeft
|
||||||
font-size 0.8em
|
position absolute
|
||||||
color lighten(textColor, 25%)
|
top 7px
|
||||||
.control-group
|
bottom 4px
|
||||||
float right
|
width 38px
|
||||||
button
|
padding 3px 0 3px 3px
|
||||||
margin 10px 3px
|
text-align center
|
||||||
.viewer-body
|
.profileImage
|
||||||
absolute bottom right
|
margin-bottom 5px
|
||||||
left 1px
|
circle()
|
||||||
top 44px
|
.fa
|
||||||
&.codeDetail>.viewer-body
|
line-height 25px
|
||||||
.viewer-detail
|
.itemRight
|
||||||
border-bottom solid 1px borderColor
|
position absolute
|
||||||
height 150px
|
top 7px
|
||||||
box-sizing border-box
|
bottom 4px
|
||||||
padding 10px
|
right 2px
|
||||||
|
left 40px
|
||||||
|
overflow-x hidden
|
||||||
|
padding 3px 10px 3px 3px
|
||||||
|
.itemInfo
|
||||||
|
margin 5px 0 13px
|
||||||
|
color lighten(textColor, 25%)
|
||||||
|
font-size 0.7em
|
||||||
|
.userProfileName
|
||||||
|
color brandColor
|
||||||
|
font-size 1.2em
|
||||||
.description
|
.description
|
||||||
height 100px
|
line-height 120%
|
||||||
line-height 1.4em
|
margin-bottom 10px
|
||||||
overflow-y auto
|
font-size 1em
|
||||||
|
overflow-x auto
|
||||||
|
white-space nowrap
|
||||||
.tags
|
.tags
|
||||||
position absolute
|
position absolute
|
||||||
left 15px
|
|
||||||
right 15px
|
|
||||||
top 120px
|
|
||||||
.content
|
|
||||||
.ace_editor
|
|
||||||
absolute left right
|
|
||||||
top 155px
|
|
||||||
bottom 5px
|
bottom 5px
|
||||||
&.noteDetail>.viewer-body
|
font-size 0.9em
|
||||||
.tags
|
.itemControl
|
||||||
absolute top
|
position absolute
|
||||||
left 15px
|
z-index 1
|
||||||
right 15px
|
top 2px
|
||||||
height 24px
|
right 2px
|
||||||
line-height 24px
|
.deleteButton, .editButton
|
||||||
|
btnDefault()
|
||||||
|
text-align center
|
||||||
|
width 33px
|
||||||
|
height 33px
|
||||||
|
border-radius 16.5px
|
||||||
|
font-size 15px
|
||||||
|
margin 0 3px
|
||||||
|
.tooltip
|
||||||
|
tooltip()
|
||||||
|
margin-top 10px
|
||||||
|
&:hover .tooltip
|
||||||
|
opacity 1
|
||||||
|
.editButton .tooltip
|
||||||
|
margin-left -12px
|
||||||
|
.deleteButton .tooltip
|
||||||
|
margin-left -26px
|
||||||
|
.detailBody
|
||||||
|
absolute left right bottom
|
||||||
|
top 105px
|
||||||
.content
|
.content
|
||||||
absolute left right bottom
|
position absolute
|
||||||
top 30px
|
top 5px
|
||||||
|
bottom 5px
|
||||||
|
left 2px
|
||||||
|
right 2px
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
padding 5px
|
padding 5px
|
||||||
border-top solid 1px borderColor
|
border-top solid 1px borderColor
|
||||||
padding 10px
|
&.noteDetail
|
||||||
|
.detailBody .content
|
||||||
overflow-x hidden
|
overflow-x hidden
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
marked()
|
marked()
|
||||||
|
&.codeDetail
|
||||||
|
.detailBody .content
|
||||||
|
.ace_editor
|
||||||
|
absolute left right top bottom
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
.HomeContainer
|
.HomeContainer
|
||||||
.HomeNavigator
|
.HomeNavigator
|
||||||
|
noSelect()
|
||||||
background-color planetNavBgColor
|
background-color planetNavBgColor
|
||||||
absolute left top bottom
|
absolute left top bottom
|
||||||
width 55px
|
width 55px
|
||||||
@@ -63,19 +64,12 @@
|
|||||||
&:hover
|
&:hover
|
||||||
background-color hoverBackgroundColor
|
background-color hoverBackgroundColor
|
||||||
.userName
|
.userName
|
||||||
float left
|
|
||||||
width 155px
|
width 155px
|
||||||
padding 10px 15px
|
padding 10px 15px
|
||||||
text-align left
|
text-align left
|
||||||
display block
|
display block
|
||||||
text-decoration none
|
text-decoration none
|
||||||
cursor pointer
|
cursor pointer
|
||||||
.userSetting
|
|
||||||
float right
|
|
||||||
display block
|
|
||||||
padding 10px 0
|
|
||||||
width 45px
|
|
||||||
cursor pointer
|
|
||||||
.createNewTeam
|
.createNewTeam
|
||||||
btnStripDefault()
|
btnStripDefault()
|
||||||
width 100%
|
width 100%
|
||||||
@@ -166,22 +160,11 @@
|
|||||||
border-color darken(brandBorderColor, 10%)
|
border-color darken(brandBorderColor, 10%)
|
||||||
background-color brandColor
|
background-color brandColor
|
||||||
color white
|
color white
|
||||||
.newPlanetTooltip
|
.tooltip
|
||||||
position fixed
|
tooltip()
|
||||||
z-index 500
|
margin-top -22px
|
||||||
background-color transparentify(invBackgroundColor, 80%)
|
|
||||||
color invTextColor
|
|
||||||
padding 10px
|
|
||||||
line-height 1em
|
|
||||||
border-radius 5px
|
|
||||||
margin-top -23px
|
|
||||||
margin-left 33px
|
margin-left 33px
|
||||||
white-space nowrap
|
&:hover .tooltip
|
||||||
font-size 1.1em
|
|
||||||
opacity 0
|
|
||||||
transition 0.1s
|
|
||||||
pointer-events none
|
|
||||||
&:hover .newPlanetTooltip
|
|
||||||
opacity 1
|
opacity 1
|
||||||
.UserContainer
|
.UserContainer
|
||||||
absolute top bottom right
|
absolute top bottom right
|
||||||
@@ -189,7 +172,7 @@
|
|||||||
.memberPopup
|
.memberPopup
|
||||||
absolute left
|
absolute left
|
||||||
top 235px
|
top 235px
|
||||||
z-index popupZIndex
|
z-index 1
|
||||||
padding 0 15px 10px
|
padding 0 15px 10px
|
||||||
width 200px
|
width 200px
|
||||||
.label
|
.label
|
||||||
@@ -205,13 +188,15 @@
|
|||||||
.memberImage
|
.memberImage
|
||||||
float left
|
float left
|
||||||
margin-right 7px
|
margin-right 7px
|
||||||
|
circle()
|
||||||
.memberInfo
|
.memberInfo
|
||||||
float left
|
float left
|
||||||
.memberProfileName
|
.memberProfileName
|
||||||
margin-bottom 5px
|
margin-bottom 5px
|
||||||
|
font-size 1.05em
|
||||||
.memberName
|
.memberName
|
||||||
margin-left 5px
|
margin-left 5px
|
||||||
font-size 0.8em
|
font-size 0.9em
|
||||||
color inactiveTextColor
|
color inactiveTextColor
|
||||||
a:hover .memberProfileName, a:hover .memberName
|
a:hover .memberProfileName, a:hover .memberName
|
||||||
text-decoration underline
|
text-decoration underline
|
||||||
@@ -259,9 +244,10 @@
|
|||||||
float left
|
float left
|
||||||
.teamProfileName
|
.teamProfileName
|
||||||
margin-bottom 5px
|
margin-bottom 5px
|
||||||
|
font-size 1.05em
|
||||||
.teamName
|
.teamName
|
||||||
margin-left 5px
|
margin-left 5px
|
||||||
font-size 0.8em
|
font-size 0.9em
|
||||||
color inactiveTextColor
|
color inactiveTextColor
|
||||||
a:hover .teamProfileName, a:hover .teamName
|
a:hover .teamProfileName, a:hover .teamName
|
||||||
text-decoration underline
|
text-decoration underline
|
||||||
@@ -277,16 +263,18 @@
|
|||||||
.memberImage
|
.memberImage
|
||||||
float left
|
float left
|
||||||
margin-right 7px
|
margin-right 7px
|
||||||
|
circle()
|
||||||
.memberInfo
|
.memberInfo
|
||||||
float left
|
float left
|
||||||
.memberProfileName
|
.memberProfileName
|
||||||
margin-bottom 5px
|
margin-bottom 5px
|
||||||
|
font-size 1.05em
|
||||||
.memberRole
|
.memberRole
|
||||||
font-size 0.8em
|
font-size 0.9em
|
||||||
color inactiveTextColor
|
color inactiveTextColor
|
||||||
.memberName
|
.memberName
|
||||||
margin-left 5px
|
margin-left 5px
|
||||||
font-size 0.8em
|
font-size 0.9em
|
||||||
color inactiveTextColor
|
color inactiveTextColor
|
||||||
.createTeamButton, .addMemberButton
|
.createTeamButton, .addMemberButton
|
||||||
btnStripDefault()
|
btnStripDefault()
|
||||||
@@ -306,6 +294,9 @@
|
|||||||
.planetGroupLabel
|
.planetGroupLabel
|
||||||
font-size 1.1em
|
font-size 1.1em
|
||||||
margin-bottom 15px
|
margin-bottom 15px
|
||||||
|
small
|
||||||
|
font-size 0.8em
|
||||||
|
color inactiveTextColor
|
||||||
.planets
|
.planets
|
||||||
margin-left 15px
|
margin-left 15px
|
||||||
li
|
li
|
||||||
|
|||||||
@@ -7,15 +7,17 @@ global-reset()
|
|||||||
@import './containers/*'
|
@import './containers/*'
|
||||||
|
|
||||||
html, body
|
html, body
|
||||||
width 100%
|
width 100%
|
||||||
height 100%
|
height 100%
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|
||||||
body
|
body
|
||||||
font-family "Lato"
|
font-family "Lato"
|
||||||
color textColor
|
color textColor
|
||||||
font-size fontSize
|
font-size fontSize
|
||||||
font-weight 400
|
font-weight 400
|
||||||
|
button
|
||||||
|
font-family "Lato"
|
||||||
|
|
||||||
div, span, a, button, input, textarea
|
div, span, a, button, input, textarea
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
@@ -105,14 +107,22 @@ textarea.block-input
|
|||||||
z-index 2000
|
z-index 2000
|
||||||
bottom 5px
|
bottom 5px
|
||||||
right 53px
|
right 53px
|
||||||
btnDefault()
|
btnPrimary()
|
||||||
padding 10px 15px
|
padding 10px 15px
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
|
background-color backgroundColor
|
||||||
.contactButton
|
.contactButton
|
||||||
position fixed
|
position fixed
|
||||||
z-index 2000
|
z-index 2000
|
||||||
bottom 5px
|
bottom 5px
|
||||||
right 5px
|
right 5px
|
||||||
btnDefault()
|
btnPrimary()
|
||||||
padding 10px 15px
|
padding 10px 15px
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
|
background-color backgroundColor
|
||||||
|
.tooltip
|
||||||
|
tooltip()
|
||||||
|
margin-top -22px
|
||||||
|
margin-left -97px
|
||||||
|
&:hover .tooltip
|
||||||
|
opacity 1
|
||||||
|
|||||||
@@ -22,10 +22,11 @@ marked()
|
|||||||
font-size 0.67em
|
font-size 0.67em
|
||||||
margin 2.33em auto
|
margin 2.33em auto
|
||||||
h1, h2, h3, h4, h5, h6
|
h1, h2, h3, h4, h5, h6
|
||||||
font-weight font-weight 400
|
font-weight 400
|
||||||
line-height 1.2em
|
line-height 1.4em
|
||||||
p
|
p
|
||||||
line-height 1.2em
|
line-height 1.4em
|
||||||
|
margin-bottom 15px
|
||||||
img
|
img
|
||||||
max-width 100%
|
max-width 100%
|
||||||
strong
|
strong
|
||||||
@@ -36,14 +37,14 @@ marked()
|
|||||||
text-decoration line-through
|
text-decoration line-through
|
||||||
blockquote
|
blockquote
|
||||||
border-left solid 4px brandBorderColor
|
border-left solid 4px brandBorderColor
|
||||||
margin 1em 0
|
margin 15px 0 15px
|
||||||
padding 0 25px
|
padding 0 25px
|
||||||
ul
|
ul
|
||||||
list-style-type disc
|
list-style-type disc
|
||||||
padding-left 35px
|
padding-left 35px
|
||||||
li
|
li
|
||||||
display list-item
|
display list-item
|
||||||
margin 0.5em 0
|
margin 15px 0
|
||||||
&>li>ul
|
&>li>ul
|
||||||
list-style-type circle
|
list-style-type circle
|
||||||
&>li>ul
|
&>li>ul
|
||||||
@@ -53,33 +54,38 @@ marked()
|
|||||||
padding-left 35px
|
padding-left 35px
|
||||||
li
|
li
|
||||||
display list-item
|
display list-item
|
||||||
margin 0.5em 0
|
margin 15px 0
|
||||||
code
|
code
|
||||||
font-family monospace
|
font-family monospace
|
||||||
padding 2px 4px
|
padding 2px 4px
|
||||||
border solid 1px borderColor
|
border solid 1px borderColor
|
||||||
border-radius 4px
|
border-radius 4px
|
||||||
font-size 0.9em
|
font-size 0.9em
|
||||||
|
color black
|
||||||
|
text-decoration none
|
||||||
|
background-color #F6F6F6
|
||||||
pre
|
pre
|
||||||
padding 5px
|
padding 5px
|
||||||
border solid 1px borderColor
|
border solid 1px borderColor
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
margin 0.5em 0
|
|
||||||
overflow-x auto
|
overflow-x auto
|
||||||
|
margin-bottom 15px
|
||||||
|
background-color #F6F6F6
|
||||||
&>code
|
&>code
|
||||||
padding 0
|
padding 0
|
||||||
border none
|
border none
|
||||||
border-radius 0
|
border-radius 0
|
||||||
|
color black
|
||||||
table
|
table
|
||||||
width 100%
|
width 100%
|
||||||
margin 15px 0
|
margin 15px 0 25px
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
background-color tableHeadBgColor
|
background-color tableHeadBgColor
|
||||||
th
|
th
|
||||||
border-style: solid;
|
border-style solid
|
||||||
padding: 5px;
|
padding 15px 5px
|
||||||
border-width: 1px 0 2px 1px;
|
border-width 1px 0 2px 1px
|
||||||
border-color borderColor
|
border-color borderColor
|
||||||
&:last-child
|
&:last-child
|
||||||
border-right solid 1px borderColor
|
border-right solid 1px borderColor
|
||||||
@@ -89,9 +95,9 @@ marked()
|
|||||||
tr:nth-child(2n)
|
tr:nth-child(2n)
|
||||||
background-color tableEvenBgColor
|
background-color tableEvenBgColor
|
||||||
td
|
td
|
||||||
border-style: solid;
|
border-style solid
|
||||||
padding: 5px;
|
padding 15px 5px
|
||||||
border-width: 0 0 1px 1px;
|
border-width 0 0 1px 1px
|
||||||
border-color borderColor
|
border-color borderColor
|
||||||
&:last-child
|
&:last-child
|
||||||
border-right solid 1px borderColor
|
border-right solid 1px borderColor
|
||||||
|
|||||||
13
browser/styles/mixins/tooltip.styl
Normal file
13
browser/styles/mixins/tooltip.styl
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
tooltip()
|
||||||
|
position fixed
|
||||||
|
z-index popupZIndex
|
||||||
|
background-color transparentify(invBackgroundColor, 80%)
|
||||||
|
color invTextColor
|
||||||
|
padding 10px
|
||||||
|
font-size 12px
|
||||||
|
line-height 12px
|
||||||
|
border-radius 5px
|
||||||
|
white-space nowrap
|
||||||
|
opacity 0
|
||||||
|
transition 0.1s
|
||||||
|
pointer-events none
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
float right
|
float right
|
||||||
padding 12px 10px
|
padding 12px 10px
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
width 200px
|
width 320px
|
||||||
font-size 1em
|
font-size 1em
|
||||||
overflow-x hidden
|
overflow-x hidden
|
||||||
white-space nowrap
|
white-space nowrap
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
float right
|
float right
|
||||||
padding 12px 10px
|
padding 12px 10px
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
width 200px
|
width 320px
|
||||||
font-size 1em
|
font-size 1em
|
||||||
overflow-x hidden
|
overflow-x hidden
|
||||||
white-space nowrap
|
white-space nowrap
|
||||||
@@ -196,7 +196,6 @@
|
|||||||
border-radius 5px
|
border-radius 5px
|
||||||
float left
|
float left
|
||||||
|
|
||||||
|
|
||||||
.LaunchModal
|
.LaunchModal
|
||||||
.modal-tab
|
.modal-tab
|
||||||
text-align center
|
text-align center
|
||||||
@@ -314,6 +313,14 @@
|
|||||||
height 55px
|
height 55px
|
||||||
circle()
|
circle()
|
||||||
btnPrimary()
|
btnPrimary()
|
||||||
|
.errorAlert
|
||||||
|
alertError()
|
||||||
|
padding 12px 10px
|
||||||
|
border-radius 5px
|
||||||
|
text-align center
|
||||||
|
display block
|
||||||
|
width 360px
|
||||||
|
margin 0 auto 15px
|
||||||
|
|
||||||
.ContactModal
|
.ContactModal
|
||||||
padding 15px
|
padding 15px
|
||||||
@@ -341,6 +348,7 @@
|
|||||||
padding 0 15px
|
padding 0 15px
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
margin-left 5px
|
margin-left 5px
|
||||||
|
font-size 1em
|
||||||
button.sendButton
|
button.sendButton
|
||||||
btnPrimary()
|
btnPrimary()
|
||||||
.confirmation
|
.confirmation
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
apiUrl: 'http://codexen-server-dev2.elasticbeanstalk.com/'
|
apiUrl: 'https://api.b00st.io/'
|
||||||
// apiUrl: 'http://localhost:8000/'
|
// apiUrl: 'http://localhost:8000/'
|
||||||
}
|
}
|
||||||
|
|||||||
26
main.js
26
main.js
@@ -27,6 +27,7 @@ var path = require('path')
|
|||||||
|
|
||||||
autoUpdater
|
autoUpdater
|
||||||
.on('error', function (err, message) {
|
.on('error', function (err, message) {
|
||||||
|
console.error(message)
|
||||||
nn.notify({
|
nn.notify({
|
||||||
title: 'Error! ' + versionText,
|
title: 'Error! ' + versionText,
|
||||||
icon: path.join(__dirname, 'browser/main/resources/favicon-230x230.png'),
|
icon: path.join(__dirname, 'browser/main/resources/favicon-230x230.png'),
|
||||||
@@ -34,11 +35,7 @@ autoUpdater
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.on('checking-for-update', function () {
|
.on('checking-for-update', function () {
|
||||||
nn.notify({
|
// Connecting
|
||||||
title: 'Boost launched!! ' + versionText,
|
|
||||||
icon: path.join(__dirname, 'browser/main/resources/favicon-230x230.png'),
|
|
||||||
message: 'Checking update is available....'
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.on('update-available', function () {
|
.on('update-available', function () {
|
||||||
nn.notify({
|
nn.notify({
|
||||||
@@ -85,7 +82,7 @@ app.on('ready', function () {
|
|||||||
Menu.setApplicationMenu(menu)
|
Menu.setApplicationMenu(menu)
|
||||||
// menu end
|
// menu end
|
||||||
appIcon = new Tray(__dirname + '/tray-icon.png')
|
appIcon = new Tray(__dirname + '/tray-icon.png')
|
||||||
appIcon.setToolTip('Codexen')
|
appIcon.setToolTip('Boost')
|
||||||
|
|
||||||
var trayMenu = new Menu()
|
var trayMenu = new Menu()
|
||||||
trayMenu.append(new MenuItem({
|
trayMenu.append(new MenuItem({
|
||||||
@@ -131,9 +128,10 @@ app.on('ready', function () {
|
|||||||
'zoom-factor': 1.0,
|
'zoom-factor': 1.0,
|
||||||
'always-on-top': true,
|
'always-on-top': true,
|
||||||
'web-preferences': {
|
'web-preferences': {
|
||||||
'overlay-scrollbars': true,
|
'overlay-scrollbars': true,
|
||||||
'skip-taskbar': true
|
'skip-taskbar': true
|
||||||
}
|
},
|
||||||
|
'standard-window': false
|
||||||
})
|
})
|
||||||
|
|
||||||
popUpWindow.loadUrl('file://' + __dirname + '/browser/finder/index.electron.html')
|
popUpWindow.loadUrl('file://' + __dirname + '/browser/finder/index.electron.html')
|
||||||
@@ -141,6 +139,7 @@ app.on('ready', function () {
|
|||||||
popUpWindow.on('blur', function () {
|
popUpWindow.on('blur', function () {
|
||||||
popUpWindow.hide()
|
popUpWindow.hide()
|
||||||
})
|
})
|
||||||
|
|
||||||
popUpWindow.setVisibleOnAllWorkspaces(true)
|
popUpWindow.setVisibleOnAllWorkspaces(true)
|
||||||
|
|
||||||
var globalShortcut = require('global-shortcut')
|
var globalShortcut = require('global-shortcut')
|
||||||
@@ -167,8 +166,9 @@ function makeNewMainWindow () {
|
|||||||
height: 720,
|
height: 720,
|
||||||
'zoom-factor': 1.0,
|
'zoom-factor': 1.0,
|
||||||
'web-preferences': {
|
'web-preferences': {
|
||||||
'overlay-scrollbars': true
|
'overlay-scrollbars': true
|
||||||
}
|
},
|
||||||
|
'standard-window': false
|
||||||
})
|
})
|
||||||
if (update != null) {
|
if (update != null) {
|
||||||
mainWindow.webContents.on('did-finish-load', function () {
|
mainWindow.webContents.on('did-finish-load', function () {
|
||||||
@@ -178,6 +178,10 @@ function makeNewMainWindow () {
|
|||||||
|
|
||||||
mainWindow.loadUrl('file://' + __dirname + '/browser/main/index.electron.html')
|
mainWindow.loadUrl('file://' + __dirname + '/browser/main/index.electron.html')
|
||||||
|
|
||||||
|
mainWindow.webContents.on('new-window', function (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
})
|
||||||
|
|
||||||
mainWindow.on('closed', function () {
|
mainWindow.on('closed', function () {
|
||||||
console.log('main closed')
|
console.log('main closed')
|
||||||
mainWindow = null
|
mainWindow = null
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ module.exports = [
|
|||||||
label: 'Electron',
|
label: 'Electron',
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'About Electron',
|
label: 'About Boost',
|
||||||
selector: 'orderFrontStandardAboutPanel:'
|
selector: 'orderFrontStandardAboutPanel:'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -89,13 +89,13 @@ module.exports = [
|
|||||||
click: function () {
|
click: function () {
|
||||||
BrowserWindow.getFocusedWindow().reload()
|
BrowserWindow.getFocusedWindow().reload()
|
||||||
}
|
}
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
label: 'Toggle DevTools',
|
// label: 'Toggle DevTools',
|
||||||
accelerator: 'Alt+Command+I',
|
// accelerator: 'Alt+Command+I',
|
||||||
click: function () {
|
// click: function () {
|
||||||
BrowserWindow.getFocusedWindow().toggleDevTools()
|
// BrowserWindow.getFocusedWindow().toggleDevTools()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "boost",
|
"name": "boost",
|
||||||
"version": "0.2.1",
|
"version": "0.2.9",
|
||||||
"description": "Boost App",
|
"description": "Boost App",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -31,7 +31,6 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/Rokt33r/codexen-app#readme",
|
"homepage": "https://github.com/Rokt33r/codexen-app#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"electron-stylus": "^0.1.0",
|
|
||||||
"font-awesome": "^4.3.0",
|
"font-awesome": "^4.3.0",
|
||||||
"markdown-it": "^4.3.1",
|
"markdown-it": "^4.3.1",
|
||||||
"md5": "^2.0.0",
|
"md5": "^2.0.0",
|
||||||
@@ -43,6 +42,7 @@
|
|||||||
"react-router": "^0.13.3",
|
"react-router": "^0.13.3",
|
||||||
"react-select": "^0.5.4",
|
"react-select": "^0.5.4",
|
||||||
"reflux": "^0.2.8",
|
"reflux": "^0.2.8",
|
||||||
|
"stylus": "^0.52.0",
|
||||||
"superagent": "^1.2.0",
|
"superagent": "^1.2.0",
|
||||||
"superagent-promise": "^1.0.3"
|
"superagent-promise": "^1.0.3"
|
||||||
},
|
},
|
||||||
|
|||||||
BIN
tray-icon.png
BIN
tray-icon.png
Binary file not shown.
|
Before Width: | Height: | Size: 463 B After Width: | Height: | Size: 959 B |
BIN
tray-icon@2x.png
BIN
tray-icon@2x.png
Binary file not shown.
|
Before Width: | Height: | Size: 924 B After Width: | Height: | Size: 2.2 KiB |
BIN
tray-icon@4x.png
BIN
tray-icon@4x.png
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 KiB |
Reference in New Issue
Block a user