Add posts lists (#22)
* Add posts list * Use map instead of polyfill * Fix some eslint issues * Address camel case and client channelId
This commit is contained in:
parent
5bdc432f71
commit
f6ed67e053
15 changed files with 169 additions and 23 deletions
|
|
@ -46,4 +46,4 @@ export function bindClientFunc(clientFunc, request, success, failure, ...args) {
|
|||
|
||||
return dispatch(() => clientFunc(...args, onRequest, onSuccess, onFailure), getState);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
src/actions/posts.js
Normal file
17
src/actions/posts.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// 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 {PostsTypes as types} from 'constants';
|
||||
|
||||
export function fetchPosts(teamId, channelId) {
|
||||
Client.setTeamId(teamId);
|
||||
return bindClientFunc(
|
||||
Client.fetchPosts,
|
||||
types.FETCH_POSTS_REQUEST,
|
||||
types.FETCH_POSTS_SUCCESS,
|
||||
types.FETCH_POSTS_FAILURE,
|
||||
channelId
|
||||
);
|
||||
}
|
||||
|
|
@ -249,6 +249,15 @@ export default class Client {
|
|||
}
|
||||
|
||||
// Post routes
|
||||
fetchPosts = (channelId, onRequest, onSuccess, onFailure) => {
|
||||
return this.doFetch(
|
||||
`${this.getPostsRoute(channelId)}/page/0/60`,
|
||||
{method: 'get'},
|
||||
onRequest,
|
||||
onSuccess,
|
||||
onFailure
|
||||
);
|
||||
}
|
||||
|
||||
createPost = (post, onRequest, onSuccess, onFailure) => {
|
||||
return this.doFetch(
|
||||
|
|
|
|||
|
|
@ -38,10 +38,9 @@ class ChannelsList extends Component {
|
|||
}
|
||||
|
||||
componentWillReceiveProps(props) {
|
||||
if (props.channels.current_channel_id &&
|
||||
!this.props.channels.current_channel_id) {
|
||||
console.warn('TODO route to PostsList'); // eslint-disable-line no-console
|
||||
// TODO: Routes.PostLists(); // eslint-disable-line new-cap
|
||||
if (props.channels.currentChannelId &&
|
||||
!this.props.channels.currentChannelId) {
|
||||
Routes.goToPostsList();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class Login extends Component {
|
|||
componentWillReceiveProps(props) {
|
||||
if (this.props.login.status === 'fetching' &&
|
||||
props.login.status === 'fetched') {
|
||||
Routes.SelectTeam(); // eslint-disable-line new-cap
|
||||
Routes.goToSelectTeam(); // eslint-disable-line new-cap
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
70
src/components/posts_list.js
Normal file
70
src/components/posts_list.js
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {Component, PropTypes} from 'react';
|
||||
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {connect} from 'react-redux';
|
||||
import {StyleSheet, Text, View} from 'react-native';
|
||||
|
||||
import * as postActions from 'actions/posts';
|
||||
import ErrorText from 'components/error_text';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
paddingTop: 200,
|
||||
backgroundColor: 'white'
|
||||
}
|
||||
});
|
||||
|
||||
const propTypes = {
|
||||
posts: PropTypes.object.isRequired,
|
||||
currentTeamId: PropTypes.string.isRequired,
|
||||
currentChannelId: PropTypes.string.isRequired,
|
||||
actions: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
class PostsList extends Component {
|
||||
static propTypes = propTypes;
|
||||
|
||||
componentWillMount() {
|
||||
this.props.actions.fetchPosts(
|
||||
this.props.currentTeamId,
|
||||
this.props.currentChannelId
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{this.props.posts.data.map((post) => {
|
||||
return (
|
||||
<Text key={post.id}>
|
||||
{`${post.user_id} - ${post.message}`}
|
||||
</Text>
|
||||
);
|
||||
})}
|
||||
<ErrorText error={this.props.posts.error}/>
|
||||
</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)(PostsList);
|
||||
|
|
@ -49,7 +49,7 @@ class SelectServerView extends Component {
|
|||
|
||||
onClick = () => {
|
||||
Client.setUrl(this.state.serverUrl);
|
||||
Routes.Login(); // eslint-disable-line new-cap
|
||||
Routes.goToLogin();
|
||||
|
||||
// this.props.getPing().then(() => {
|
||||
// AsyncStorage.setItem('serverUrl', this.state.serverUrl, () => {
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ class SelectTeam extends Component {
|
|||
}
|
||||
|
||||
componentWillReceiveProps(props) {
|
||||
if (props.teams.current_team_id && !this.props.teams.current_team_id) {
|
||||
Routes.ChannelsList(); // eslint-disable-line new-cap
|
||||
if (props.teams.currentTeamId && !this.props.teams.currentTeamId) {
|
||||
Routes.goToChannelsList();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@ import * as DeviceTypes from './device';
|
|||
import * as GeneralTypes from './general';
|
||||
import * as LoginTypes from './login';
|
||||
import * as TeamsTypes from './teams';
|
||||
import * as PostsTypes from './posts';
|
||||
|
||||
export {
|
||||
DeviceTypes,
|
||||
GeneralTypes,
|
||||
LoginTypes,
|
||||
TeamsTypes,
|
||||
ChannelsTypes
|
||||
ChannelsTypes,
|
||||
PostsTypes
|
||||
};
|
||||
|
|
|
|||
3
src/constants/posts.js
Normal file
3
src/constants/posts.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export const FETCH_POSTS_REQUEST = 'FETCH_POSTS_REQUEST';
|
||||
export const FETCH_POSTS_SUCCESS = 'FETCH_POSTS_SUCCESS';
|
||||
export const FETCH_POSTS_FAILURE = 'FETCH_POSTS_FAILURE';
|
||||
|
|
@ -4,7 +4,7 @@ const initState = {
|
|||
status: 'not fetched',
|
||||
error: null,
|
||||
data: [],
|
||||
current_channel_id: null
|
||||
currentChannelId: null
|
||||
};
|
||||
|
||||
export default function reduceChannels(state = initState, action) {
|
||||
|
|
@ -12,7 +12,7 @@ export default function reduceChannels(state = initState, action) {
|
|||
|
||||
case types.SELECT_CHANNEL:
|
||||
return {...state,
|
||||
current_channel_id: action.channel_id
|
||||
currentChannelId: action.channel_id
|
||||
};
|
||||
|
||||
case types.FETCH_CHANNELS_REQUEST:
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ import device from './device.js';
|
|||
import general from './general.js';
|
||||
import login from './login';
|
||||
import teams from './teams';
|
||||
import posts from './posts';
|
||||
|
||||
const entities = combineReducers({
|
||||
channels,
|
||||
general,
|
||||
teams
|
||||
teams,
|
||||
posts
|
||||
});
|
||||
|
||||
const views = combineReducers({
|
||||
|
|
|
|||
32
src/reducers/posts.js
Normal file
32
src/reducers/posts.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import _ from 'lodash';
|
||||
import {PostsTypes as types} from 'constants';
|
||||
|
||||
const initState = {
|
||||
status: 'not fetched',
|
||||
error: null,
|
||||
data: []
|
||||
};
|
||||
|
||||
export default function reducePosts(state = initState, action) {
|
||||
switch (action.type) {
|
||||
|
||||
case types.FETCH_POSTS_REQUEST:
|
||||
return {...state,
|
||||
status: 'fetching',
|
||||
error: null
|
||||
};
|
||||
case types.FETCH_POSTS_SUCCESS:
|
||||
return {...state,
|
||||
status: 'fetched',
|
||||
data: _.values(action.data.posts)
|
||||
};
|
||||
case types.FETCH_POSTS_FAILURE:
|
||||
return {...state,
|
||||
status: 'failed',
|
||||
error: action.error
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ const initState = {
|
|||
status: 'not fetched',
|
||||
error: null,
|
||||
data: [],
|
||||
current_team_id: null
|
||||
currentTeamId: null
|
||||
};
|
||||
|
||||
export default function reduceTeams(state = initState, action) {
|
||||
|
|
@ -13,7 +13,7 @@ export default function reduceTeams(state = initState, action) {
|
|||
|
||||
case types.SELECT_TEAM:
|
||||
return {...state,
|
||||
current_team_id: action.team_id
|
||||
currentTeamId: action.team_id
|
||||
};
|
||||
|
||||
case types.FETCH_TEAMS_REQUEST:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import ChannelsList from 'components/channels_list';
|
|||
import Login from 'components/login';
|
||||
import SelectServerView from 'components/select_server_view';
|
||||
import SelectTeam from 'components/select_team';
|
||||
import PostsList from 'components/posts_list';
|
||||
|
||||
export default class Routes extends Component {
|
||||
render() {
|
||||
|
|
@ -16,26 +17,37 @@ export default class Routes extends Component {
|
|||
<Router>
|
||||
<Scene key='root'>
|
||||
<Scene
|
||||
key='ChannelsList'
|
||||
component={ChannelsList}
|
||||
title='Channels'
|
||||
/>
|
||||
<Scene
|
||||
key='Login'
|
||||
key='goToLogin'
|
||||
component={Login}
|
||||
title='Login'
|
||||
/>
|
||||
<Scene
|
||||
key='SelectServerView'
|
||||
key='goToSelectServerView'
|
||||
component={SelectServerView}
|
||||
title='Enter Server URL'
|
||||
initial={true}
|
||||
/>
|
||||
<Scene
|
||||
key='SelectTeam'
|
||||
key='goToSelectServerView'
|
||||
component={SelectServerView}
|
||||
title='Enter Server URL'
|
||||
initial={true}
|
||||
/>
|
||||
<Scene
|
||||
key='goToChannelsList'
|
||||
component={ChannelsList}
|
||||
title='Channels'
|
||||
/>
|
||||
<Scene
|
||||
key='goToSelectTeam'
|
||||
component={SelectTeam}
|
||||
title='Select Team'
|
||||
/>
|
||||
<Scene
|
||||
key='goToPostsList'
|
||||
component={PostsList}
|
||||
title='Posts List'
|
||||
/>
|
||||
</Scene>
|
||||
</Router>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue