mattermost-mobile/app/scenes/right_menu_drawer/right_menu_drawer.js
Chris Duarte e17eb6c237 PLT-5709 Global error handler (#187)
* 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
2017-03-12 14:42:02 -03:00

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
}
});
});