Various UI Fixes (#384)
* Various UI Fixes * ability to scroll through teams * Fix drawer when not logged in * fix channel info DM status * channel drawer spacing of icons made equal * address feedback
This commit is contained in:
parent
56a27ce7ad
commit
c049cb0f9d
17 changed files with 239 additions and 308 deletions
|
|
@ -232,7 +232,13 @@ export function requestCloseModal() {
|
|||
|
||||
export function renderDrawer() {
|
||||
return async (dispatch, getState) => {
|
||||
dispatch({type: NavigationTypes.NAVIGATION_RENDER_LEFT_DRAWER}, getState);
|
||||
dispatch({type: NavigationTypes.NAVIGATION_RENDER_LEFT_DRAWER, data: true}, getState);
|
||||
};
|
||||
}
|
||||
|
||||
export function unrenderDrawer() {
|
||||
return async (dispatch, getState) => {
|
||||
dispatch({type: NavigationTypes.NAVIGATION_RENDER_LEFT_DRAWER, data: false}, getState);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@ export default class ChannelDrawerItem extends PureComponent {
|
|||
theme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
handleLongPress = (channel) => {
|
||||
if (this.props.onLongPress) {
|
||||
this.props.onLongPress(channel);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
channel,
|
||||
|
|
@ -81,7 +87,7 @@ export default class ChannelDrawerItem extends PureComponent {
|
|||
onPress={() => this.props.onSelectChannel(channel)}
|
||||
delayLongPress={1000}
|
||||
onLongPress={() => {
|
||||
this.props.onLongPress(channel);
|
||||
this.handleLongPress(channel);
|
||||
}}
|
||||
>
|
||||
<View style={style.container}>
|
||||
|
|
@ -142,10 +148,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
badgeContainer: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: theme.mentionBj,
|
||||
borderRadius: 7,
|
||||
height: 15,
|
||||
justifyContent: 'center',
|
||||
marginRight: 16,
|
||||
width: 15
|
||||
width: 16
|
||||
},
|
||||
badge: {
|
||||
color: theme.mentionColor,
|
||||
|
|
|
|||
|
|
@ -154,133 +154,6 @@ class ChannelDrawerList extends Component {
|
|||
);
|
||||
};
|
||||
|
||||
onShowModal = (channel) => {
|
||||
const {formatMessage} = this.props.intl;
|
||||
let open;
|
||||
let close;
|
||||
let favorite;
|
||||
let term;
|
||||
let title;
|
||||
|
||||
switch (channel.type) {
|
||||
case Constants.DM_CHANNEL:
|
||||
title = formatMessage({
|
||||
id: 'mobile.channel_list.modalTitle',
|
||||
defaultMessage: 'Select an action for the {term} {name}'},
|
||||
{
|
||||
name: channel.display_name,
|
||||
term: formatMessage({id: 'mobile.channel_list.dm', defaultMessage: 'Direct Message'}).toLowerCase()
|
||||
});
|
||||
|
||||
open = {
|
||||
action: () => {
|
||||
this.props.actions.closeOptionsModal();
|
||||
this.onSelectChannel(channel);
|
||||
},
|
||||
text: formatMessage({id: 'mobile.channel_list.openDM', defaultMessage: 'Open Direct Message'})
|
||||
};
|
||||
|
||||
close = {
|
||||
action: () => {
|
||||
this.handleClose(channel);
|
||||
},
|
||||
text: formatMessage({id: 'mobile.channel_list.closeDM', defaultMessage: 'Close Direct Message'}),
|
||||
textStyle: {
|
||||
color: '#CC3239'
|
||||
}
|
||||
};
|
||||
break;
|
||||
case Constants.GM_CHANNEL:
|
||||
title = formatMessage({
|
||||
id: 'mobile.channel_list.modalTitle',
|
||||
defaultMessage: 'Select an action for the {term} {name}'},
|
||||
{
|
||||
name: channel.display_name,
|
||||
term: formatMessage({id: 'mobile.channel_list.gm', defaultMessage: 'Group Message'}).toLowerCase()
|
||||
});
|
||||
|
||||
open = {
|
||||
action: () => {
|
||||
this.props.actions.closeOptionsModal();
|
||||
this.onSelectChannel(channel);
|
||||
},
|
||||
text: formatMessage({id: 'mobile.channel_list.openGM', defaultMessage: 'Open Group Message'})
|
||||
};
|
||||
|
||||
close = {
|
||||
action: () => {
|
||||
this.handleClose(channel);
|
||||
},
|
||||
text: formatMessage({id: 'mobile.channel_list.closeGM', defaultMessage: 'Close Group Message'}),
|
||||
textStyle: {
|
||||
color: '#CC3239'
|
||||
}
|
||||
};
|
||||
break;
|
||||
default:
|
||||
term = channel.type === Constants.OPEN_CHANNEL ?
|
||||
formatMessage({id: 'mobile.channel_list.publicChannel', defaultMessage: 'Public Channel'}) :
|
||||
formatMessage({id: 'mobile.channel_list.privateChannel', defaultMessage: 'Private Channel'});
|
||||
|
||||
title = formatMessage({
|
||||
id: 'mobile.channel_list.modalTitle',
|
||||
defaultMessage: 'Select an action for the {term} {name}'},
|
||||
{
|
||||
name: channel.display_name,
|
||||
term: term.toLowerCase()
|
||||
});
|
||||
|
||||
open = {
|
||||
action: () => {
|
||||
this.props.actions.closeOptionsModal();
|
||||
this.onSelectChannel(channel);
|
||||
},
|
||||
text: formatMessage({id: 'mobile.channel_list.openChannel', defaultMessage: 'Open {term}'}, {
|
||||
term
|
||||
})
|
||||
};
|
||||
|
||||
if (channel.name !== Constants.DEFAULT_CHANNEL) {
|
||||
close = {
|
||||
action: () => {
|
||||
this.handleLeave(channel, term);
|
||||
},
|
||||
text: formatMessage({id: 'channel_header.leave', defaultMessage: 'Leave {term}'}, {
|
||||
term
|
||||
}),
|
||||
textStyle: {
|
||||
color: '#CC3239'
|
||||
}
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (channel.isFavorite) {
|
||||
favorite = {
|
||||
action: () => {
|
||||
this.props.actions.closeOptionsModal();
|
||||
this.props.actions.unmarkFavorite(channel.id);
|
||||
},
|
||||
text: formatMessage({id: 'channelHeader.removeFromFavorites', defaultMessage: 'Remove from Favorites'})
|
||||
};
|
||||
} else {
|
||||
favorite = {
|
||||
action: () => {
|
||||
this.props.actions.closeOptionsModal();
|
||||
this.props.actions.markFavorite(channel.id);
|
||||
},
|
||||
text: formatMessage({id: 'channelHeader.addToFavorites', defaultMessage: 'Add to Favorites'})
|
||||
};
|
||||
}
|
||||
|
||||
const options = [open, favorite];
|
||||
if (close) {
|
||||
options.push(close);
|
||||
}
|
||||
this.props.actions.showOptionsModal({title, items: options});
|
||||
};
|
||||
|
||||
getUnreadMessages = (channel) => {
|
||||
const member = this.props.channelMembers[channel.id];
|
||||
let mentions = 0;
|
||||
|
|
@ -328,7 +201,6 @@ class ChannelDrawerList extends Component {
|
|||
hasUnread={unread}
|
||||
mentions={mentions}
|
||||
onSelectChannel={this.onSelectChannel}
|
||||
onLongPress={this.onShowModal}
|
||||
isActive={channel.isCurrent}
|
||||
theme={this.props.theme}
|
||||
/>
|
||||
|
|
@ -557,7 +429,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
width: 50
|
||||
},
|
||||
settings: {
|
||||
color: theme.sidebarText,
|
||||
color: theme.sidebarHeaderTextColor,
|
||||
fontSize: 18,
|
||||
fontWeight: '300'
|
||||
},
|
||||
|
|
@ -578,7 +450,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
lineHeight: 18
|
||||
},
|
||||
divider: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.1),
|
||||
backgroundColor: changeOpacity(theme.sidebarText, 0.1),
|
||||
height: 1
|
||||
},
|
||||
actionContainer: {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ function channelIcon(props) {
|
|||
return (
|
||||
<Icon
|
||||
name='lock'
|
||||
style={[style.icon, unreadIcon, activeIcon, {fontSize: size}]}
|
||||
style={[style.icon, unreadIcon, activeIcon, {fontSize: size + 1}]}
|
||||
/>
|
||||
);
|
||||
} else if (type === Constants.GM_CHANNEL) {
|
||||
|
|
@ -90,7 +90,7 @@ function channelIcon(props) {
|
|||
<OfflineStatus
|
||||
width={size}
|
||||
height={size}
|
||||
color={changeOpacity(theme.centerChannelColor, 0.4)}
|
||||
color={changeOpacity(theme.sidebarText, 0.5)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
|
@ -116,6 +116,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
paddingRight: 12
|
||||
},
|
||||
groupBox: {
|
||||
alignSelf: 'flex-start',
|
||||
alignItems: 'center',
|
||||
borderWidth: 1,
|
||||
borderColor: changeOpacity(theme.sidebarText, 0.4),
|
||||
|
|
|
|||
|
|
@ -1,46 +1,10 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
import React, {PropTypes, PureComponent} from 'react';
|
||||
import {ListView, StyleSheet, Text, View} from 'react-native';
|
||||
import {ListView, Platform, StyleSheet, Text, View} from 'react-native';
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
|
||||
|
||||
const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
||||
return StyleSheet.create({
|
||||
listView: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.centerChannelBg
|
||||
},
|
||||
loadingText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.6)
|
||||
},
|
||||
sectionContainer: {
|
||||
backgroundColor: theme.sidebarHeaderBg,
|
||||
paddingLeft: 10,
|
||||
paddingVertical: 2
|
||||
},
|
||||
sectionText: {
|
||||
fontWeight: '600',
|
||||
color: theme.sidebarHeaderTextColor
|
||||
},
|
||||
separator: {
|
||||
height: 1,
|
||||
flex: 1,
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.1)
|
||||
},
|
||||
noResultContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
noResultText: {
|
||||
fontSize: 26,
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5)
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
export default class CustomList extends PureComponent {
|
||||
static propTypes = {
|
||||
data: PropTypes.array.isRequired,
|
||||
|
|
@ -225,3 +189,44 @@ export default class CustomList extends PureComponent {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
||||
return StyleSheet.create({
|
||||
listView: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
...Platform.select({
|
||||
android: {
|
||||
marginBottom: 20
|
||||
}
|
||||
})
|
||||
},
|
||||
loadingText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.6)
|
||||
},
|
||||
sectionContainer: {
|
||||
backgroundColor: theme.sidebarHeaderBg,
|
||||
paddingLeft: 10,
|
||||
paddingVertical: 2
|
||||
},
|
||||
sectionText: {
|
||||
fontWeight: '600',
|
||||
color: theme.sidebarHeaderTextColor
|
||||
},
|
||||
separator: {
|
||||
height: 1,
|
||||
flex: 1,
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.1)
|
||||
},
|
||||
noResultContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
noResultText: {
|
||||
fontSize: 26,
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5)
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {PropTypes, PureComponent} from 'react';
|
||||
import {AppState, View} from 'react-native';
|
||||
import React, {Component, PropTypes} from 'react';
|
||||
import {AppState, StatusBar, View} from 'react-native';
|
||||
import {IntlProvider} from 'react-intl';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ import {Constants} from 'mattermost-redux/constants';
|
|||
import {getTranslations} from 'app/i18n';
|
||||
import EventEmitter from 'mattermost-redux/utils/event_emitter';
|
||||
|
||||
export default class Root extends PureComponent {
|
||||
export default class Root extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node,
|
||||
currentTeamId: PropTypes.string,
|
||||
|
|
@ -66,6 +66,7 @@ export default class Root extends PureComponent {
|
|||
messages={getTranslations(locale)}
|
||||
>
|
||||
<View style={{flex: 1}}>
|
||||
<StatusBar barStyle='light-content'/>
|
||||
{this.props.children}
|
||||
<PushNotification/>
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export default class SearchBarIos extends PureComponent {
|
|||
|
||||
static defaultProps = {
|
||||
barStyle: 'default',
|
||||
searchBarStyle: 'default',
|
||||
searchBarStyle: 'minimal',
|
||||
placeholder: 'Search',
|
||||
showCancelButton: true,
|
||||
hideBackground: true,
|
||||
|
|
@ -77,7 +77,7 @@ export default class SearchBarIos extends PureComponent {
|
|||
text={this.props.text}
|
||||
placeholder={this.props.placeholder}
|
||||
showsCancelButton={this.state.displayCancelButton}
|
||||
hideBackground={this.props.hideBackground}
|
||||
hideBackground={false}
|
||||
textFieldBackgroundColor={this.props.textFieldBackgroundColor}
|
||||
placeholderTextColor={this.props.placeholderTextColor}
|
||||
textColor={this.props.textColor}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// See License.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import Svg, {
|
||||
Ellipse,
|
||||
G,
|
||||
|
|
@ -16,30 +17,33 @@ export default class AwayStatus extends React.Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
const {color, height, width} = this.props;
|
||||
return (
|
||||
<Svg
|
||||
width={this.props.width}
|
||||
height={this.props.height}
|
||||
viewBox='-299 391 12 12'
|
||||
>
|
||||
<G>
|
||||
<Ellipse
|
||||
cx='-294.6'
|
||||
cy='394'
|
||||
rx='2.5'
|
||||
ry='2.5'
|
||||
fill={this.props.color}
|
||||
/>
|
||||
<View style={{height, width, alignItems: 'flex-start'}}>
|
||||
<Svg
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox='-299 391 12 12'
|
||||
>
|
||||
<G>
|
||||
<Ellipse
|
||||
cx='-294.6'
|
||||
cy='394'
|
||||
rx='2.5'
|
||||
ry='2.5'
|
||||
fill={color}
|
||||
/>
|
||||
<Path
|
||||
d='M-293.8,399.4c0-0.4,0.1-0.7,0.2-1c-0.3,0.1-0.6,0.2-1,0.2c-2.5,0-2.5-2-2.5-2s-1,0.1-1.2,0.5c-0.4,0.6-0.6,1.7-0.7,2.5 c0,0.1-0.1,0.5,0,0.6c0.2,1.3,2.2,2.3,4.4,2.4c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0.7,0,1.4-0.1,2-0.3 C-293.3,401.5-293.8,400.5-293.8,399.4z'
|
||||
fill={color}
|
||||
/>
|
||||
</G>
|
||||
<Path
|
||||
d='M-293.8,399.4c0-0.4,0.1-0.7,0.2-1c-0.3,0.1-0.6,0.2-1,0.2c-2.5,0-2.5-2-2.5-2s-1,0.1-1.2,0.5c-0.4,0.6-0.6,1.7-0.7,2.5 c0,0.1-0.1,0.5,0,0.6c0.2,1.3,2.2,2.3,4.4,2.4c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0.7,0,1.4-0.1,2-0.3 C-293.3,401.5-293.8,400.5-293.8,399.4z'
|
||||
fill={this.props.color}
|
||||
d='M-287,400c0,0.1-0.1,0.1-0.1,0.1l-4.9,0c-0.1,0-0.1-0.1-0.1-0.1v-1.6c0-0.1,0.1-0.1,0.1-0.1l4.9,0c0.1,0,0.1,0.1,0.1,0.1 V400z'
|
||||
fill={color}
|
||||
/>
|
||||
</G>
|
||||
<Path
|
||||
d='M-287,400c0,0.1-0.1,0.1-0.1,0.1l-4.9,0c-0.1,0-0.1-0.1-0.1-0.1v-1.6c0-0.1,0.1-0.1,0.1-0.1l4.9,0c0.1,0,0.1,0.1,0.1,0.1 V400z'
|
||||
fill={this.props.color}
|
||||
/>
|
||||
</Svg>
|
||||
</Svg>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// See License.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import Svg, {
|
||||
Ellipse,
|
||||
G,
|
||||
|
|
@ -16,34 +17,37 @@ export default class OfflineStatus extends React.Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
const {color, height, width} = this.props;
|
||||
return (
|
||||
<Svg
|
||||
width={this.props.width}
|
||||
height={this.props.height}
|
||||
viewBox='-299 391 12 12'
|
||||
>
|
||||
<G>
|
||||
<View style={{height, width, alignItems: 'flex-start'}}>
|
||||
<Svg
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox='-299 391 12 12'
|
||||
>
|
||||
<G>
|
||||
<G>
|
||||
<Ellipse
|
||||
cx='-294.5'
|
||||
cy='394'
|
||||
rx='2.5'
|
||||
ry='2.5'
|
||||
fill={color}
|
||||
/>
|
||||
<Path
|
||||
d='M-294.3,399.7c0-0.4,0.1-0.8,0.2-1.2c-0.1,0-0.2,0-0.4,0c-2.5,0-2.5-2-2.5-2s-1,0.1-1.2,0.5c-0.4,0.6-0.6,1.7-0.7,2.5 c0,0.1-0.1,0.5,0,0.6c0.2,1.3,2.2,2.3,4.4,2.4h0.1h0.1c0.3,0,0.7,0,1-0.1C-293.9,401.6-294.3,400.7-294.3,399.7z'
|
||||
fill={color}
|
||||
/>
|
||||
</G>
|
||||
</G>
|
||||
<G>
|
||||
<Ellipse
|
||||
cx='-294.5'
|
||||
cy='394'
|
||||
rx='2.5'
|
||||
ry='2.5'
|
||||
fill={this.props.color}
|
||||
/>
|
||||
<Path
|
||||
d='M-294.3,399.7c0-0.4,0.1-0.8,0.2-1.2c-0.1,0-0.2,0-0.4,0c-2.5,0-2.5-2-2.5-2s-1,0.1-1.2,0.5c-0.4,0.6-0.6,1.7-0.7,2.5 c0,0.1-0.1,0.5,0,0.6c0.2,1.3,2.2,2.3,4.4,2.4h0.1h0.1c0.3,0,0.7,0,1-0.1C-293.9,401.6-294.3,400.7-294.3,399.7z'
|
||||
fill={this.props.color}
|
||||
d='M-288.9,399.4l1.8-1.8c0.1-0.1,0.1-0.3,0-0.3l-0.7-0.7c-0.1-0.1-0.3-0.1-0.3,0l-1.8,1.8l-1.8-1.8c-0.1-0.1-0.3-0.1-0.3,0 l-0.7,0.7c-0.1,0.1-0.1,0.3,0,0.3l1.8,1.8l-1.8,1.8c-0.1,0.1-0.1,0.3,0,0.3l0.7,0.7c0.1,0.1,0.3,0.1,0.3,0l1.8-1.8l1.8,1.8 c0.1,0.1,0.3,0.1,0.3,0l0.7-0.7c0.1-0.1,0.1-0.3,0-0.3L-288.9,399.4z'
|
||||
fill={color}
|
||||
/>
|
||||
</G>
|
||||
</G>
|
||||
<G>
|
||||
<Path
|
||||
d='M-288.9,399.4l1.8-1.8c0.1-0.1,0.1-0.3,0-0.3l-0.7-0.7c-0.1-0.1-0.3-0.1-0.3,0l-1.8,1.8l-1.8-1.8c-0.1-0.1-0.3-0.1-0.3,0 l-0.7,0.7c-0.1,0.1-0.1,0.3,0,0.3l1.8,1.8l-1.8,1.8c-0.1,0.1-0.1,0.3,0,0.3l0.7,0.7c0.1,0.1,0.3,0.1,0.3,0l1.8-1.8l1.8,1.8 c0.1,0.1,0.3,0.1,0.3,0l0.7-0.7c0.1-0.1,0.1-0.3,0-0.3L-288.9,399.4z'
|
||||
fill={this.props.color}
|
||||
/>
|
||||
</G>
|
||||
</Svg>
|
||||
</Svg>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// See License.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import Svg, {
|
||||
Ellipse,
|
||||
G,
|
||||
|
|
@ -16,38 +17,41 @@ export default class OnlineStatus extends React.Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
const {color, height, width} = this.props;
|
||||
return (
|
||||
<Svg
|
||||
width={this.props.width}
|
||||
height={this.props.height}
|
||||
viewBox='-243 245 12 12'
|
||||
>
|
||||
<G>
|
||||
<Path
|
||||
d='M-236,250.5C-236,250.5-236,250.5-236,250.5C-236,250.5-236,250.5-236,250.5C-236,250.5-236,250.5-236,250.5z'
|
||||
fill={this.props.color}
|
||||
/>
|
||||
<Ellipse
|
||||
cx='-238.5'
|
||||
cy='248'
|
||||
rx='2.5'
|
||||
ry='2.5'
|
||||
fill={this.props.color}
|
||||
/>
|
||||
</G>
|
||||
<Path
|
||||
d='M-238.9,253.8c0-0.4,0.1-0.9,0.2-1.3c-2.2-0.2-2.2-2-2.2-2s-1,0.1-1.2,0.5c-0.4,0.6-0.6,1.7-0.7,2.5c0,0.1-0.1,0.5,0,0.6 c0.2,1.3,2.2,2.3,4.4,2.4c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0C-238.7,255.7-238.9,254.8-238.9,253.8z'
|
||||
fill={this.props.color}
|
||||
/>
|
||||
<G>
|
||||
<View style={{height, width, alignItems: 'flex-start'}}>
|
||||
<Svg
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox='-243 245 12 12'
|
||||
>
|
||||
<G>
|
||||
<Path
|
||||
d='M-232.3,250.1l1.3,1.3c0,0,0,0.1,0,0.1l-4.1,4.1c0,0,0,0-0.1,0c0,0,0,0,0,0l-2.7-2.7c0,0,0-0.1,0-0.1l1.2-1.2 c0,0,0.1,0,0.1,0l1.4,1.4l2.9-2.9C-232.4,250.1-232.3,250.1-232.3,250.1z'
|
||||
fill={this.props.color}
|
||||
d='M-236,250.5C-236,250.5-236,250.5-236,250.5C-236,250.5-236,250.5-236,250.5C-236,250.5-236,250.5-236,250.5z'
|
||||
fill={color}
|
||||
/>
|
||||
<Ellipse
|
||||
cx='-238.5'
|
||||
cy='248'
|
||||
rx='2.5'
|
||||
ry='2.5'
|
||||
fill={color}
|
||||
/>
|
||||
</G>
|
||||
</G>
|
||||
</Svg>
|
||||
<Path
|
||||
d='M-238.9,253.8c0-0.4,0.1-0.9,0.2-1.3c-2.2-0.2-2.2-2-2.2-2s-1,0.1-1.2,0.5c-0.4,0.6-0.6,1.7-0.7,2.5c0,0.1-0.1,0.5,0,0.6 c0.2,1.3,2.2,2.3,4.4,2.4c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0C-238.7,255.7-238.9,254.8-238.9,253.8z'
|
||||
fill={color}
|
||||
/>
|
||||
<G>
|
||||
<G>
|
||||
<Path
|
||||
d='M-232.3,250.1l1.3,1.3c0,0,0,0.1,0,0.1l-4.1,4.1c0,0,0,0-0.1,0c0,0,0,0,0,0l-2.7-2.7c0,0,0-0.1,0-0.1l1.2-1.2 c0,0,0.1,0,0.1,0l1.4,1.4l2.9-2.9C-232.4,250.1-232.3,250.1-232.3,250.1z'
|
||||
fill={color}
|
||||
/>
|
||||
</G>
|
||||
</G>
|
||||
</Svg>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ class Router extends Component {
|
|||
deviceWidth: event.nativeEvent.layout.width
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleDrawerTween = (ratio) => {
|
||||
const opacity = (ratio / 2);
|
||||
|
|
@ -216,8 +216,8 @@ class Router extends Component {
|
|||
opacity
|
||||
},
|
||||
drawerOverlay: {
|
||||
backgroundColor: '#000',
|
||||
opacity: (1 - ratio) / 2
|
||||
backgroundColor: ratio ? '#000' : '#FFF',
|
||||
opacity: ratio ? (1 - ratio) / 2 : 1
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ export default function(state = initialState, action) {
|
|||
case NavigationTypes.NAVIGATION_RENDER_LEFT_DRAWER: {
|
||||
return {
|
||||
...state,
|
||||
shouldRenderDrawer: true
|
||||
shouldRenderDrawer: action.data
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ class ChannelInfo extends PureComponent {
|
|||
currentChannelCreatorName,
|
||||
currentChannelMemberCount,
|
||||
canManageUsers,
|
||||
status,
|
||||
theme
|
||||
} = this.props;
|
||||
|
||||
|
|
@ -186,6 +187,7 @@ class ChannelInfo extends PureComponent {
|
|||
displayName={currentChannel.display_name}
|
||||
header={currentChannel.header}
|
||||
purpose={currentChannel.purpose}
|
||||
status={status}
|
||||
theme={theme}
|
||||
type={currentChannel.type}
|
||||
/>
|
||||
|
|
@ -200,14 +202,19 @@ class ChannelInfo extends PureComponent {
|
|||
theme={theme}
|
||||
/>
|
||||
<View style={style.separator}/>
|
||||
<ChannelInfoRow
|
||||
action={() => true}
|
||||
defaultMessage='Notification Preferences'
|
||||
icon='bell-o'
|
||||
textId='channel_header.notificationPreferences'
|
||||
theme={theme}
|
||||
/>
|
||||
<View style={style.separator}/>
|
||||
{
|
||||
|
||||
/**
|
||||
<ChannelInfoRow
|
||||
action={() => true}
|
||||
defaultMessage='Notification Preferences'
|
||||
icon='bell-o'
|
||||
textId='channel_header.notificationPreferences'
|
||||
theme={theme}
|
||||
/>
|
||||
<View style={style.separator}/>
|
||||
**/
|
||||
}
|
||||
<ChannelInfoRow
|
||||
action={this.props.actions.goToChannelMembers}
|
||||
defaultMessage={canManageUsers ? 'Manage Members' : 'View Members'}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import React, {PropTypes, PureComponent} from 'react';
|
|||
import {
|
||||
Image,
|
||||
Keyboard,
|
||||
StatusBar,
|
||||
TouchableWithoutFeedback,
|
||||
View
|
||||
} from 'react-native';
|
||||
|
|
@ -34,7 +35,8 @@ export default class SelectServer extends PureComponent {
|
|||
getPing: PropTypes.func.isRequired,
|
||||
resetPing: PropTypes.func.isRequired,
|
||||
handleLoginOptions: PropTypes.func.isRequired,
|
||||
handleServerUrlChanged: PropTypes.func.isRequired
|
||||
handleServerUrlChanged: PropTypes.func.isRequired,
|
||||
unrenderDrawer: PropTypes.func.isRequired
|
||||
}).isRequired
|
||||
};
|
||||
|
||||
|
|
@ -46,6 +48,10 @@ export default class SelectServer extends PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.actions.unrenderDrawer();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (!this.props.transition && nextProps.transition) {
|
||||
this.props.actions.resetPing().then(() => {
|
||||
|
|
@ -101,6 +107,7 @@ export default class SelectServer extends PureComponent {
|
|||
style={{flex: 1}}
|
||||
keyboardVerticalOffset={0}
|
||||
>
|
||||
<StatusBar barStyle='light-content'/>
|
||||
<TouchableWithoutFeedback onPress={this.blur}>
|
||||
<View style={[GlobalStyles.container, GlobalStyles.signupContainer]}>
|
||||
<Image
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import navigationSceneConnect from '../navigationSceneConnect';
|
|||
|
||||
import {getPing, resetPing} from 'mattermost-redux/actions/general';
|
||||
import {RequestStatus} from 'mattermost-redux/constants';
|
||||
import {unrenderDrawer} from 'app/actions/navigation';
|
||||
import * as SelectServerActions from 'app/actions/views/select_server';
|
||||
|
||||
import SelectServer from './select_server';
|
||||
|
|
@ -31,7 +32,8 @@ function mapDispatchToProps(dispatch) {
|
|||
actions: bindActionCreators({
|
||||
...SelectServerActions,
|
||||
getPing,
|
||||
resetPing
|
||||
resetPing,
|
||||
unrenderDrawer
|
||||
}, dispatch)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import React, {PropTypes, PureComponent} from 'react';
|
|||
import {
|
||||
Image,
|
||||
InteractionManager,
|
||||
ScrollView,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View
|
||||
|
|
@ -12,16 +13,15 @@ import {
|
|||
import Button from 'react-native-button';
|
||||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
import {GlobalStyles} from 'app/styles';
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
|
||||
import logo from 'assets/images/logo.png';
|
||||
|
||||
export default class SelectTeam extends PureComponent {
|
||||
static propTypes = {
|
||||
config: PropTypes.object.isRequired,
|
||||
teams: PropTypes.object.isRequired,
|
||||
myMembers: PropTypes.object.isRequired,
|
||||
teams: PropTypes.array.isRequired,
|
||||
subscribeToHeaderEvent: PropTypes.func.isRequired,
|
||||
unsubscribeFromHeaderEvent: PropTypes.func.isRequired,
|
||||
actions: PropTypes.shape({
|
||||
|
|
@ -70,48 +70,50 @@ export default class SelectTeam extends PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const content = [];
|
||||
const teams = Object.values(this.props.teams);
|
||||
for (const team of teams) {
|
||||
if (this.props.myMembers.hasOwnProperty(team.id)) {
|
||||
content.push(
|
||||
<Button
|
||||
key={team.id}
|
||||
onPress={() => this.onSelectTeam(team)}
|
||||
style={GlobalStyles.buttonListItemText}
|
||||
containerStyle={GlobalStyles.buttonListItem}
|
||||
>
|
||||
{team.display_name}
|
||||
<Icon
|
||||
name='keyboard-arrow-right'
|
||||
size={24}
|
||||
color='#777'
|
||||
/>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
||||
const content = this.props.teams.map((team) => {
|
||||
return (
|
||||
<Button
|
||||
key={team.id}
|
||||
onPress={() => this.onSelectTeam(team)}
|
||||
style={GlobalStyles.buttonListItemText}
|
||||
containerStyle={GlobalStyles.buttonListItem}
|
||||
>
|
||||
{team.display_name}
|
||||
<Icon
|
||||
name='keyboard-arrow-right'
|
||||
size={24}
|
||||
color='#777'
|
||||
/>
|
||||
</Button>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={GlobalStyles.container}>
|
||||
<Image
|
||||
style={GlobalStyles.logo}
|
||||
source={logo}
|
||||
/>
|
||||
<Text style={GlobalStyles.header}>
|
||||
{this.props.config.SiteName}
|
||||
</Text>
|
||||
<FormattedText
|
||||
style={GlobalStyles.subheader}
|
||||
id='web.root.signup_info'
|
||||
defaultMessage='All team communication in one place, searchable and accessible anywhere'
|
||||
/>
|
||||
<FormattedText
|
||||
style={GlobalStyles.subheader}
|
||||
id='signup_team.choose'
|
||||
defaultMessage='Your teams:'
|
||||
/>
|
||||
{content}
|
||||
<ScrollView
|
||||
style={{flex: 1}}
|
||||
contentContainerStyle={{alignItems: 'center', paddingVertical: 64}}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<Image
|
||||
style={GlobalStyles.logo}
|
||||
source={logo}
|
||||
/>
|
||||
<Text style={GlobalStyles.header}>
|
||||
{this.props.config.SiteName}
|
||||
</Text>
|
||||
<FormattedText
|
||||
style={GlobalStyles.subheader}
|
||||
id='web.root.signup_info'
|
||||
defaultMessage='All team communication in one place, searchable and accessible anywhere'
|
||||
/>
|
||||
<FormattedText
|
||||
style={GlobalStyles.subheader}
|
||||
id='signup_team.choose'
|
||||
defaultMessage='Your teams:'
|
||||
/>
|
||||
{content}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,17 +8,26 @@ import navigationSceneConnect from '../navigationSceneConnect';
|
|||
import {closeDrawers, closeModal, goBack} from 'app/actions/navigation';
|
||||
import {handleTeamChange} from 'app/actions/views/select_team';
|
||||
|
||||
import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getCurrentTeam, getTeams, getTeamMemberships} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import SelectTeam from './select_team.js';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const allTeams = Object.values(getTeams(state));
|
||||
const myMembers = getTeamMemberships(state);
|
||||
const user = getCurrentUser(state);
|
||||
const myTeams = allTeams.filter((team) => myMembers.hasOwnProperty(team.id));
|
||||
|
||||
function sortTeams(a, b) {
|
||||
return a.display_name.localeCompare(b.display_name, user.locale, {numeric: true});
|
||||
}
|
||||
|
||||
return {
|
||||
config: state.entities.general.config,
|
||||
teamsRequest: state.requests.teams.allTeams,
|
||||
teams: state.entities.teams.teams,
|
||||
currentTeam: getCurrentTeam(state),
|
||||
myMembers: state.entities.teams.myMembers
|
||||
teams: myTeams.sort(sortTeams),
|
||||
currentTeam: getCurrentTeam(state)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue