diff --git a/browser/main/Components/AboutModal.jsx b/browser/main/Components/AboutModal.jsx
index 53ffc253..d95254d5 100644
--- a/browser/main/Components/AboutModal.jsx
+++ b/browser/main/Components/AboutModal.jsx
@@ -4,12 +4,20 @@ var version = remote.getGlobal('version')
var React = require('react/addons')
var ExternalLink = require('../Mixins/ExternalLink')
+var KeyCaster = require('../Mixins/KeyCaster')
module.exports = React.createClass({
- mixins: [ExternalLink],
+ mixins: [ExternalLink, KeyCaster('aboutModal')],
propTypes: {
close: React.PropTypes.func
},
+ onKeyCast: function (e) {
+ switch (e.status) {
+ case 'closeModal':
+ this.props.close()
+ break
+ }
+ },
render: function () {
return (
diff --git a/browser/main/Components/AddMemberModal.jsx b/browser/main/Components/AddMemberModal.jsx
index e96f2b47..7b682156 100644
--- a/browser/main/Components/AddMemberModal.jsx
+++ b/browser/main/Components/AddMemberModal.jsx
@@ -5,6 +5,8 @@ var LinkedState = require('../Mixins/LinkedState')
var Hq = require('../Services/Hq')
+var KeyCaster = require('../Mixins/KeyCaster')
+
var UserStore = require('../Stores/UserStore')
var getOptions = function (input, callback) {
@@ -26,7 +28,7 @@ var getOptions = function (input, callback) {
}
module.exports = React.createClass({
- mixins: [LinkedState],
+ mixins: [LinkedState, KeyCaster('addMemberModal')],
propTypes: {
team: React.PropTypes.object,
close: React.PropTypes.func
@@ -37,6 +39,16 @@ module.exports = React.createClass({
role: 'member'
}
},
+ onKeyCast: function (e) {
+ switch (e.status) {
+ case 'closeModal':
+ this.props.close()
+ break
+ case 'submitAddMemberModal':
+ this.handleSubmit()
+ break
+ }
+ },
handleSubmit: function () {
Hq
.addMember(this.props.team.name, {
diff --git a/browser/main/Components/CodeDeleteModal.jsx b/browser/main/Components/CodeDeleteModal.jsx
index dd9503bf..b7dbc147 100644
--- a/browser/main/Components/CodeDeleteModal.jsx
+++ b/browser/main/Components/CodeDeleteModal.jsx
@@ -2,19 +2,26 @@ var React = require('react')
var Hq = require('../Services/Hq')
+var KeyCaster = require('../Mixins/KeyCaster')
+
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
+ mixins: [KeyCaster('codeDeleteModal')],
propTypes: {
planet: React.PropTypes.object,
code: React.PropTypes.object,
close: React.PropTypes.func
},
- componentDidMount: function () {
- React.findDOMNode(this).focus()
- },
- stopPropagation: function (e) {
- e.stopPropagation()
+ onKeyCast: function (e) {
+ switch (e.status) {
+ case 'submitCodeDeleteModal':
+ this.submit()
+ break
+ case 'closeModal':
+ this.props.close()
+ break
+ }
},
submit: function () {
var planet = this.props.planet
diff --git a/browser/main/Components/CodeEditModal.jsx b/browser/main/Components/CodeEditModal.jsx
index 8877cafa..7b070db6 100644
--- a/browser/main/Components/CodeEditModal.jsx
+++ b/browser/main/Components/CodeEditModal.jsx
@@ -7,13 +7,19 @@ module.exports = React.createClass({
code: 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 () {
return (
)
}
diff --git a/browser/main/Components/CodeEditor.jsx b/browser/main/Components/CodeEditor.jsx
index 6cf3a4a7..4402ecd2 100644
--- a/browser/main/Components/CodeEditor.jsx
+++ b/browser/main/Components/CodeEditor.jsx
@@ -6,6 +6,7 @@ module.exports = React.createClass({
propTypes: {
code: React.PropTypes.string,
mode: React.PropTypes.string,
+ className: React.PropTypes.string,
onChange: React.PropTypes.func
},
componentDidMount: function () {
@@ -52,7 +53,7 @@ module.exports = React.createClass({
},
render: function () {
return (
-
+
)
}
})
diff --git a/browser/main/Components/CodeForm.jsx b/browser/main/Components/CodeForm.jsx
index e80dc6af..47f1a75b 100644
--- a/browser/main/Components/CodeForm.jsx
+++ b/browser/main/Components/CodeForm.jsx
@@ -5,6 +5,7 @@ var Select = require('react-select')
var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
+var KeyCaster = require('../Mixins/KeyCaster')
var PlanetStore = require('../Stores/PlanetStore')
@@ -29,7 +30,7 @@ var getOptions = function (input, callback) {
}
module.exports = React.createClass({
- mixins: [LinkedState],
+ mixins: [LinkedState, KeyCaster('codeForm')],
propTypes: {
planet: React.PropTypes.object,
close: React.PropTypes.func,
@@ -55,6 +56,16 @@ module.exports = React.createClass({
code: code
}
},
+ onKeyCast: function (e) {
+ switch (e.status) {
+ case 'submitCodeForm':
+ this.submit()
+ break
+ case 'closeModal':
+ this.props.close()
+ break
+ }
+ },
handleModeChange: function (selected) {
var code = this.state.code
code.mode = selected
diff --git a/browser/main/Components/CodeViewer.jsx b/browser/main/Components/CodeViewer.jsx
index bd20fe2f..6818490b 100644
--- a/browser/main/Components/CodeViewer.jsx
+++ b/browser/main/Components/CodeViewer.jsx
@@ -5,7 +5,8 @@ var ace = window.ace
module.exports = React.createClass({
propTypes: {
code: React.PropTypes.string,
- mode: React.PropTypes.string
+ mode: React.PropTypes.string,
+ className: React.PropTypes.string
},
componentDidMount: function () {
var el = React.findDOMNode(this.refs.target)
@@ -46,7 +47,7 @@ module.exports = React.createClass({
},
render: function () {
return (
-
+
)
}
})
diff --git a/browser/main/Components/ContactModal.jsx b/browser/main/Components/ContactModal.jsx
index 5fc7cc84..e2818f06 100644
--- a/browser/main/Components/ContactModal.jsx
+++ b/browser/main/Components/ContactModal.jsx
@@ -1,11 +1,12 @@
var React = require('react')
var LinkedState = require('../Mixins/LinkedState')
+var KeyCaster = require('../Mixins/KeyCaster')
var Hq = require('../Services/Hq')
module.exports = React.createClass({
- mixins: [LinkedState],
+ mixins: [LinkedState, KeyCaster('contactModal')],
propTypes: {
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 () {
Hq.sendEmail(this.state.mail)
.then(function (res) {
@@ -36,7 +54,7 @@ module.exports = React.createClass({
-
+
diff --git a/browser/main/Components/EditProfileModal.jsx b/browser/main/Components/EditProfileModal.jsx
index cf9e8c86..c128ab9a 100644
--- a/browser/main/Components/EditProfileModal.jsx
+++ b/browser/main/Components/EditProfileModal.jsx
@@ -5,17 +5,19 @@ var React = require('react/addons')
var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
+var KeyCaster = require('../Mixins/KeyCaster')
var UserStore = require('../Stores/UserStore')
module.exports = React.createClass({
- mixins: [LinkedState],
+ mixins: [LinkedState, KeyCaster('editProfileModal')],
propTypes: {
user: React.PropTypes.shape({
name: React.PropTypes.string,
profileName: React.PropTypes.string,
email: React.PropTypes.string
- })
+ }),
+ close: React.PropTypes.func
},
getInitialState: function () {
var user = this.props.user
@@ -34,6 +36,13 @@ module.exports = React.createClass({
passwordSubmitStatus: null
}
},
+ onKeyCast: function (e) {
+ switch (e.status) {
+ case 'closeModal':
+ this.props.close()
+ break
+ }
+ },
selectTab: function (tabName) {
return function () {
this.setState({currentTab: tabName})
diff --git a/browser/main/Components/HomeNavigator.jsx b/browser/main/Components/HomeNavigator.jsx
index c39e31f4..c4ba5ca5 100644
--- a/browser/main/Components/HomeNavigator.jsx
+++ b/browser/main/Components/HomeNavigator.jsx
@@ -96,6 +96,10 @@ module.exports = React.createClass({
handleLogoutClick: function () {
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 () {
var params = this.getParams()
@@ -110,12 +114,12 @@ module.exports = React.createClass({
return team.Planets == null ? planets : planets.concat(team.Planets)
}, []))).map(function (planet, index) {
return (
-
+
{planet.name[0]}
{planet.userName}/{planet.name}
- ⌘{index + 1}
+ {index < 9 ? (⌘{index + 1}
) : null}
)
})
@@ -128,12 +132,12 @@ module.exports = React.createClass({
{popup}
-
+
)
diff --git a/browser/main/Components/LaunchModal.jsx b/browser/main/Components/LaunchModal.jsx
index 649404db..f7bc3bb4 100644
--- a/browser/main/Components/LaunchModal.jsx
+++ b/browser/main/Components/LaunchModal.jsx
@@ -15,34 +15,52 @@ module.exports = React.createClass({
}
},
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) {
- e.stopPropagation()
- },
- selectCodeTab: function () {
- this.setState({currentTab: 'code'})
- },
- selectNoteTab: function () {
- this.setState({currentTab: 'note'})
+ componentWillUnmount: function () {
+ React.findDOMNode(this.refs.codeButton).removeEventListener('keydown', this.handleKeyDown)
+ React.findDOMNode(this.refs.noteButton).removeEventListener('keydown', this.handleKeyDown)
},
handleKeyDown: function (e) {
if (e.keyCode === 37 && e.metaKey) {
this.selectCodeTab()
+ e.stopPropagation()
+ return
}
if (e.keyCode === 39 && e.metaKey) {
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 () {
var modalBody
if (this.state.currentTab === 'code') {
modalBody = (
-
+
)
} else {
modalBody = (
-
+
)
}
@@ -50,7 +68,8 @@ module.exports = React.createClass({
{modalBody}
diff --git a/browser/main/Components/LogoutModal.jsx b/browser/main/Components/LogoutModal.jsx
index 9a6e542d..0ce9ca87 100644
--- a/browser/main/Components/LogoutModal.jsx
+++ b/browser/main/Components/LogoutModal.jsx
@@ -2,11 +2,24 @@
var React = require('react')
+var KeyCaster = require('../Mixins/KeyCaster')
+
module.exports = React.createClass({
+ mixins: [KeyCaster('logoutModal')],
propTypes: {
transitionTo: 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 () {
localStorage.removeItem('currentUser')
localStorage.removeItem('token')
diff --git a/browser/main/Components/NoteDeleteModal.jsx b/browser/main/Components/NoteDeleteModal.jsx
index 841b5291..4d6702c7 100644
--- a/browser/main/Components/NoteDeleteModal.jsx
+++ b/browser/main/Components/NoteDeleteModal.jsx
@@ -2,16 +2,26 @@ var React = require('react')
var Hq = require('../Services/Hq')
+var KeyCaster = require('../Mixins/KeyCaster')
+
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
+ mixins: [KeyCaster('noteDeleteModal')],
propTypes: {
planet: React.PropTypes.object,
note: React.PropTypes.object,
close: React.PropTypes.func
},
- componentDidMount: function () {
- React.findDOMNode(this).focus()
+ onKeyCast: function (e) {
+ switch (e.status) {
+ case 'submitNoteDeleteModal':
+ this.submit()
+ break
+ case 'closeModal':
+ this.props.close()
+ break
+ }
},
submit: function () {
var planet = this.props.planet
diff --git a/browser/main/Components/NoteEditModal.jsx b/browser/main/Components/NoteEditModal.jsx
index 458b57ea..cfea0469 100644
--- a/browser/main/Components/NoteEditModal.jsx
+++ b/browser/main/Components/NoteEditModal.jsx
@@ -8,13 +8,19 @@ module.exports = React.createClass({
note: 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 () {
return (
)
}
diff --git a/browser/main/Components/NoteForm.jsx b/browser/main/Components/NoteForm.jsx
index 0f805dbb..a3246492 100644
--- a/browser/main/Components/NoteForm.jsx
+++ b/browser/main/Components/NoteForm.jsx
@@ -1,11 +1,11 @@
var React = require('react/addons')
-var ReactRouter = require('react-router')
var Select = require('react-select')
var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
var Markdown = require('../Mixins/Markdown')
+var KeyCaster = require('../Mixins/KeyCaster')
var PlanetStore = require('../Stores/PlanetStore')
@@ -34,7 +34,7 @@ var EDIT_MODE = 0
var PREVIEW_MODE = 1
module.exports = React.createClass({
- mixins: [LinkedState, Markdown],
+ mixins: [LinkedState, Markdown, KeyCaster('noteForm')],
propTypes: {
planet: React.PropTypes.object,
close: React.PropTypes.func,
@@ -58,8 +58,15 @@ module.exports = React.createClass({
mode: EDIT_MODE
}
},
- componentDidMount: function () {
- React.findDOMNode(this.refs.title).focus()
+ onKeyCast: function (e) {
+ switch (e.status) {
+ case 'submitNoteForm':
+ this.submit()
+ break
+ case 'closeModal':
+ this.props.close()
+ break
+ }
},
handleTagsChange: function (selected, all) {
var note = this.state.note
diff --git a/browser/main/Components/PlanetArticleDetail.jsx b/browser/main/Components/PlanetArticleDetail.jsx
index a01c64c7..23ff9761 100644
--- a/browser/main/Components/PlanetArticleDetail.jsx
+++ b/browser/main/Components/PlanetArticleDetail.jsx
@@ -25,6 +25,7 @@ module.exports = React.createClass({
}
},
openEditModal: function () {
+ if (this.props.article == null) return
switch (this.props.article.type) {
case 'code' :
this.openModal(CodeEditModal, {code: this.props.article, planet: this.props.planet})
@@ -34,6 +35,7 @@ module.exports = React.createClass({
}
},
openDeleteModal: function () {
+ if (this.props.article == null) return
switch (this.props.article.type) {
case 'code' :
this.openModal(CodeDeleteModal, {code: this.props.article, planet: this.props.planet})
@@ -74,14 +76,18 @@ module.exports = React.createClass({
-
-
+
+
)
@@ -101,8 +107,14 @@ module.exports = React.createClass({
diff --git a/browser/main/Components/PlanetArticleList.jsx b/browser/main/Components/PlanetArticleList.jsx
index ddde09fa..b0772475 100644
--- a/browser/main/Components/PlanetArticleList.jsx
+++ b/browser/main/Components/PlanetArticleList.jsx
@@ -1,6 +1,5 @@
var React = require('react/addons')
var ReactRouter = require('react-router')
-var Link = ReactRouter.Link
var moment = require('moment')
var ForceUpdate = require('../Mixins/ForceUpdate')
@@ -16,9 +15,10 @@ module.exports = React.createClass({
},
handleArticleClikck: function (article) {
if (article.type === 'code') {
- return function () {
+ return function (e) {
var params = this.getParams()
+ document.getElementById('articleEditButton').focus()
this.transitionTo('codes', {
userName: params.userName,
planetName: params.planetName,
@@ -28,9 +28,10 @@ module.exports = React.createClass({
}
if (article.type === 'note') {
- return function () {
+ return function (e) {
var params = this.getParams()
+ document.getElementById('articleEditButton').focus()
this.transitionTo('notes', {
userName: params.userName,
planetName: params.planetName,
@@ -51,8 +52,6 @@ module.exports = React.createClass({
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 handleClick
-
if (article.type === 'code') {
return (
@@ -94,7 +93,7 @@ module.exports = React.createClass({
return (
diff --git a/browser/main/Components/PlanetCreateModal.jsx b/browser/main/Components/PlanetCreateModal.jsx
index 974a06a7..2d396705 100644
--- a/browser/main/Components/PlanetCreateModal.jsx
+++ b/browser/main/Components/PlanetCreateModal.jsx
@@ -5,11 +5,12 @@ var React = require('react/addons')
var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
+var KeyCaster = require('../Mixins/KeyCaster')
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
- mixins: [LinkedState],
+ mixins: [LinkedState, KeyCaster('planetCreateModal')],
propTypes: {
ownerName: React.PropTypes.string,
transitionTo: React.PropTypes.func,
@@ -30,9 +31,14 @@ module.exports = React.createClass({
componentDidMount: function () {
React.findDOMNode(this.refs.name).focus()
},
- onListen: function (res) {
- if (res.status === 'planetCreated') {
- this.props.close()
+ onKeyCast: function (e) {
+ switch (e.status) {
+ case 'closeModal':
+ this.props.close()
+ break
+ case 'submitPlanetCreateModal':
+ this.handleSubmit()
+ break
}
},
handleSubmit: function () {
diff --git a/browser/main/Components/PlanetHeader.jsx b/browser/main/Components/PlanetHeader.jsx
index 279f3629..101b2a3b 100644
--- a/browser/main/Components/PlanetHeader.jsx
+++ b/browser/main/Components/PlanetHeader.jsx
@@ -21,7 +21,21 @@ module.exports = React.createClass({
}
},
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()
+ }
+ if (e.keyCode !== 27 && (e.keyCode !== 13 || !e.metaKey)) {
+ e.stopPropagation()
+ }
},
openPlanetSettingModal: function () {
this.openModal(PlanetSettingModal, {planet: this.props.currentPlanet})
@@ -42,12 +56,13 @@ module.exports = React.createClass({
{this.props.currentPlanet.public ? null : (
-
Private planet
+
Private planet
)}
-