* WIP Global error handler Adding components Adding actions * Add general errors where errors are caught * Filter out non displayable errors * Initial setup to email errors * Add current user/team to error email * Fix a few lints * Ensure errors are cleared when reporting a problem * Add clear all and internationalization * Fix trailing comma issue * fix lints * Use Formatted Text component * Move error list out of channel * Add mobile prefix to i18n id for connection error * Set shouldRender to true in RightMenuDrawerItem.defaultProps * Update component name for RightMenuDrawerItem * Clean up propTypes in RightMenuDrawerItem * Clean up styles in RightMenuDrawerItem * Use selector to filter displayable errors * Clarify code for constructing wrapper style in ErrorList * Avoid indenting email body for error report * Remove extraneous params from errors actions * Rename action type for logging errors * Rename action for logging errors * Set shouldRender to true in RightMenuDrawerItem.defaultProps * Make logged errors displayable by default * Don't log error when websocket connection is closed * Hide button to dismiss all errors if ShowErrorsList isn't enabled * Display only last error in alert bar when ShowErrorsList is disabled * Add error logging where missing in actions * Always show button to report problem * Only include errors in report problem email if any have been logged * Clarify subject of report problem email * Set ShowErrorsList to false in default config.json * Remove unused component + translation for connection errors * Capture entire error object not just message * Display fallback if error.message is blank * Log errors in login actions * Fix construction of errors email body
172 lines
5.7 KiB
JavaScript
172 lines
5.7 KiB
JavaScript
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
|
// See License.txt for license information.
|
|
|
|
import React from 'react';
|
|
import {
|
|
ScrollView,
|
|
StyleSheet,
|
|
Platform,
|
|
View,
|
|
Linking
|
|
} from 'react-native';
|
|
import Icon from 'react-native-vector-icons/FontAwesome';
|
|
|
|
import FormattedText from 'app/components/formatted_text';
|
|
import {makeStyleSheetFromTheme} from 'app/utils/theme';
|
|
|
|
import RightMenuDrawerItem from './right_menu_drawer_item';
|
|
|
|
export default class RightMenuDrawer extends React.Component {
|
|
static propTypes = {
|
|
errors: React.PropTypes.array.isRequired,
|
|
currentUserId: React.PropTypes.string.isRequired,
|
|
currentTeamId: React.PropTypes.string.isRequired,
|
|
actions: React.PropTypes.shape({
|
|
goToModalAccountSettings: React.PropTypes.func.isRequired,
|
|
goToModalSelectTeam: React.PropTypes.func.isRequired,
|
|
clearErrors: React.PropTypes.func.isRequired,
|
|
logout: React.PropTypes.func.isRequired
|
|
}).isRequired,
|
|
theme: React.PropTypes.object
|
|
};
|
|
|
|
openErrorEmail = () => {
|
|
const recipient = 'feedback@mattermost.com';
|
|
const subject = 'Problem with Mattermost React Native app';
|
|
Linking.openURL(
|
|
`mailto:${recipient}?subject=${subject}&body=${this.errorEmailBody()}`
|
|
);
|
|
this.props.actions.clearErrors();
|
|
};
|
|
|
|
errorEmailBody = () => {
|
|
const {currentUserId, currentTeamId, errors} = this.props;
|
|
let contents = [
|
|
`Current User Id: ${currentUserId}`,
|
|
`Current Team Id: ${currentTeamId}`
|
|
];
|
|
if (errors.length) {
|
|
contents = contents.concat([
|
|
'',
|
|
'Errors:',
|
|
JSON.stringify(errors.map((e) => e.error))
|
|
]);
|
|
}
|
|
return contents.join('\n');
|
|
};
|
|
|
|
render() {
|
|
const Styles = getStyleSheet(this.props.theme);
|
|
|
|
return (
|
|
<ScrollView style={Styles.container}>
|
|
<Divider style={Styles.divider}/>
|
|
<RightMenuDrawerItem onPress={this.props.actions.goToModalAccountSettings}>
|
|
<Icon
|
|
style={Styles.icon}
|
|
name='cog'
|
|
/>
|
|
<FormattedText
|
|
style={Styles.itemText}
|
|
id='sidebar_right_menu.accountSettings'
|
|
defaultMessage='Account Settings'
|
|
/>
|
|
</RightMenuDrawerItem>
|
|
<Divider style={Styles.divider}/>
|
|
<RightMenuDrawerItem onPress={this.props.actions.goToModalSelectTeam}>
|
|
<Icon
|
|
style={Styles.icon}
|
|
name='exchange'
|
|
/>
|
|
<FormattedText
|
|
style={Styles.itemText}
|
|
id='sidebar_right_menu.switch_team'
|
|
defaultMessage='Team Selection'
|
|
/>
|
|
</RightMenuDrawerItem>
|
|
<Divider style={Styles.divider}/>
|
|
<RightMenuDrawerItem>
|
|
<Icon
|
|
style={Styles.icon}
|
|
name='question'
|
|
/>
|
|
<FormattedText
|
|
style={Styles.itemText}
|
|
id='sidebar_right_menu.help'
|
|
defaultMessage='Help'
|
|
/>
|
|
</RightMenuDrawerItem>
|
|
<RightMenuDrawerItem onPress={this.openErrorEmail}>
|
|
<Icon
|
|
style={Styles.icon}
|
|
name='phone'
|
|
/>
|
|
<FormattedText
|
|
style={Styles.itemText}
|
|
id='sidebar_right_menu.report'
|
|
defaultMessage='Report a Problem'
|
|
/>
|
|
</RightMenuDrawerItem>
|
|
<RightMenuDrawerItem>
|
|
<Icon
|
|
style={Styles.icon}
|
|
name='info'
|
|
/>
|
|
<FormattedText
|
|
style={Styles.itemText}
|
|
id='navbar_dropdown.about'
|
|
defaultMessage='About Mattermost'
|
|
/>
|
|
</RightMenuDrawerItem>
|
|
<Divider style={Styles.divider}/>
|
|
<RightMenuDrawerItem onPress={this.props.actions.logout}>
|
|
<Icon
|
|
style={Styles.icon}
|
|
name='sign-out'
|
|
/>
|
|
<FormattedText
|
|
style={Styles.itemText}
|
|
id='sidebar_right_menu.logout'
|
|
defaultMessage='Logout'
|
|
/>
|
|
</RightMenuDrawerItem>
|
|
</ScrollView>
|
|
);
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
});
|
|
});
|