diff --git a/package.json b/package.json index 715e080ab..23b6c6e56 100644 --- a/package.json +++ b/package.json @@ -3,19 +3,23 @@ "version": "0.0.1", "private": true, "dependencies": { + "babel-preset-es2015": "6.18.0", "intl": "1.2.5", "isomorphic-fetch": "2.2.1", "lodash": "4.16.4", "react": "15.3.2", + "react-addons-pure-render-mixin": "15.3.2", "react-intl": "2.1.5", "react-native": "0.34.1", "react-native-button": "1.7.1", + "react-native-drawer": "2.3.0", "react-native-keyboard-spacer": "0.3.0", "react-native-router-flux": "3.36.0", + "react-native-vector-icons": "2.1.0", "react-redux": "4.4.5", "redux": "3.6.0", - "redux-thunk": "2.1.0", - "react-native-vector-icons": "2.1.0" + "redux-batched-actions": "0.1.3", + "redux-thunk": "2.1.0" }, "devDependencies": { "babel-eslint": "7.0.0", diff --git a/src/actions/channels.js b/src/actions/channels.js index fcc5b61ce..75ae50cd8 100644 --- a/src/actions/channels.js +++ b/src/actions/channels.js @@ -1,22 +1,30 @@ // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import {bindClientFunc} from './helpers.js'; -import Client from 'client/client_instance'; -import {ChannelsTypes} from 'constants'; +import {ChannelTypes} from 'constants'; +import {batchActions} from 'redux-batched-actions'; +import Client from 'client/client_instance.js'; -export function selectChannel(channel) { - return { - type: ChannelsTypes.SELECT_CHANNEL, - channelId: channel.id +export function fetchMyChannelsAndMembers(teamId) { + return async (dispatch, getState) => { + try { + const channels = Client.getChannels(teamId); + const channelMembers = Client.getMyChannelMembers(teamId); + + dispatch(batchActions([ + { + type: ChannelTypes.CHANNELS_RECEIVED, + teamId, + channels: await channels + }, + { + type: ChannelTypes.CHANNEL_MEMBERS_RECEIVED, + teamId, + channelMembers: await channelMembers + } + ]), getState); + } catch (err) { + console.error(err); // eslint-disable-line no-console + } }; } - -export function fetchChannels() { - return bindClientFunc( - Client.fetchChannels, - ChannelsTypes.FETCH_CHANNELS_REQUEST, - ChannelsTypes.FETCH_CHANNELS_SUCCESS, - ChannelsTypes.FETCH_CHANNELS_FAILURE - ); -} diff --git a/src/actions/teams.js b/src/actions/teams.js index fe2b08968..2c9e80cc8 100644 --- a/src/actions/teams.js +++ b/src/actions/teams.js @@ -15,7 +15,7 @@ export function selectTeam(team) { export function fetchTeams() { return bindClientFunc( - Client.fetchTeams, + Client.getAllTeams, TeamsTypes.FETCH_TEAMS_REQUEST, TeamsTypes.FETCH_TEAMS_SUCCESS, TeamsTypes.FETCH_TEAMS_FAILURE diff --git a/src/client/client.js b/src/client/client.js index 08f2884ad..580a05212 100644 --- a/src/client/client.js +++ b/src/client/client.js @@ -11,7 +11,6 @@ const CONTENT_TYPE_JSON = 'application/json'; export default class Client { constructor() { - this.teamId = ''; this.logToConsole = false; this.token = ''; this.url = ''; @@ -27,18 +26,6 @@ export default class Client { this.url = url; } - setTeamId(id) { - this.teamId = id; - } - - getTeamId() { - if (!this.teamId) { - console.error('You are trying to use a route that requires a team_id, but you have not called setTeamId() in client.jsx'); // eslint-disable-line no-console - } - - return this.teamId; - } - getBaseRoute() { return `${this.url}${this.urlVersion}`; } @@ -59,16 +46,16 @@ export default class Client { return `${this.url}${this.urlVersion}/teams`; } - getTeamNeededRoute() { - return `${this.url}${this.urlVersion}/teams/${this.getTeamId()}`; + getTeamNeededRoute(teamId) { + return `${this.url}${this.urlVersion}/teams/${teamId}`; } - getChannelsRoute() { - return `${this.url}${this.urlVersion}/teams/${this.getTeamId()}/channels`; + getChannelsRoute(teamId) { + return `${this.url}${this.urlVersion}/teams/${teamId}/channels`; } - getChannelNameRoute(channelName) { - return `${this.url}${this.urlVersion}/teams/${this.getTeamId()}/channels/name/${channelName}`; + getChannelNameRoute(teamId, channelName) { + return `${this.url}${this.urlVersion}/teams/${teamId}/channels/name/${channelName}`; } getChannelNeededRoute(channelId) { @@ -209,7 +196,14 @@ export default class Client { ); } - fetchTeams = async () => { + getAllTeams = async() => { + return this.doFetch( + `${this.getTeamsRoute()}/all`, + {method: 'get'} + ); + } + + getAllTeamListings = async () => { return this.doFetch( `${this.getTeamsRoute()}/all_team_listings`, {method: 'get'} @@ -225,9 +219,16 @@ export default class Client { ); } - fetchChannels = async () => { + getChannels = async (teamId) => { return this.doFetch( - `${this.getChannelsRoute()}/`, + `${this.getChannelsRoute(teamId)}/`, + {method: 'get'} + ); + } + + getMyChannelMembers = async (teamId) => { + return this.doFetch( + `${this.getChannelsRoute(teamId)}/members`, {method: 'get'} ); } diff --git a/src/components/channel_sidebar.js b/src/components/channel_sidebar.js new file mode 100644 index 000000000..655c5958a --- /dev/null +++ b/src/components/channel_sidebar.js @@ -0,0 +1,59 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import React from 'react'; + +// import {bindActionCreators} from 'redux'; +import {connect} from 'react-redux'; + +import {Text, View} from 'react-native'; + +class ChannelSidebar extends React.Component { + static propTypes = { + currentTeam: React.PropTypes.object.isRequired, + channels: React.PropTypes.array.isRequired, + onSelectChannel: React.PropTypes.func + }; + + onSelectChannel = (channel) => { + console.log('clicked channel ' + channel.name); // eslint-disable-line no-console + + // this.props.onSelectChannel(channel); + } + + render() { + const channels = this.props.channels.map((channel) => { + return ( + this.onSelectChannel(channel)} + > + {channel.name} + + ); + }); + + return ( + + {this.props.currentTeam.name} + {channels} + + ); + } +} + +function mapStateToProps(state, ownProps) { + return { + ...ownProps, + channels: Object.keys(state.entities.channel.channelIdsByTeamId[ownProps.currentTeam.id] || {}).map((channelId) => state.entities.channel.channels[channelId]) + }; +} + +export default connect(mapStateToProps)(ChannelSidebar); diff --git a/src/components/channels_list_view.js b/src/components/channels_list_view.js deleted file mode 100644 index e9c02fbb7..000000000 --- a/src/components/channels_list_view.js +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React, {Component, PropTypes} from 'react'; -import {View, Text} from 'react-native'; -import {Actions as Routes} from 'react-native-router-flux'; -import Button from 'react-native-button'; -import _ from 'lodash'; - -import ErrorText from 'components/error_text'; -import FormattedText from 'components/formatted_text'; -import {GlobalStyles} from 'styles'; - -const propTypes = { - teams: PropTypes.object.isRequired, - channels: PropTypes.object.isRequired, - actions: PropTypes.object.isRequired -}; - -class ChannelsListView extends Component { - static propTypes = propTypes; - - componentWillMount() { - this.props.actions.fetchChannels(); - } - - componentWillReceiveProps(nextProps) { - const {currentChannelId} = nextProps.channels; - if (currentChannelId && - currentChannelId !== this.props.channels.currentChannelId) { - Routes.goToPostsList(); - } - } - - render() { - const {data: teams, currentTeamId} = this.props.teams; - const currentTeam = teams[currentTeamId]; - const channels = _.values(this.props.channels.data); - return ( - - - {currentTeam.display_name} - - - {_.map(channels, (channel) => ( - - ))} - - - - ); - } -} - -export default ChannelsListView; diff --git a/src/components/drawer.js b/src/components/drawer.js new file mode 100644 index 000000000..d3e53b316 --- /dev/null +++ b/src/components/drawer.js @@ -0,0 +1,24 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import React from 'react'; +import BaseDrawer from 'react-native-drawer'; + +// Extends react-native-drawer to allow better control over the open/closed state from the parent +export default class Drawer extends BaseDrawer { + static propTypes = { + ...BaseDrawer.propTypes, + onRequestClose: React.PropTypes.func.isRequired + }; + + close = (type, callback) => { + this.props.onRequestClose(); + + if (typeof type === 'function') { + // This function can be called with only a callback as its only argument + type(); + } else if (callback) { + callback(); + } + } +} diff --git a/src/components/login_view.js b/src/components/login_view.js index d004381a7..5b9b036df 100644 --- a/src/components/login_view.js +++ b/src/components/login_view.js @@ -14,28 +14,30 @@ import logo from 'images/logo.png'; import {injectIntl, intlShape} from 'react-intl'; -const propTypes = { - intl: intlShape.isRequired, - clientConfig: PropTypes.object.isRequired, - login: PropTypes.object.isRequired, - actions: PropTypes.object.isRequired -}; - class LoginView extends Component { - static propTypes = propTypes; + static propTypes = { + intl: intlShape.isRequired, + clientConfig: PropTypes.object.isRequired, + login: PropTypes.object.isRequired, + actions: PropTypes.object.isRequired + }; + state = { loginId: '', password: '' }; + componentWillMount() { + this.props.actions.getClientConfig(); + } + componentWillReceiveProps(nextProps) { - if (this.props.login.status === 'fetching' && - nextProps.login.status === 'fetched') { + if (this.props.login.status === 'fetching' && nextProps.login.status === 'fetched') { Routes.goToSelectTeam(); } } - signIn() { + signIn = () => { if (this.props.login.status !== 'fetching') { const {loginId, password} = this.state; this.props.actions.login(loginId, password); @@ -44,7 +46,7 @@ class LoginView extends Component { createLoginPlaceholder() { const {formatMessage} = this.props.intl; - const clientConfig = this.props.clientConfig.data; + const clientConfig = this.props.clientConfig; const loginPlaceholders = []; if (clientConfig.EnableSignInWithEmail === 'true') { @@ -75,7 +77,7 @@ class LoginView extends Component { } render() { - if (!this.props.clientConfig || !this.props.clientConfig.data) { + if (this.props.clientConfig.loading || this.props.clientConfig.error) { return ; } @@ -86,7 +88,7 @@ class LoginView extends Component { source={logo} /> - {this.props.clientConfig.data.SiteName} + {this.props.clientConfig.SiteName} this.setState({loginId})} style={GlobalStyles.inputBox} @@ -111,8 +114,10 @@ class LoginView extends Component { autoCorrect={false} autoCapitalize='none' underlineColorAndroid='transparent' + returnKeyType='go' + onSubmitEditing={this.signIn} /> - + ); + } return ( @@ -45,7 +62,7 @@ export default class SelectTeamView extends Component { source={logo} /> - {this.props.clientConfig.data.SiteName} + {this.props.clientConfig.SiteName} - {_.map(teams, (team) => ( - - ))} + {teams} ); diff --git a/src/constants/channel.js b/src/constants/channel.js new file mode 100644 index 000000000..f82fc9448 --- /dev/null +++ b/src/constants/channel.js @@ -0,0 +1,8 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +export const CHANNEL_RECEIVED = 'mattermost/channels/channel_received'; +export const CHANNELS_RECEIVED = 'mattermost/channels/channels_received'; + +export const CHANNEL_MEMBER_RECEIVED = 'mattermost/channels/channel_member_received'; +export const CHANNEL_MEMBERS_RECEVED = 'mattermost/channels/channel_members_received'; diff --git a/src/constants/channels.js b/src/constants/channels.js deleted file mode 100644 index c68652e7e..000000000 --- a/src/constants/channels.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -export const SELECT_CHANNEL = 'SELECT_CHANNEL'; - -export const FETCH_CHANNELS_REQUEST = 'FETCH_CHANNELS_REQUEST'; -export const FETCH_CHANNELS_SUCCESS = 'FETCH_CHANNELS_SUCCESS'; -export const FETCH_CHANNELS_FAILURE = 'FETCH_CHANNELS_FAILURE'; diff --git a/src/constants/index.js b/src/constants/index.js index 23ad6cc6f..426aedd60 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -1,7 +1,7 @@ // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import * as ChannelsTypes from './channels'; +import * as ChannelTypes from './channel'; import * as DeviceTypes from './device'; import * as GeneralTypes from './general'; import * as LoginTypes from './login'; @@ -15,6 +15,6 @@ export { LoginTypes, LogoutTypes, TeamsTypes, - ChannelsTypes, + ChannelTypes, PostsTypes }; diff --git a/src/containers/channels_list_container.js b/src/containers/channels_list_container.js deleted file mode 100644 index be9b288cc..000000000 --- a/src/containers/channels_list_container.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import {bindActionCreators} from 'redux'; -import {connect} from 'react-redux'; -import * as channelActions from 'actions/channels'; -import ChannelsListView from 'components/channels_list_view'; - -function mapStateToProps(state) { - return { - teams: state.entities.teams, - channels: state.entities.channels - }; -} - -function mapDispatchToProps(dispatch) { - return { - actions: bindActionCreators(channelActions, dispatch) - }; -} - -export default connect(mapStateToProps, mapDispatchToProps)(ChannelsListView); diff --git a/src/containers/login_container.js b/src/containers/login_container.js index 5c9ebe5f2..dfdb87a5d 100644 --- a/src/containers/login_container.js +++ b/src/containers/login_container.js @@ -4,6 +4,7 @@ import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; import * as loginActions from 'actions/login'; +import {getClientConfig} from 'actions/general'; import LoginView from 'components/login_view'; function mapStateToProps(state) { @@ -15,7 +16,10 @@ function mapStateToProps(state) { function mapDispatchToProps(dispatch) { return { - actions: bindActionCreators(loginActions, dispatch) + actions: bindActionCreators({ + ...loginActions, + getClientConfig + }, dispatch) }; } diff --git a/src/containers/main_container.js b/src/containers/main_container.js new file mode 100644 index 000000000..843fd614a --- /dev/null +++ b/src/containers/main_container.js @@ -0,0 +1,42 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import {bindActionCreators} from 'redux'; +import {connect} from 'react-redux'; +import {fetchMyChannelsAndMembers} from 'actions/channels.js'; +import MainView from 'components/main_view.js'; + +function mapStateToProps(state, ownProps) { + let currentChannel; + if (ownProps.currentChannelId) { + currentChannel = state.entities.channel.channels[ownProps.currentChannelId]; + } else { + // TODO figure out the town square id before this + const channelIds = state.entities.channel.channelIdsByTeamId[ownProps.currentTeamId] || {}; + + for (const channelId of Object.keys(channelIds)) { + const channel = state.entities.channel.channels[channelId]; + + if (channel.name === 'town-square') { + currentChannel = channel; + break; + } + } + } + + return { + ...ownProps, + currentTeam: state.entities.teams.data[ownProps.currentTeamId] || {}, + currentChannel + }; +} + +function mapDispatchToProps(dispatch) { + return { + actions: bindActionCreators({ + fetchMyChannelsAndMembers + }, dispatch) + }; +} + +export default connect(mapStateToProps, mapDispatchToProps)(MainView); diff --git a/src/containers/posts_list_container.js b/src/containers/posts_list_container.js deleted file mode 100644 index 20bf34453..000000000 --- a/src/containers/posts_list_container.js +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import {bindActionCreators} from 'redux'; -import {connect} from 'react-redux'; -import * as postActions from 'actions/posts'; -import PostsListView from 'components/posts_list_view'; - -function mapStateToProps(state) { - return { - posts: state.entities.posts, - currentTeamId: state.entities.teams.currentTeamId, - currentChannelId: state.entities.channels.currentChannelId - }; -} - -function mapDispatchToProps(dispatch) { - return { - actions: bindActionCreators(postActions, dispatch) - }; -} - -export default connect(mapStateToProps, mapDispatchToProps)(PostsListView); diff --git a/src/containers/select_server_container.js b/src/containers/select_server_container.js index 4f8fd4c18..4cdb40b14 100644 --- a/src/containers/select_server_container.js +++ b/src/containers/select_server_container.js @@ -3,7 +3,7 @@ import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; -import {getPing, getClientConfig} from 'actions/general'; +import {getPing} from 'actions/general'; import SelectServerView from 'components/select_server_view'; function mapStateToProps(state) { @@ -15,7 +15,7 @@ function mapStateToProps(state) { function mapDispatchToProps(dispatch) { return { - actions: bindActionCreators({getPing, getClientConfig}, dispatch) + actions: bindActionCreators({getPing}, dispatch) }; } diff --git a/src/reducers/channel.js b/src/reducers/channel.js new file mode 100644 index 000000000..d7b1c11b4 --- /dev/null +++ b/src/reducers/channel.js @@ -0,0 +1,99 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import {ChannelTypes} from 'constants'; +import {combineReducers} from 'redux'; + +export function channels(state = {}, action) { + switch (action.type) { + case ChannelTypes.CHANNEL_RECEIVED: + return { + ...state, + [action.channel.id]: action.channel + }; + + case ChannelTypes.CHANNELS_RECEIVED: { + const nextState = {...state}; + + for (const channel of action.channels) { + nextState[channel.id] = channel; + } + + return nextState; + } + + default: + return state; + } +} + +export function channelIdsByTeamId(state = {}, action) { + switch (action.type) { + case ChannelTypes.CHANNEL_RECEIVED: { + const channel = action.channel; + + return { + ...state, + [channel.team_id]: { + ...state[channel.team_id], + [channel.id]: channel.id + } + }; + } + + case ChannelTypes.CHANNELS_RECEIVED: { + const nextState = {...state}; + + for (const channel of action.channels) { + nextState[channel.team_id] = { + ...nextState[channel.team_id], + [channel.id]: channel.id + }; + } + + return nextState; + } + + default: + return state; + } +} + +export function channelMembers(state = {}, action) { + switch (action.type) { + + case ChannelTypes.CHANNEL_MEMBER_RECEIVED: { + const channelMember = action.channelMember; + + return { + ...state, + [`${channelMember.channel_id}-${channelMember.user_id}`]: channelMember + }; + } + + case ChannelTypes.CHANNEL_MEMBERS_RECEIVED: { + const nextState = {...state}; + + for (const channelMember of action.channelMembers) { + nextState[`${channelMember.channel_id}-${channelMember.user_id}`] = channelMember; + } + + return nextState; + } + + default: + return state; + } +} + +export default combineReducers({ + + // A map of channel IDs to channels + channels, + + // A map of team IDs to pseudo-sets of channelIds + channelIdsByTeamId, + + // A map of "channelId-userId" to channel members + channelMembers +}); diff --git a/src/reducers/channels.js b/src/reducers/channels.js deleted file mode 100644 index b744c7ee1..000000000 --- a/src/reducers/channels.js +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import _ from 'lodash'; -import {ChannelsTypes, LogoutTypes} from 'constants'; - -export const initState = { - status: 'not fetched', - error: null, - data: {}, - currentChannelId: null -}; - -// TODO: this can be extracted into a util -function zipById(channels) { - return _.zipObject(_.map(channels, 'id'), channels); -} - -export default function reduceChannels(state = initState, action) { - switch (action.type) { - - case ChannelsTypes.SELECT_CHANNEL: - return {...state, - currentChannelId: action.channelId - }; - - case ChannelsTypes.FETCH_CHANNELS_REQUEST: - return {...state, - status: 'fetching', - error: null - }; - case ChannelsTypes.FETCH_CHANNELS_SUCCESS: - return {...state, - status: 'fetched', - data: zipById(action.data.channels) - }; - case ChannelsTypes.FETCH_CHANNELS_FAILURE: - return {...state, - status: 'failed', - error: action.error - }; - - case LogoutTypes.LOGOUT_SUCCESS: - return initState; - default: - return state; - } -} diff --git a/src/reducers/general.js b/src/reducers/general.js index 2b7bba5b5..54a862e7a 100644 --- a/src/reducers/general.js +++ b/src/reducers/general.js @@ -2,34 +2,62 @@ // See License.txt for license information. import {combineReducers} from 'redux'; -import {initialState, handle} from './helpers.js'; +import {initialState} from './helpers.js'; import {GeneralTypes} from 'constants'; export const initState = initialState(); -// TODO: clientConfig should be cleared when the user logs out. -// We can't do so until it's extracted into its own store with more reducers -export function clientConfig(state = initState, action) { - return handle( - GeneralTypes.CLIENT_CONFIG_REQUEST, - GeneralTypes.CLIENT_CONFIG_SUCCESS, - GeneralTypes.CLIENT_CONFIG_FAILURE, - state, - action - ); +function ping(state = {}, action) { + switch (action.type) { + case GeneralTypes.PING_REQUEST: + return { + ...action.data, + loading: true + }; + case GeneralTypes.PING_SUCCESS: + return { + ...action.data, + loading: false, + error: null + }; + case GeneralTypes.PING_FAILURE: + return { + ...action.data, + loading: false, + error: action.error + }; + + default: + return state; + } } -export function ping(state = initialState(), action) { - return handle( - GeneralTypes.PING_REQUEST, - GeneralTypes.PING_SUCCESS, - GeneralTypes.PING_FAILURE, - state, - action - ); +function clientConfig(state = {}, action) { + switch (action.type) { + case GeneralTypes.CLIENT_CONFIG_REQUEST: + return { + ...action.data, + loading: true + }; + case GeneralTypes.CLIENT_CONFIG_SUCCESS: + return { + ...action.data, + loading: false, + error: null + }; + case GeneralTypes.CLIENT_CONFIG_FAILURE: + return { + ...action.data, + loading: false, + error: action.error + }; + + default: + return state; + } } export default combineReducers({ - clientConfig, - ping + ping, + clientConfig }); diff --git a/src/reducers/index.js b/src/reducers/index.js index 1f00e943e..8801a41dc 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -3,7 +3,7 @@ import {combineReducers} from 'redux'; -import channels from './channels'; +import channel from './channel.js'; import device from './device.js'; import general from './general.js'; import login from './login'; @@ -12,7 +12,7 @@ import teams from './teams'; import posts from './posts'; const entities = combineReducers({ - channels, + channel, general, teams, posts diff --git a/src/reducers/login.js b/src/reducers/login.js index 81be65b69..50e270db4 100644 --- a/src/reducers/login.js +++ b/src/reducers/login.js @@ -12,16 +12,19 @@ export default function reduceLogin(state = initState, action) { switch (action.type) { case LoginTypes.LOGIN_REQUEST: - return {...state, + return { + ...state, status: 'fetching', error: null }; case LoginTypes.LOGIN_SUCCESS: - return {...state, + return { + ...state, status: 'fetched' }; case LoginTypes.LOGIN_FAILURE: - return {...state, + return { + ...state, status: 'failed', error: action.error }; diff --git a/src/reducers/teams.js b/src/reducers/teams.js index bdaff675a..57a8a40d9 100644 --- a/src/reducers/teams.js +++ b/src/reducers/teams.js @@ -14,22 +14,26 @@ export default function reduceTeams(state = initState, action) { switch (action.type) { case TeamsTypes.SELECT_TEAM: - return {...state, + return { + ...state, currentTeamId: action.teamId }; case TeamsTypes.FETCH_TEAMS_REQUEST: - return {...state, + return { + ...state, status: 'fetching', error: null }; case TeamsTypes.FETCH_TEAMS_SUCCESS: - return {...state, + return { + ...state, status: 'fetched', data: action.data }; case TeamsTypes.FETCH_TEAMS_FAILURE: - return {...state, + return { + ...state, status: 'failed', error: action.error }; diff --git a/src/routes.js b/src/routes.js index b6820bbe4..3e930c77a 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1,15 +1,13 @@ -/* eslint-disable - class-methods-use-this, - react/require-optimization */ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. import React, {Component} from 'react'; import {Scene, Router} from 'react-native-router-flux'; -import ChannelsListContainer from 'containers/channels_list_container'; import LoginContainer from 'containers/login_container'; import SelectServerContainer from 'containers/select_server_container'; import SelectTeamContainer from 'containers/select_team_container'; -import PostsListContainer from 'containers/posts_list_container'; +import MainContainer from 'containers/main_container.js'; import Logout from 'components/logout'; import * as logout from 'actions/logout'; @@ -26,11 +24,6 @@ class Routes extends Component { return ( - - - } + key='goToLogin' + component={LoginContainer} + title={formatMessage({id: 'mobile.routes.login', defaultMessage: 'Login'})} /> - - } + key='goToMain' + component={MainContainer} + hideNavBar={true} /> diff --git a/src/store/configureStore.dev.js b/src/store/configureStore.dev.js index 840098014..499691174 100644 --- a/src/store/configureStore.dev.js +++ b/src/store/configureStore.dev.js @@ -1,21 +1,23 @@ // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import {applyMiddleware, createStore} from 'redux'; -import {composeWithDevTools} from 'remote-redux-devtools'; +import {applyMiddleware, compose, createStore} from 'redux'; +import devTools from 'remote-redux-devtools'; +import {enableBatching} from 'redux-batched-actions'; import rootReducer from 'reducers/index.js'; import thunk from 'redux-thunk'; export default function configureStore(preloadedState) { const store = createStore( - rootReducer, + enableBatching(rootReducer), preloadedState, - composeWithDevTools({ - name: 'Mattermost', - hostname: 'localhost', - port: 5678 - })( - applyMiddleware(thunk) + compose( + applyMiddleware(thunk), + devTools({ + name: 'Mattermost', + hostname: 'localhost', + port: 5678 + }) ) ); @@ -28,4 +30,4 @@ export default function configureStore(preloadedState) { } return store; -} \ No newline at end of file +} diff --git a/src/store/configureStore.prod.js b/src/store/configureStore.prod.js index adbda1afd..81bea2789 100644 --- a/src/store/configureStore.prod.js +++ b/src/store/configureStore.prod.js @@ -2,13 +2,14 @@ // See License.txt for license information. import {applyMiddleware, createStore} from 'redux'; +import {enableBatching} from 'redux-batched-actions'; import rootReducer from 'reducers/index.js'; import thunk from 'redux-thunk'; export default function configureStore(preloadedState) { return createStore( - rootReducer, + enableBatching(rootReducer), preloadedState, applyMiddleware(thunk) ); -} \ No newline at end of file +}