PLT-5836 Smooth transitions and add activity indicators (#339)
This commit is contained in:
parent
f5745cbc0e
commit
f3dbb72f65
17 changed files with 289 additions and 244 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = (
|
||||
<View style={{flex: 1, flexDirection: 'column', justifyContent: 'center', alignItems: 'center'}}>
|
||||
<TouchableOpacity
|
||||
onPress={this.onPress}
|
||||
style={{paddingHorizontal: 15}}
|
||||
>
|
||||
<FormattedText
|
||||
id={labelId}
|
||||
defaultMessage={labelDefaultMessage}
|
||||
style={{color}}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
contents = (
|
||||
<View style={{flex: 1, flexDirection: 'column', justifyContent: 'center', alignItems: 'center', paddingHorizontal: 15}}>
|
||||
<FormattedText
|
||||
id={labelId}
|
||||
defaultMessage={labelDefaultMessage}
|
||||
style={{color}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
|
|
@ -88,20 +113,7 @@ class ActionButton extends PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{flexDirection: 'column', justifyContent: 'center', alignItems: 'center', flex: 1}}>
|
||||
<TouchableOpacity
|
||||
onPress={this.onPress}
|
||||
style={{paddingHorizontal: 15}}
|
||||
>
|
||||
<FormattedText
|
||||
id={labelId}
|
||||
defaultMessage={labelDefaultMessage}
|
||||
style={{color}}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 <Text>{'Waiting on team'}</Text>;
|
||||
} else if (!currentChannel) {
|
||||
return <Text>{'Waiting on channel'}</Text>;
|
||||
if (!currentTeam || !currentChannel) {
|
||||
return (
|
||||
<View style={{flex: 1, backgroundColor: theme.centerChannelBg}}>
|
||||
<Loading/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
let teamId = currentChannel.team_id;
|
||||
|
|
|
|||
|
|
@ -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 <Text>{'waiting on posts'}</Text>;
|
||||
if (!posts || (postsRequests.getPosts.status === RequestStatus.STARTED && !this.state.didInitialPostsLoad)) {
|
||||
return <Loading/>;
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<TouchableOpacity
|
||||
style={{flexDirection: 'row', flex: 1, alignItems: 'center'}}
|
||||
style={{flexDirection: 'row', flex: 1}}
|
||||
onPress={() => props.emitter('show_channel_info')}
|
||||
>
|
||||
<View>
|
||||
<View style={{flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center'}}>
|
||||
<Text style={{color: props.theme.sidebarHeaderTextColor, fontSize: 15, fontWeight: 'bold'}}>
|
||||
{channelName}
|
||||
</Text>
|
||||
<Icon
|
||||
style={{marginHorizontal: 6}}
|
||||
size={12}
|
||||
name='chevron-down'
|
||||
color={props.theme.sidebarHeaderTextColor}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<View style={style.container}>
|
||||
<View
|
||||
style={{marginVertical: 5}}
|
||||
>
|
||||
<SearchBar
|
||||
ref={this.searchBarRef}
|
||||
placeholder={formatMessage({id: 'search_bar.search', defaultMesage: 'Search'})}
|
||||
height={27}
|
||||
fontSize={14}
|
||||
textColor={this.props.theme.centerChannelColor}
|
||||
hideBackground={true}
|
||||
textFieldBackgroundColor={changeOpacity(this.props.theme.centerChannelColor, 0.07)}
|
||||
onChange={this.searchProfiles}
|
||||
onSearchButtonPress={this.onSearchButtonPress}
|
||||
onCancelButtonPress={this.cancelSearch}
|
||||
let content;
|
||||
if (this.state.adding) {
|
||||
content = (
|
||||
<View style={style.container}>
|
||||
<Loading/>
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<View style={style.container}>
|
||||
<View
|
||||
style={{marginVertical: 5}}
|
||||
>
|
||||
<SearchBar
|
||||
ref={this.searchBarRef}
|
||||
placeholder={formatMessage({id: 'search_bar.search', defaultMesage: 'Search'})}
|
||||
height={27}
|
||||
fontSize={14}
|
||||
textColor={this.props.theme.centerChannelColor}
|
||||
hideBackground={true}
|
||||
textFieldBackgroundColor={changeOpacity(this.props.theme.centerChannelColor, 0.07)}
|
||||
onChange={this.searchProfiles}
|
||||
onSearchButtonPress={this.onSearchButtonPress}
|
||||
onCancelButtonPress={this.cancelSearch}
|
||||
/>
|
||||
</View>
|
||||
<ChannelList
|
||||
data={this.state.channels}
|
||||
theme={this.props.theme}
|
||||
searching={this.state.searching}
|
||||
onListEndReached={more}
|
||||
loading={isLoading}
|
||||
selectable={false}
|
||||
listScrollRenderAheadDistance={50}
|
||||
showSections={false}
|
||||
renderRow={this.renderChannelRow}
|
||||
onRowPress={this.onSelectChannel}
|
||||
loadingText={{id: 'mobile.loading_channels', defaultMessage: 'Loading Channels...'}}
|
||||
/>
|
||||
</View>
|
||||
<ChannelList
|
||||
data={this.state.channels}
|
||||
theme={this.props.theme}
|
||||
searching={this.state.searching}
|
||||
onListEndReached={more}
|
||||
loading={isLoading}
|
||||
selectable={false}
|
||||
listScrollRenderAheadDistance={50}
|
||||
showSections={false}
|
||||
renderRow={this.renderChannelRow}
|
||||
onRowPress={this.onSelectChannel}
|
||||
loadingText={{id: 'mobile.loading_channels', defaultMessage: 'Loading Channels...'}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
||||
return StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.centerChannelBg
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
export default injectIntl(MoreChannels);
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<View style={style.container}>
|
||||
<View
|
||||
style={{marginVertical: 5}}
|
||||
>
|
||||
<SearchBar
|
||||
ref={this.searchBarRef}
|
||||
placeholder={formatMessage({id: 'search_bar.search', defaultMesage: 'Search'})}
|
||||
height={27}
|
||||
fontSize={14}
|
||||
textColor={this.props.theme.centerChannelColor}
|
||||
hideBackground={true}
|
||||
textFieldBackgroundColor={changeOpacity(this.props.theme.centerChannelColor, 0.07)}
|
||||
onChange={this.searchProfiles}
|
||||
onSearchButtonPress={this.onSearchButtonPress}
|
||||
onCancelButtonPress={this.cancelSearch}
|
||||
let content;
|
||||
if (this.state.adding) {
|
||||
content = (
|
||||
<View style={style.container}>
|
||||
<Loading/>
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<View style={style.container}>
|
||||
<View
|
||||
style={{marginVertical: 5}}
|
||||
>
|
||||
<SearchBar
|
||||
ref={this.searchBarRef}
|
||||
placeholder={formatMessage({id: 'search_bar.search', defaultMesage: 'Search'})}
|
||||
height={27}
|
||||
fontSize={14}
|
||||
textColor={this.props.theme.centerChannelColor}
|
||||
hideBackground={true}
|
||||
textFieldBackgroundColor={changeOpacity(this.props.theme.centerChannelColor, 0.07)}
|
||||
onChange={this.searchProfiles}
|
||||
onSearchButtonPress={this.onSearchButtonPress}
|
||||
onCancelButtonPress={this.cancelSearch}
|
||||
/>
|
||||
</View>
|
||||
<MemberList
|
||||
data={this.state.profiles}
|
||||
theme={this.props.theme}
|
||||
searching={this.state.searching}
|
||||
onListEndReached={more}
|
||||
preferences={this.props.preferences}
|
||||
loading={isLoading}
|
||||
selectable={false}
|
||||
listScrollRenderAheadDistance={50}
|
||||
createSections={createMembersSections}
|
||||
renderRow={renderMemberRow}
|
||||
onRowPress={this.onSelectMember}
|
||||
loadingText={loadingText}
|
||||
/>
|
||||
</View>
|
||||
<MemberList
|
||||
data={this.state.profiles}
|
||||
theme={this.props.theme}
|
||||
searching={this.state.searching}
|
||||
onListEndReached={more}
|
||||
preferences={this.props.preferences}
|
||||
loading={isLoading}
|
||||
selectable={false}
|
||||
listScrollRenderAheadDistance={50}
|
||||
createSections={createMembersSections}
|
||||
renderRow={renderMemberRow}
|
||||
onRowPress={this.onSelectMember}
|
||||
loadingText={loadingText}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
||||
return StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.centerChannelBg
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
export default injectIntl(MoreDirectMessages);
|
||||
|
|
|
|||
|
|
@ -22,15 +22,11 @@ const defaults = {
|
|||
onPress={props.onNavigateBack}
|
||||
>
|
||||
<Icon
|
||||
style={{fontWeight: 'bold'}}
|
||||
name='angle-left'
|
||||
size={18}
|
||||
size={35}
|
||||
color={theme.sidebarHeaderTextColor}
|
||||
/>
|
||||
<FormattedText
|
||||
id='mobile.routes.back'
|
||||
defaultMessage='Back'
|
||||
style={{color: theme.sidebarHeaderTextColor, marginLeft: 10}}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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 <View {...props}/>;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue