/* global localStorage*/ 'strict' var React = require('react/addons') var ReactRouter = require('react-router') var Reflux = require('reflux') var PlanetHeader = require('../Components/PlanetHeader') var PlanetNavigator = require('../Components/PlanetNavigator') var PlanetArticleList = require('../Components/PlanetArticleList') var PlanetArticleDetail = require('../Components/PlanetArticleDetail') var Hq = require('../Services/Hq') var Modal = require('../Mixins/Modal') var ArticleFilter = require('../Mixins/ArticleFilter') var Helper = require('../Mixins/Helper') var KeyCaster = require('../Mixins/KeyCaster') var UserStore = require('../Stores/UserStore') var PlanetStore = require('../Stores/PlanetStore') module.exports = React.createClass({ mixins: [ReactRouter.Navigation, ReactRouter.State, Modal, Reflux.listenTo(UserStore, 'onUserChange'), Reflux.listenTo(PlanetStore, 'onPlanetChange'), ArticleFilter, Helper, KeyCaster('planetContainer')], propTypes: { params: React.PropTypes.object, planetName: React.PropTypes.string }, getInitialState: function () { return { currentUser: JSON.parse(localStorage.getItem('currentUser')), planet: null, search: '' } }, componentDidMount: function () { this.fetchPlanet(this.props.params.userName, this.props.params.planetName) }, componentDidUpdate: function () { if (this.isActive('planetHome') && this.refs.list != null && this.refs.list.props.articles.length > 0) { var article = this.refs.list.props.articles[0] var planet = this.state.planet switch (article.type) { case 'code': this.transitionTo('codes', {userName: planet.Owner.name, planetName: planet.name, localId: article.localId}) break case 'note': this.transitionTo('notes', {userName: planet.Owner.name, planetName: planet.name, localId: article.localId}) break } } }, componentWillReceiveProps: function (nextProps) { if (this.state.planet == null) { this.fetchPlanet(nextProps.params.userName, nextProps.params.planetName) return } if (nextProps.params.userName !== this.state.planet.Owner.name || nextProps.params.planetName !== this.state.planet.name) { this.setState({ planet: null }, function () { this.fetchPlanet(nextProps.params.userName, nextProps.params.planetName) }) } }, 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) { if (this.state.planet == null) return var planet, code, note, articleIndex, articlesCount switch (res.status) { case 'updated': planet = res.data if (this.state.planet.id === planet.id) { if (this.state.planet.name === planet.name) { this.setState({planet: planet}) } else { this.transitionTo('planetHome', {userName: planet.Owner.name, planetName: planet.name}) } } break case 'destroyed': planet = res.data if (this.state.planet.id === planet.id) { this.transitionTo('userHome', {userName: this.state.planet.Owner.name}) } break case 'codeUpdated': code = res.data if (code.PlanetId === this.state.planet.id) { this.state.planet.Codes = this.updateItemToTargetArray(code, this.state.planet.Codes) this.setState({planet: this.state.planet}) } break case 'noteUpdated': note = res.data if (note.PlanetId === this.state.planet.id) { this.state.planet.Notes = this.updateItemToTargetArray(note, this.state.planet.Notes) this.setState({planet: this.state.planet}) } break case 'codeDestroyed': code = res.data if (code.PlanetId === this.state.planet.id) { this.state.planet.Codes = this.deleteItemFromTargetArray(code, this.state.planet.Codes) if (this.refs.detail.props.article != null && this.refs.detail.props.article.type === code.type && this.refs.detail.props.article.localId === code.localId) { articleIndex = this.getFilteredIndexOfCurrentArticle() articlesCount = this.refs.list.props.articles.length this.setState({planet: this.state.planet}, function () { if (articlesCount > 1) { if (articleIndex > 0) { this.selectArticleByListIndex(articleIndex - 1) } else { this.selectArticleByListIndex(articleIndex) } } }) return } this.setState({planet: this.state.planet}) } break case 'noteDestroyed': note = res.data if (note.PlanetId === this.state.planet.id) { this.state.planet.Notes = this.deleteItemFromTargetArray(note, this.state.planet.Notes) if (this.refs.detail.props.article != null && this.refs.detail.props.article.type === note.type && this.refs.detail.props.article.localId === note.localId) { articleIndex = this.getFilteredIndexOfCurrentArticle() articlesCount = this.refs.list.props.articles.length this.setState({planet: this.state.planet}, function () { if (articlesCount > 1) { if (articleIndex > 0) { this.selectArticleByListIndex(articleIndex - 1) } else { this.selectArticleByListIndex(articleIndex) } } }) return } this.setState({planet: this.state.planet}) } break } }, onUserChange: function () { }, fetchPlanet: function (userName, planetName) { if (userName == null) userName = this.props.params.userName if (planetName == null) planetName = this.props.params.planetName Hq.fetchPlanet(userName, planetName) .then(function (res) { var planet = res.body planet.Codes.forEach(function (code) { code.type = 'code' }) planet.Notes.forEach(function (note) { note.type = 'note' }) localStorage.setItem('planet-' + planet.id, JSON.stringify(planet)) this.setState({planet: planet}) }.bind(this)) .catch(function (err) { console.error(err) }) }, getFilteredIndexOfCurrentArticle: function () { var params = this.props.params var index = 0 if (this.isActive('codes')) { this.refs.list.props.articles.some(function (_article, _index) { if (_article.type === 'code' && _article.localId === parseInt(params.localId, 10)) { index = _index } }) } else if (this.isActive('notes')) { this.refs.list.props.articles.some(function (_article, _index) { if (_article.type === 'note' && _article.localId === parseInt(params.localId, 10)) { index = _index return true } return false }) } return index }, selectArticleByListIndex: function (index) { var article = this.refs.list.props.articles[index] var params = this.props.params if (article == null) { this.transitionTo('planetHome', params) 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') { params.localId = article.localId this.transitionTo('codes', params) return } if (article.type === 'note') { params.localId = article.localId this.transitionTo('notes', params) return } }, selectNextArticle: function () { if (this.state.planet == null) return var index = this.getFilteredIndexOfCurrentArticle() if (index < this.refs.list.props.articles.length - 1) { this.selectArticleByListIndex(index + 1) } }, selectPriorArticle: function () { if (this.state.planet == null) { return } var index = this.getFilteredIndexOfCurrentArticle() if (index > 0) { this.selectArticleByListIndex(index - 1) } else { 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) { this.setState({search: e.target.value}, function () { this.selectArticleByListIndex(0) }) }, showAll: function () { this.setState({search: ''}) }, toggleCodeFilter: function () { var keywords = typeof this.state.search === 'string' ? this.state.search.split(' ') : [] var usingCodeFilter = false var usingNoteFilter = false keywords = keywords.filter(function (keyword) { if (keyword === '$n') { usingNoteFilter = true return false } if (keyword === '$c') usingCodeFilter = true return true }) if (usingCodeFilter && !usingNoteFilter) { keywords = keywords.filter(function (keyword) { return keyword !== '$c' }) } if (!usingCodeFilter) { keywords.unshift('$c') } this.setState({search: keywords.join(' ')}, function () { this.selectArticleByListIndex(0) }) }, toggleNoteFilter: function () { var keywords = typeof this.state.search === 'string' ? this.state.search.split(' ') : [] var usingCodeFilter = false var usingNoteFilter = false keywords = keywords.filter(function (keyword) { if (keyword === '$c') { usingCodeFilter = true return false } if (keyword === '$n') usingNoteFilter = true return true }) if (usingNoteFilter && !usingCodeFilter) { keywords = keywords.filter(function (keyword) { return keyword !== '$n' }) } if (!usingNoteFilter) { keywords.unshift('$n') } this.setState({search: keywords.join(' ')}, function () { this.selectArticleByListIndex(0) }) }, applyTagFilter: function (tag) { return function () { this.setState({search: '#' + tag}) }.bind(this) }, render: function () { if (this.state.planet == null) return (
) var localId = parseInt(this.props.params.localId, 10) var codes = this.state.planet.Codes var notes = this.state.planet.Notes var article if (this.isActive('codes')) { codes.some(function (_article) { if (localId === _article.localId) { article = _article return true } return false }) } else if (this.isActive('notes')) { notes.some(function (_article) { if (localId === _article.localId) { article = _article return true } return false }) } var articles = codes.concat(notes) var filteredArticles = this.searchArticle(this.state.search, articles) return (