diff --git a/app/actions/navigation/index.js b/app/actions/navigation/index.js
index 2c32ee497..1d7986a1b 100644
--- a/app/actions/navigation/index.js
+++ b/app/actions/navigation/index.js
@@ -69,6 +69,7 @@ export function goToLoadTeam() {
export function goToModalSelectTeam() {
return async (dispatch, getState) => {
+ closeDrawers()(dispatch, getState);
dispatch({
type: NavigationTypes.NAVIGATION_MODAL,
route: Routes.SelectTeam
@@ -168,6 +169,7 @@ export function showOptionsModal(title, options) {
export function showMoreChannelsModal() {
return async (dispatch, getState) => {
+ closeDrawers()(dispatch, getState);
dispatch({
type: NavigationTypes.NAVIGATION_MODAL,
route: Routes.MoreChannels
@@ -177,6 +179,7 @@ export function showMoreChannelsModal() {
export function showDirectMessagesModal() {
return async (dispatch, getState) => {
+ closeDrawers()(dispatch, getState);
dispatch({
type: NavigationTypes.NAVIGATION_MODAL,
route: Routes.MoreDirectMessages
@@ -194,6 +197,7 @@ export function closeModal() {
export function goToModalAccountSettings() {
return async (dispatch, getState) => {
+ closeDrawers()(dispatch, getState);
dispatch({
type: NavigationTypes.NAVIGATION_MODAL,
route: Routes.AccountSettings
diff --git a/app/actions/views/channel.js b/app/actions/views/channel.js
index a6b0524ff..a49879b1a 100644
--- a/app/actions/views/channel.js
+++ b/app/actions/views/channel.js
@@ -5,7 +5,6 @@ import {batchActions} from 'redux-batched-actions';
import {ViewTypes} from 'app/constants';
import {updateStorage} from 'app/actions/storage';
-import {closeDrawers} from 'app/actions/navigation';
import {
fetchMyChannelsAndMembers,
@@ -154,10 +153,6 @@ export function handleSelectChannel(channelId) {
await updateStorage(currentTeamId, {currentChannelId: channelId});
await selectChannel(channelId)(dispatch, getState);
await getChannelStats(currentTeamId, channelId)(dispatch, getState);
-
- setTimeout(async () => {
- await closeDrawers()(dispatch, getState); // trying to smooth out channel switch transitions
- }, 200);
};
}
diff --git a/app/components/action_button.js b/app/components/action_button.js
index 8f6120ca3..38f6352b9 100644
--- a/app/components/action_button.js
+++ b/app/components/action_button.js
@@ -69,8 +69,33 @@ class ActionButton extends PureComponent {
const {labelDefaultMessage, labelId, theme} = this.props;
const {enabled, loading} = this.state;
let color = changeOpacity(theme.sidebarHeaderTextColor, 0.4);
+ let contents;
if (enabled) {
color = theme.sidebarHeaderTextColor;
+ contents = (
+
+
+
+
+
+ );
+ } else {
+ contents = (
+
+
+
+ );
}
if (loading) {
@@ -88,20 +113,7 @@ class ActionButton extends PureComponent {
);
}
- return (
-
-
-
-
-
- );
+ return contents;
}
}
diff --git a/app/components/channel_drawer_list/channel_drawer_list.js b/app/components/channel_drawer_list/channel_drawer_list.js
index d26e45af3..c6a540abf 100644
--- a/app/components/channel_drawer_list/channel_drawer_list.js
+++ b/app/components/channel_drawer_list/channel_drawer_list.js
@@ -21,61 +21,6 @@ import UnreadIndicator from './unread_indicator';
import deepEqual from 'deep-equal';
import Icon from 'react-native-vector-icons/FontAwesome';
-const Styles = StyleSheet.create({
- container: {
- flex: 1
- },
- scrollContainer: {
- flex: 1
- },
- headerContainer: {
- flexDirection: 'column',
- ...Platform.select({
- ios: {
- height: 64,
- justifyContent: 'flex-end'
- },
- android: {
- height: 56,
- justifyContent: 'center',
- paddingTop: 10
- }
- }),
- width: 300,
- paddingLeft: 10,
- paddingBottom: 12
- },
- header: {
- fontSize: 18,
- fontWeight: 'bold'
- },
- title: {
- paddingTop: 10,
- paddingRight: 10,
- paddingLeft: 10,
- paddingBottom: 5,
- fontSize: 15,
- opacity: 0.6
- },
- indicatorText: {
- paddingVertical: 2,
- paddingHorizontal: 4,
- backgroundColor: 'transparent',
- fontSize: 14,
- textAlign: 'center',
- textAlignVertical: 'center'
- },
- more: {
- position: 'absolute',
- opacity: 0.6,
- right: 0,
- width: 50,
- height: 30,
- alignItems: 'center',
- justifyContent: 'center'
- }
-});
-
class ChannelDrawerList extends Component {
static propTypes = {
intl: intlShape.isRequired,
@@ -86,8 +31,6 @@ class ChannelDrawerList extends Component {
theme: PropTypes.object.isRequired,
onSelectChannel: PropTypes.func.isRequired,
actions: PropTypes.shape({
- viewChannel: PropTypes.func.isRequired,
- markChannelAsRead: PropTypes.func.isRequired,
closeDMChannel: PropTypes.func.isRequired,
goToCreateChannel: PropTypes.func.isRequired,
leaveChannel: PropTypes.func.isRequired,
@@ -167,15 +110,8 @@ class ChannelDrawerList extends Component {
}
};
- onSelectChannel = async (channel) => {
- const {
- currentChannel,
- currentTeam
- } = this.props;
-
- await this.props.onSelectChannel(channel.id);
- this.props.actions.viewChannel(currentTeam.id, channel.id);
- this.props.actions.markChannelAsRead(channel.id, currentChannel.id);
+ onSelectChannel = (channel) => {
+ this.props.onSelectChannel(channel.id);
};
onLayout = (event) => {
@@ -547,4 +483,59 @@ class ChannelDrawerList extends Component {
}
}
+const Styles = StyleSheet.create({
+ container: {
+ flex: 1
+ },
+ scrollContainer: {
+ flex: 1
+ },
+ headerContainer: {
+ flexDirection: 'column',
+ ...Platform.select({
+ ios: {
+ height: 64,
+ justifyContent: 'flex-end'
+ },
+ android: {
+ height: 56,
+ justifyContent: 'center',
+ paddingTop: 10
+ }
+ }),
+ width: 300,
+ paddingLeft: 10,
+ paddingBottom: 12
+ },
+ header: {
+ fontSize: 18,
+ fontWeight: 'bold'
+ },
+ title: {
+ paddingTop: 10,
+ paddingRight: 10,
+ paddingLeft: 10,
+ paddingBottom: 5,
+ fontSize: 15,
+ opacity: 0.6
+ },
+ indicatorText: {
+ paddingVertical: 2,
+ paddingHorizontal: 4,
+ backgroundColor: 'transparent',
+ fontSize: 14,
+ textAlign: 'center',
+ textAlignVertical: 'center'
+ },
+ more: {
+ position: 'absolute',
+ opacity: 0.6,
+ right: 0,
+ width: 50,
+ height: 30,
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});
+
export default injectIntl(ChannelDrawerList);
diff --git a/app/components/channel_drawer_list/channel_drawer_list_container.js b/app/components/channel_drawer_list/channel_drawer_list_container.js
index 57fd07e32..95853e70b 100644
--- a/app/components/channel_drawer_list/channel_drawer_list_container.js
+++ b/app/components/channel_drawer_list/channel_drawer_list_container.js
@@ -19,7 +19,6 @@ import {
unmarkFavorite
} from 'app/actions/views/channel';
-import {viewChannel, markChannelAsRead} from 'service/actions/channels';
import ChannelDrawerList from './channel_drawer_list';
function mapStateToProps(state, ownProps) {
@@ -31,8 +30,6 @@ function mapStateToProps(state, ownProps) {
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
- viewChannel,
- markChannelAsRead,
closeDMChannel,
goToCreateChannel,
leaveChannel,
diff --git a/app/navigation/router.js b/app/navigation/router.js
index 3382b1f6e..7e26fbfce 100644
--- a/app/navigation/router.js
+++ b/app/navigation/router.js
@@ -38,17 +38,17 @@ class Router extends React.Component {
if (subscription) {
subscription();
}
- }
+ };
subscribeToHeaderEvent = (key) => (event, callback) => {
this.headerEventSubscriptions[`${key}-${event}`] = callback;
- }
+ };
unsubscribeFromHeaderEvent = (key) => (event) => {
if (this.headerEventSubscriptions[event]) {
Reflect.deleteProperty(this.headerEventSubscriptions, `${key}-${event}`);
}
- }
+ };
wrapHeaderComponent = (fx, emitter) => (props) => {
if (fx && props.scene.isActive) {
@@ -56,11 +56,11 @@ class Router extends React.Component {
}
return null;
- }
+ };
extractNavigationProps = (route) => {
return Object.assign({}, route.navigationProps, route.component.navigationProps);
- }
+ };
renderTransition = (transitionProps) => {
const navigationProps = this.extractNavigationProps(transitionProps.scene.route);
diff --git a/app/scenes/channel/channel.js b/app/scenes/channel/channel.js
index 609e7c800..ab752fc9c 100644
--- a/app/scenes/channel/channel.js
+++ b/app/scenes/channel/channel.js
@@ -5,10 +5,11 @@ import React from 'react';
import {
Platform,
StatusBar,
- Text
+ View
} from 'react-native';
import KeyboardLayout from 'app/components/layout/keyboard_layout';
+import Loading from 'app/components/loading';
import PostTextbox from 'app/components/post_textbox';
import {Constants} from 'service/constants';
@@ -120,10 +121,12 @@ export default class Channel extends React.PureComponent {
theme
} = this.props;
- if (!currentTeam) {
- return {'Waiting on team'};
- } else if (!currentChannel) {
- return {'Waiting on channel'};
+ if (!currentTeam || !currentChannel) {
+ return (
+
+
+
+ );
}
let teamId = currentChannel.team_id;
diff --git a/app/scenes/channel/channel_post_list/channel_post_list.js b/app/scenes/channel/channel_post_list/channel_post_list.js
index 80359820f..48fea5353 100644
--- a/app/scenes/channel/channel_post_list/channel_post_list.js
+++ b/app/scenes/channel/channel_post_list/channel_post_list.js
@@ -5,6 +5,7 @@ import React, {PropTypes, PureComponent} from 'react';
import {Constants, RequestStatus} from 'service/constants';
+import Loading from 'app/components/loading';
import PostList from 'app/components/post_list';
export default class ChannelPostList extends PureComponent {
@@ -84,8 +85,8 @@ export default class ChannelPostList extends PureComponent {
render() {
const {posts, postsRequests} = this.props;
- if (!posts) {
- return {'waiting on posts'};
+ if (!posts || (postsRequests.getPosts.status === RequestStatus.STARTED && !this.state.didInitialPostsLoad)) {
+ return ;
}
return (
diff --git a/app/scenes/channel/channel_title.js b/app/scenes/channel/channel_title.js
index 63de2ab8c..39b2e6320 100644
--- a/app/scenes/channel/channel_title.js
+++ b/app/scenes/channel/channel_title.js
@@ -8,6 +8,7 @@ import {
TouchableOpacity,
View
} from 'react-native';
+import Icon from 'react-native-vector-icons/FontAwesome';
import {getCurrentChannel} from 'service/selectors/entities/channels';
import {getTheme} from 'service/selectors/entities/preferences';
@@ -16,13 +17,19 @@ function ChannelTitle(props) {
const channelName = props.currentChannel.display_name;
return (
props.emitter('show_channel_info')}
>
-
+
{channelName}
+
);
diff --git a/app/scenes/channel_drawer/channel_drawer.js b/app/scenes/channel_drawer/channel_drawer.js
index e293abe00..c95bd438b 100644
--- a/app/scenes/channel_drawer/channel_drawer.js
+++ b/app/scenes/channel_drawer/channel_drawer.js
@@ -1,30 +1,43 @@
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import React from 'react';
+import React, {PropTypes, PureComponent} from 'react';
+import {InteractionManager} from 'react-native';
import ChannelDrawerList from 'app/components/channel_drawer_list';
-export default class ChannelDrawer extends React.PureComponent {
+export default class ChannelDrawer extends PureComponent {
static propTypes = {
- actions: React.PropTypes.shape({
- closeDrawers: React.PropTypes.func.isRequired,
- handleSelectChannel: React.PropTypes.func.isRequired
+ actions: PropTypes.shape({
+ closeDrawers: PropTypes.func.isRequired,
+ handleSelectChannel: PropTypes.func.isRequired,
+ viewChannel: PropTypes.func.isRequired,
+ markChannelAsRead: PropTypes.func.isRequired
}).isRequired,
- currentTeam: React.PropTypes.object,
- currentChannel: React.PropTypes.object,
- channels: React.PropTypes.object,
- channelMembers: React.PropTypes.object,
- theme: React.PropTypes.object.isRequired
+ currentTeam: PropTypes.object,
+ currentChannel: PropTypes.object,
+ channels: PropTypes.object,
+ channelMembers: PropTypes.object,
+ theme: PropTypes.object.isRequired
};
static defaultProps = {
currentTeam: {},
currentChannel: {}
- }
+ };
selectChannel = (id) => {
- return this.props.actions.handleSelectChannel(id);
+ const {
+ currentChannel,
+ currentTeam
+ } = this.props;
+
+ this.props.actions.closeDrawers();
+ InteractionManager.runAfterInteractions(() => {
+ this.props.actions.markChannelAsRead(id, currentChannel.id);
+ this.props.actions.handleSelectChannel(id);
+ this.props.actions.viewChannel(currentTeam.id, id);
+ });
};
render() {
diff --git a/app/scenes/channel_drawer/channel_drawer_container.js b/app/scenes/channel_drawer/channel_drawer_container.js
index 13a6ae2a8..0d8410b6b 100644
--- a/app/scenes/channel_drawer/channel_drawer_container.js
+++ b/app/scenes/channel_drawer/channel_drawer_container.js
@@ -11,6 +11,8 @@ import {getChannelsByCategory, getCurrentChannel} from 'service/selectors/entiti
import {getTheme} from 'service/selectors/entities/preferences';
import {getCurrentTeam} from 'service/selectors/entities/teams';
+import {viewChannel, markChannelAsRead} from 'service/actions/channels';
+
import ChannelDrawer from './channel_drawer.js';
function mapStateToProps(state) {
@@ -27,7 +29,9 @@ function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
closeDrawers,
- handleSelectChannel
+ handleSelectChannel,
+ viewChannel,
+ markChannelAsRead
}, dispatch)
};
}
diff --git a/app/scenes/more_channels/more_channels.js b/app/scenes/more_channels/more_channels.js
index 1369e4992..12b594558 100644
--- a/app/scenes/more_channels/more_channels.js
+++ b/app/scenes/more_channels/more_channels.js
@@ -10,9 +10,10 @@ import {
View
} from 'react-native';
-import FormattedText from 'app/components/formatted_text';
import ChannelList from 'app/components/custom_list';
import ChannelListRow from 'app/components/custom_list/channel_list_row';
+import FormattedText from 'app/components/formatted_text';
+import Loading from 'app/components/loading';
import SearchBar from 'app/components/search_bar';
import {Constants, RequestStatus} from 'service/constants';
@@ -20,15 +21,6 @@ import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
import CreateButton from './create_button';
-const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
- return StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: theme.centerChannelBg
- }
- });
-});
-
class MoreChannels extends PureComponent {
static propTypes = {
intl: intlShape.isRequired,
@@ -77,6 +69,7 @@ class MoreChannels extends PureComponent {
this.state = {
channels: [],
page: 0,
+ adding: false,
next: true,
searching: false
};
@@ -193,6 +186,7 @@ class MoreChannels extends PureComponent {
};
onSelectChannel = async (id) => {
+ this.setState({adding: true});
this.searchBar.blur();
await this.props.actions.joinChannel(
this.props.currentUserId,
@@ -215,40 +209,60 @@ class MoreChannels extends PureComponent {
const style = getStyleFromTheme(this.props.theme);
const more = this.state.searching ? () => true : this.loadMoreChannels;
- return (
-
-
-
+
+
+ );
+ } else {
+ content = (
+
+
+
+
+
-
-
- );
+ );
+ }
+
+ return content;
}
}
+const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
+ return StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: theme.centerChannelBg
+ }
+ });
+});
+
export default injectIntl(MoreChannels);
diff --git a/app/scenes/more_dms/more_dms.js b/app/scenes/more_dms/more_dms.js
index adfa7e981..6fe634dfd 100644
--- a/app/scenes/more_dms/more_dms.js
+++ b/app/scenes/more_dms/more_dms.js
@@ -11,21 +11,13 @@ import {
} from 'react-native';
import FormattedText from 'app/components/formatted_text';
+import Loading from 'app/components/loading';
import MemberList from 'app/components/custom_list';
import SearchBar from 'app/components/search_bar';
import {createMembersSections, loadingText, renderMemberRow} from 'app/utils/member_list';
import {Constants, RequestStatus} from 'service/constants';
import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
-const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
- return StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: theme.centerChannelBg
- }
- });
-});
-
class MoreDirectMessages extends PureComponent {
static propTypes = {
intl: intlShape.isRequired,
@@ -70,6 +62,7 @@ class MoreDirectMessages extends PureComponent {
this.state = {
profiles: [],
page: 0,
+ adding: false,
next: true,
searching: false
};
@@ -151,9 +144,9 @@ class MoreDirectMessages extends PureComponent {
};
onSelectMember = async (id) => {
+ this.setState({adding: true});
this.searchBar.blur();
await this.props.actions.makeDirectChannel(id);
-
InteractionManager.runAfterInteractions(() => {
this.props.actions.goBack();
});
@@ -166,41 +159,61 @@ class MoreDirectMessages extends PureComponent {
const style = getStyleFromTheme(this.props.theme);
const more = this.state.searching ? () => true : this.loadMoreProfiles;
- return (
-
-
-
+
+
+ );
+ } else {
+ content = (
+
+
+
+
+
-
-
- );
+ );
+ }
+
+ return content;
}
}
+const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
+ return StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: theme.centerChannelBg
+ }
+ });
+});
+
export default injectIntl(MoreDirectMessages);
diff --git a/app/scenes/navigationSceneConnect.js b/app/scenes/navigationSceneConnect.js
index eec943786..6cd806215 100644
--- a/app/scenes/navigationSceneConnect.js
+++ b/app/scenes/navigationSceneConnect.js
@@ -22,15 +22,11 @@ const defaults = {
onPress={props.onNavigateBack}
>
-
);
},
diff --git a/app/scenes/right_menu_drawer/right_menu_drawer.js b/app/scenes/right_menu_drawer/right_menu_drawer.js
index c1f27d719..d48dad7a8 100644
--- a/app/scenes/right_menu_drawer/right_menu_drawer.js
+++ b/app/scenes/right_menu_drawer/right_menu_drawer.js
@@ -15,38 +15,6 @@ import {makeStyleSheetFromTheme} from 'app/utils/theme';
import RightMenuDrawerItem from './right_menu_drawer_item';
-const getStyleSheet = makeStyleSheetFromTheme((theme) => {
- return StyleSheet.create({
- container: {
- backgroundColor: theme.sidebarBg,
- flex: 1,
- ...Platform.select({
- ios: {
- paddingTop: 20
- },
- android: {
- paddingTop: 5
- }
- })
- },
- itemText: {
- color: 'white'
- },
- icon: {
- color: 'white',
- width: 25
- },
- mentionIcon: {
- fontSize: 17,
- fontWeight: 'bold'
- },
- divider: {
- borderColor: 'rgba(255, 255, 255, 0.6)',
- borderTopWidth: StyleSheet.hairlineWidth
- }
- });
-});
-
export default class RightMenuDrawer extends React.Component {
static propTypes = {
actions: React.PropTypes.shape({
@@ -55,7 +23,7 @@ export default class RightMenuDrawer extends React.Component {
logout: React.PropTypes.func.isRequired
}).isRequired,
theme: React.PropTypes.object
- }
+ };
render() {
const Styles = getStyleSheet(this.props.theme);
@@ -140,3 +108,35 @@ export default class RightMenuDrawer extends React.Component {
function Divider(props) {
return ;
}
+
+const getStyleSheet = makeStyleSheetFromTheme((theme) => {
+ return StyleSheet.create({
+ container: {
+ backgroundColor: theme.sidebarBg,
+ flex: 1,
+ ...Platform.select({
+ ios: {
+ paddingTop: 20
+ },
+ android: {
+ paddingTop: 5
+ }
+ })
+ },
+ itemText: {
+ color: 'white'
+ },
+ icon: {
+ color: 'white',
+ width: 25
+ },
+ mentionIcon: {
+ fontSize: 17,
+ fontWeight: 'bold'
+ },
+ divider: {
+ borderColor: 'rgba(255, 255, 255, 0.6)',
+ borderTopWidth: StyleSheet.hairlineWidth
+ }
+ });
+});
diff --git a/app/scenes/select_team/select_team.js b/app/scenes/select_team/select_team.js
index f714db81f..a5171ea11 100644
--- a/app/scenes/select_team/select_team.js
+++ b/app/scenes/select_team/select_team.js
@@ -26,7 +26,6 @@ export default class SelectTeam extends React.Component {
unsubscribeFromHeaderEvent: React.PropTypes.func.isRequired,
actions: React.PropTypes.shape({
goBackToChannelView: React.PropTypes.func.isRequired,
- closeDrawers: React.PropTypes.func.isRequired,
handleTeamChange: React.PropTypes.func.isRequired
}).isRequired
};
@@ -59,14 +58,11 @@ export default class SelectTeam extends React.Component {
onSelectTeam = async (team) => {
const {
goBackToChannelView,
- closeDrawers,
handleTeamChange
-
} = this.props.actions;
await handleTeamChange(team);
- await InteractionManager.runAfterInteractions(goBackToChannelView);
- InteractionManager.runAfterInteractions(() => setTimeout(closeDrawers, 200));
+ InteractionManager.runAfterInteractions(goBackToChannelView);
};
render() {
diff --git a/app/scenes/select_team/select_team_container.js b/app/scenes/select_team/select_team_container.js
index e21eed828..06f10e629 100644
--- a/app/scenes/select_team/select_team_container.js
+++ b/app/scenes/select_team/select_team_container.js
@@ -5,7 +5,7 @@ import {bindActionCreators} from 'redux';
import navigationSceneConnect from '../navigationSceneConnect';
-import {goBack, closeDrawers} from 'app/actions/navigation';
+import {goBack} from 'app/actions/navigation';
import {handleTeamChange} from 'app/actions/views/select_team';
import {getCurrentTeam} from 'service/selectors/entities/teams';
@@ -26,7 +26,6 @@ function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
goBackToChannelView: goBack,
- closeDrawers,
handleTeamChange
}, dispatch)
};