[MM-10215] Fix saving of email notification props when email batching is enabled (#1654)
* fix saving of email notification props when email batching is enabled * fix email notification settings for android * make screen for Android email notification * update per comment * leave as is "...email.everyXMinutes", and fix prop type error on emailInterval * add "mobile." prefix to newly introduced translation ID
This commit is contained in:
parent
665bb862a8
commit
e4a0a4b4ec
12 changed files with 909 additions and 416 deletions
|
|
@ -17,34 +17,30 @@ export default class RadioButtonGroup extends PureComponent {
|
|||
options: []
|
||||
};
|
||||
|
||||
state = {};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.selected = null;
|
||||
if (this.props.options.length) {
|
||||
this.props.options.forEach((option) => {
|
||||
const {
|
||||
value,
|
||||
checked,
|
||||
} = option;
|
||||
this.state = {
|
||||
selected: this.getSelectedValue(props.options),
|
||||
};
|
||||
}
|
||||
|
||||
if (!this.state.selected && checked) {
|
||||
this.selected = value;
|
||||
}
|
||||
});
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.options !== nextProps.options) {
|
||||
this.setState({selected: this.getSelectedValue(nextProps.options)});
|
||||
}
|
||||
}
|
||||
|
||||
getSelectedValue = (options = []) => {
|
||||
let selected;
|
||||
for (const option in options) {
|
||||
if (option.checked) {
|
||||
selected = option.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.state = {selected: this.selected};
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.state.selected;
|
||||
}
|
||||
|
||||
set value(value) {
|
||||
this.onChange(value);
|
||||
return selected;
|
||||
}
|
||||
|
||||
onChange = (value) => {
|
||||
|
|
@ -81,7 +77,7 @@ export default class RadioButtonGroup extends PureComponent {
|
|||
label={label}
|
||||
disabled={disabled}
|
||||
onCheck={this.onChange}
|
||||
checked={this.state.selected && value === this.state.selected}
|
||||
checked={option.checked}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,19 +6,14 @@ import PropTypes from 'prop-types';
|
|||
import {injectIntl, intlShape} from 'react-intl';
|
||||
import {
|
||||
Alert,
|
||||
Modal,
|
||||
Platform,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import deepEqual from 'deep-equal';
|
||||
|
||||
import {General, Preferences, RequestStatus} from 'mattermost-redux/constants';
|
||||
import {getPreferencesByCategory} from 'mattermost-redux/utils/preference_utils';
|
||||
import {General, RequestStatus} from 'mattermost-redux/constants';
|
||||
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
import RadioButtonGroup from 'app/components/radio_button';
|
||||
import StatusBar from 'app/components/status_bar';
|
||||
import NotificationPreferences from 'app/notification_preferences';
|
||||
import SettingsItem from 'app/screens/settings/settings_item';
|
||||
|
|
@ -31,10 +26,8 @@ class NotificationSettings extends PureComponent {
|
|||
actions: PropTypes.shape({
|
||||
handleUpdateUserNotifyProps: PropTypes.func.isRequired,
|
||||
}),
|
||||
config: PropTypes.object.isRequired,
|
||||
currentUser: PropTypes.object.isRequired,
|
||||
intl: intlShape.isRequired,
|
||||
myPreferences: PropTypes.object.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
theme: PropTypes.object.isRequired,
|
||||
updateMeRequest: PropTypes.object.isRequired,
|
||||
|
|
@ -42,10 +35,6 @@ class NotificationSettings extends PureComponent {
|
|||
enableAutoResponder: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
state = {
|
||||
showEmailNotificationsModal: false,
|
||||
};
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.theme !== nextProps.theme) {
|
||||
setNavigatorStyles(this.props.navigator, nextProps.theme);
|
||||
|
|
@ -94,30 +83,25 @@ class NotificationSettings extends PureComponent {
|
|||
};
|
||||
|
||||
goToNotificationSettingsEmail = () => {
|
||||
if (Platform.OS === 'ios') {
|
||||
const {currentUser, intl, navigator, theme} = this.props;
|
||||
navigator.push({
|
||||
backButtonTitle: '',
|
||||
screen: 'NotificationSettingsEmail',
|
||||
title: intl.formatMessage({
|
||||
id: 'mobile.notification_settings.email_title',
|
||||
defaultMessage: 'Email Notifications',
|
||||
}),
|
||||
animated: true,
|
||||
navigatorStyle: {
|
||||
navBarTextColor: theme.sidebarHeaderTextColor,
|
||||
navBarBackgroundColor: theme.sidebarHeaderBg,
|
||||
navBarButtonColor: theme.sidebarHeaderTextColor,
|
||||
screenBackgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
passProps: {
|
||||
currentUser,
|
||||
onBack: this.saveNotificationProps,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.setState({showEmailNotificationsModal: true});
|
||||
}
|
||||
const {currentUser, intl, navigator, theme} = this.props;
|
||||
navigator.push({
|
||||
backButtonTitle: '',
|
||||
screen: 'NotificationSettingsEmail',
|
||||
title: intl.formatMessage({
|
||||
id: 'mobile.notification_settings.email_title',
|
||||
defaultMessage: 'Email Notifications',
|
||||
}),
|
||||
animated: true,
|
||||
navigatorStyle: {
|
||||
navBarTextColor: theme.sidebarHeaderTextColor,
|
||||
navBarBackgroundColor: theme.sidebarHeaderBg,
|
||||
navBarButtonColor: theme.sidebarHeaderTextColor,
|
||||
screenBackgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
passProps: {
|
||||
currentUserId: currentUser.id,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
goToNotificationSettingsMentions = () => {
|
||||
|
|
@ -168,34 +152,6 @@ class NotificationSettings extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
setEmailNotifications = (emailSetting) => {
|
||||
this.setState({emailSetting});
|
||||
};
|
||||
|
||||
saveEmailNotifications = () => {
|
||||
const {config, currentUser} = this.props;
|
||||
const {emailSetting} = this.state;
|
||||
|
||||
this.setState({showEmailNotificationsModal: false});
|
||||
|
||||
if (emailSetting) {
|
||||
let email = emailSetting;
|
||||
let interval;
|
||||
|
||||
const emailBatchingEnabled = config.EnableEmailBatching === 'true';
|
||||
if (emailBatchingEnabled && emailSetting !== 'false') {
|
||||
interval = emailSetting;
|
||||
email = 'true';
|
||||
}
|
||||
|
||||
this.saveNotificationProps({
|
||||
...getNotificationProps(currentUser),
|
||||
email,
|
||||
interval,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
saveNotificationProps = (notifyProps) => {
|
||||
const {currentUser} = this.props;
|
||||
const {user_id: userId} = notifyProps;
|
||||
|
|
@ -204,10 +160,6 @@ class NotificationSettings extends PureComponent {
|
|||
user_id: userId,
|
||||
};
|
||||
|
||||
if (notifyProps.interval) {
|
||||
previousProps.interval = notifyProps.interval;
|
||||
}
|
||||
|
||||
if (!deepEqual(previousProps, notifyProps)) {
|
||||
this.props.actions.handleUpdateUserNotifyProps(notifyProps);
|
||||
}
|
||||
|
|
@ -247,154 +199,6 @@ class NotificationSettings extends PureComponent {
|
|||
}
|
||||
};
|
||||
|
||||
renderEmailNotificationSettings = (style) => {
|
||||
if (Platform.OS === 'ios') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {config, currentUser, intl, myPreferences} = this.props;
|
||||
const notifyProps = getNotificationProps(currentUser);
|
||||
const sendEmailNotifications = config.SendEmailNotifications === 'true';
|
||||
const emailBatchingEnabled = sendEmailNotifications && config.EnableEmailBatching === 'true';
|
||||
|
||||
const never = notifyProps.email === 'false';
|
||||
let sendImmediatley = notifyProps.email === 'true';
|
||||
let sendImmediatleyValue = 'true';
|
||||
let fifteenMinutes;
|
||||
let hourly;
|
||||
let interval;
|
||||
|
||||
if (emailBatchingEnabled) {
|
||||
const emailPreferences = getPreferencesByCategory(myPreferences, Preferences.CATEGORY_NOTIFICATIONS);
|
||||
if (emailPreferences.size) {
|
||||
interval = emailPreferences.get(Preferences.EMAIL_INTERVAL).value;
|
||||
}
|
||||
}
|
||||
|
||||
if (emailBatchingEnabled && notifyProps.email !== 'false') {
|
||||
sendImmediatley = interval === Preferences.INTERVAL_IMMEDIATE.toString();
|
||||
fifteenMinutes = interval === Preferences.INTERVAL_FIFTEEN_MINUTES.toString();
|
||||
hourly = interval === Preferences.INTERVAL_HOUR.toString();
|
||||
sendImmediatleyValue = Preferences.INTERVAL_IMMEDIATE.toString();
|
||||
}
|
||||
|
||||
let helpText;
|
||||
if (sendEmailNotifications) {
|
||||
helpText = (
|
||||
<FormattedText
|
||||
id='user.settings.notifications.emailInfo'
|
||||
defaultMessage='Email notifications are sent for mentions and direct messages when you are offline or away from {siteName} for more than 5 minutes.'
|
||||
values={{siteName: config.SiteName}}
|
||||
style={style.modalHelpText}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const emailOptions = [{
|
||||
label: intl.formatMessage({
|
||||
id: 'user.settings.notifications.email.immediately',
|
||||
defaultMessage: 'Immediately',
|
||||
}),
|
||||
value: sendImmediatleyValue,
|
||||
checked: sendImmediatley,
|
||||
}];
|
||||
|
||||
if (emailBatchingEnabled) {
|
||||
emailOptions.push({
|
||||
label: intl.formatMessage({
|
||||
id: 'user.settings.notifications.email.everyXMinutes',
|
||||
defaultMessage: 'Every {count, plural, one {minute} other {{count, number} minutes}}',
|
||||
}, {count: Preferences.INTERVAL_FIFTEEN_MINUTES / 60}),
|
||||
value: Preferences.INTERVAL_FIFTEEN_MINUTES.toString(),
|
||||
checked: fifteenMinutes,
|
||||
}, {
|
||||
label: intl.formatMessage({
|
||||
id: 'user.settings.notifications.email.everyHour',
|
||||
defaultMessage: 'Every hour',
|
||||
}),
|
||||
value: Preferences.INTERVAL_HOUR.toString(),
|
||||
checked: hourly,
|
||||
});
|
||||
}
|
||||
|
||||
emailOptions.push({
|
||||
label: intl.formatMessage({
|
||||
id: 'user.settings.notifications.email.never',
|
||||
defaultMessage: 'Never',
|
||||
}),
|
||||
value: 'false',
|
||||
checked: never,
|
||||
});
|
||||
|
||||
return (
|
||||
<Modal
|
||||
animationType='slide'
|
||||
transparent={true}
|
||||
visible={this.state.showEmailNotificationsModal}
|
||||
onRequestClose={() => this.setState({showEmailNotificationsModal: false})}
|
||||
>
|
||||
<View style={style.modalOverlay}>
|
||||
<View style={style.modal}>
|
||||
<View style={style.modalBody}>
|
||||
<View style={style.modalTitleContainer}>
|
||||
<FormattedText
|
||||
id='user.settings.notifications.email.send'
|
||||
defaultMessage='Send email notifications'
|
||||
style={style.modalTitle}
|
||||
/>
|
||||
</View>
|
||||
{!sendEmailNotifications &&
|
||||
<FormattedText
|
||||
id='user.settings.general.emailHelp2'
|
||||
defaultMessage='Email has been disabled by your System Administrator. No notification emails will be sent until it is enabled.'
|
||||
style={style.modalOptionDisabled}
|
||||
/>
|
||||
}
|
||||
{sendEmailNotifications &&
|
||||
<RadioButtonGroup
|
||||
name='emailSettings'
|
||||
onSelect={this.setEmailNotifications}
|
||||
options={emailOptions}
|
||||
/>
|
||||
}
|
||||
{helpText}
|
||||
</View>
|
||||
<View style={style.modalFooter}>
|
||||
<View style={style.divider}/>
|
||||
<View style={style.modalFooterContainer}>
|
||||
<TouchableOpacity
|
||||
style={style.modalFooterOptionContainer}
|
||||
onPress={this.saveEmailNotifications}
|
||||
>
|
||||
<FormattedText
|
||||
id='mobile.notification_settings.modal_cancel'
|
||||
defaultMessage='CANCEL'
|
||||
style={style.modalFooterOption}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
{sendEmailNotifications &&
|
||||
<View>
|
||||
<View style={{marginRight: 10}}/>
|
||||
<TouchableOpacity
|
||||
style={style.modalFooterOptionContainer}
|
||||
onPress={this.saveEmailNotifications}
|
||||
>
|
||||
<FormattedText
|
||||
id='mobile.notification_settings.modal_save'
|
||||
defaultMessage='SAVE'
|
||||
style={style.modalFooterOption}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {theme, enableAutoResponder} = this.props;
|
||||
const style = getStyleSheet(theme);
|
||||
|
|
@ -458,7 +262,6 @@ class NotificationSettings extends PureComponent {
|
|||
{autoResponder}
|
||||
<View style={style.divider}/>
|
||||
</ScrollView>
|
||||
{this.renderEmailNotificationSettings(style)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
@ -483,60 +286,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
height: 1,
|
||||
width: '100%',
|
||||
},
|
||||
modalOverlay: {
|
||||
backgroundColor: changeOpacity('#000000', 0.6),
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
},
|
||||
modal: {
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
borderRadius: 4,
|
||||
marginTop: 20,
|
||||
width: '95%',
|
||||
},
|
||||
modalBody: {
|
||||
paddingHorizontal: 24,
|
||||
},
|
||||
modalTitleContainer: {
|
||||
marginBottom: 30,
|
||||
marginTop: 20,
|
||||
},
|
||||
modalTitle: {
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 19,
|
||||
},
|
||||
modalOptionDisabled: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 17,
|
||||
},
|
||||
modalHelpText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 13,
|
||||
marginTop: 20,
|
||||
},
|
||||
modalFooter: {
|
||||
alignItems: 'flex-end',
|
||||
height: 58,
|
||||
marginTop: 40,
|
||||
width: '100%',
|
||||
},
|
||||
modalFooterContainer: {
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
paddingRight: 24,
|
||||
},
|
||||
modalFooterOptionContainer: {
|
||||
alignItems: 'center',
|
||||
height: 40,
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 10,
|
||||
paddingVertical: 5,
|
||||
},
|
||||
modalFooterOption: {
|
||||
color: theme.linkColor,
|
||||
fontSize: 14,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`NotificationSettingsMobileAndroid should match snapshot 1`] = `
|
||||
<sectionItem
|
||||
action={[Function]}
|
||||
actionType="default"
|
||||
description={
|
||||
<InjectIntl(FormattedText)
|
||||
defaultMessage="Immediately"
|
||||
id="user.settings.notifications.email.immediately"
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<InjectIntl(FormattedText)
|
||||
defaultMessage="Send email notifications"
|
||||
id="user.settings.notifications.email.send"
|
||||
/>
|
||||
}
|
||||
theme={
|
||||
Object {
|
||||
"centerChannelBg": "#aaa",
|
||||
"centerChannelColor": "#aaa",
|
||||
}
|
||||
}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`NotificationSettingsMobileAndroid should match snapshot 2`] = `
|
||||
<Component
|
||||
animationType="slide"
|
||||
hardwareAccelerated={false}
|
||||
onRequestClose={[Function]}
|
||||
transparent={true}
|
||||
visible={false}
|
||||
>
|
||||
<Component
|
||||
style={undefined}
|
||||
>
|
||||
<Component
|
||||
style={Object {}}
|
||||
>
|
||||
<Component
|
||||
style={Object {}}
|
||||
>
|
||||
<Component
|
||||
style={Object {}}
|
||||
>
|
||||
<InjectIntl(FormattedText)
|
||||
defaultMessage="Send email notifications"
|
||||
id="user.settings.notifications.email.send"
|
||||
style={Object {}}
|
||||
/>
|
||||
</Component>
|
||||
<RadioButtonGroup
|
||||
name="emailSettings"
|
||||
onSelect={[Function]}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"checked": true,
|
||||
"label": "Immediately",
|
||||
"value": "30",
|
||||
},
|
||||
Object {
|
||||
"checked": false,
|
||||
"label": "Never",
|
||||
"value": "0",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
<InjectIntl(FormattedText)
|
||||
defaultMessage="Email notifications are sent for mentions and direct messages when you are offline or away from {siteName} for more than 5 minutes."
|
||||
id="user.settings.notifications.emailInfo"
|
||||
style={Object {}}
|
||||
values={
|
||||
Object {
|
||||
"siteName": "Mattermost",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</Component>
|
||||
<Component
|
||||
style={Object {}}
|
||||
>
|
||||
<Component
|
||||
style={Object {}}
|
||||
/>
|
||||
<Component
|
||||
style={Object {}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.2}
|
||||
onPress={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<InjectIntl(FormattedText)
|
||||
defaultMessage="CANCEL"
|
||||
id="mobile.notification_settings.modal_cancel"
|
||||
style={Object {}}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<Component>
|
||||
<Component
|
||||
style={
|
||||
Object {
|
||||
"marginRight": 10,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.2}
|
||||
onPress={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
<InjectIntl(FormattedText)
|
||||
defaultMessage="SAVE"
|
||||
id="mobile.notification_settings.modal_save"
|
||||
style={Object {}}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</Component>
|
||||
</Component>
|
||||
</Component>
|
||||
</Component>
|
||||
</Component>
|
||||
</Component>
|
||||
`;
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`NotificationSettingsEmailIos should match snapshot, renderEmailSection 1`] = `
|
||||
<section
|
||||
disableFooter={false}
|
||||
footerDefaultMessage="Email notifications are sent for mentions and direct messages when you are offline or away from {siteName} for more than 5 minutes."
|
||||
footerId="user.settings.notifications.emailInfo"
|
||||
footerValues={
|
||||
Object {
|
||||
"siteName": "Mattermost",
|
||||
}
|
||||
}
|
||||
headerDefaultMessage="SEND EMAIL NOTIFICATIONS"
|
||||
headerId="mobile.notification_settings.email.send"
|
||||
theme={
|
||||
Object {
|
||||
"centerChannelBg": "#aaa",
|
||||
"centerChannelColor": "#aaa",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Component>
|
||||
<sectionItem
|
||||
action={[Function]}
|
||||
actionType="select"
|
||||
actionValue="30"
|
||||
label={
|
||||
<InjectIntl(FormattedText)
|
||||
defaultMessage="Immediately"
|
||||
id="user.settings.notifications.email.immediately"
|
||||
/>
|
||||
}
|
||||
selected={true}
|
||||
theme={
|
||||
Object {
|
||||
"centerChannelBg": "#aaa",
|
||||
"centerChannelColor": "#aaa",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<Component
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": undefined,
|
||||
"flex": 1,
|
||||
"height": 1,
|
||||
"marginLeft": 15,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<sectionItem
|
||||
action={[Function]}
|
||||
actionType="select"
|
||||
actionValue="0"
|
||||
label={
|
||||
<InjectIntl(FormattedText)
|
||||
defaultMessage="Never"
|
||||
id="user.settings.notifications.email.never"
|
||||
/>
|
||||
}
|
||||
selected={false}
|
||||
theme={
|
||||
Object {
|
||||
"centerChannelBg": "#aaa",
|
||||
"centerChannelColor": "#aaa",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</Component>
|
||||
</section>
|
||||
`;
|
||||
|
|
@ -1,19 +1,47 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
|
||||
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
||||
|
||||
import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getMyPreferences, getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {
|
||||
get as getPreference,
|
||||
getTheme,
|
||||
} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import NotificationSettingsEmail from './notification_settings_email';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const config = getConfig(state);
|
||||
const sendEmailNotifications = config.SendEmailNotifications === 'true';
|
||||
const enableEmailBatching = config.EnableEmailBatching === 'true';
|
||||
const emailInterval = getPreference(
|
||||
state,
|
||||
Preferences.CATEGORY_NOTIFICATIONS,
|
||||
Preferences.EMAIL_INTERVAL,
|
||||
Preferences.INTERVAL_NEVER
|
||||
).toString();
|
||||
|
||||
return {
|
||||
config: getConfig(state),
|
||||
myPreferences: getMyPreferences(state),
|
||||
enableEmailBatching,
|
||||
emailInterval,
|
||||
sendEmailNotifications,
|
||||
siteName: config.siteName || '',
|
||||
theme: getTheme(state),
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(NotificationSettingsEmail);
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
savePreferences,
|
||||
}, dispatch),
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(NotificationSettingsEmail);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,321 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {intlShape} from 'react-intl';
|
||||
import {
|
||||
Modal,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
import RadioButtonGroup from 'app/components/radio_button';
|
||||
import SectionItem from 'app/screens/settings/section_item';
|
||||
|
||||
import NotificationSettingsEmailBase from './notification_settings_email_base';
|
||||
|
||||
class NotificationSettingsEmailAndroid extends NotificationSettingsEmailBase {
|
||||
static contextTypes = {
|
||||
intl: intlShape,
|
||||
};
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({showEmailNotificationsModal: false});
|
||||
}
|
||||
|
||||
handleSaveEmailNotification = () => {
|
||||
this.saveEmailNotifyProps();
|
||||
this.handleClose();
|
||||
};
|
||||
|
||||
showEmailModal = () => {
|
||||
this.setState({showEmailNotificationsModal: true});
|
||||
};
|
||||
|
||||
renderEmailSection() {
|
||||
const {
|
||||
sendEmailNotifications,
|
||||
theme,
|
||||
} = this.props;
|
||||
const {interval} = this.state;
|
||||
let i18nId;
|
||||
let i18nMessage;
|
||||
if (sendEmailNotifications) {
|
||||
switch (interval) {
|
||||
case Preferences.INTERVAL_IMMEDIATE.toString():
|
||||
i18nId = 'user.settings.notifications.email.immediately';
|
||||
i18nMessage = 'Immediately';
|
||||
break;
|
||||
case Preferences.INTERVAL_HOUR.toString():
|
||||
i18nId = 'user.settings.notifications.email.everyHour';
|
||||
i18nMessage = 'Every hour';
|
||||
break;
|
||||
case Preferences.INTERVAL_FIFTEEN_MINUTES.toString():
|
||||
i18nId = 'mobile.user.settings.notifications.email.fifteenMinutes';
|
||||
i18nMessage = 'Every 15 minutes';
|
||||
break;
|
||||
case Preferences.INTERVAL_NEVER.toString():
|
||||
default:
|
||||
i18nId = 'user.settings.notifications.email.never';
|
||||
i18nMessage = 'Never';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
i18nId = 'user.settings.notifications.email.disabled';
|
||||
i18nMessage = 'Email notifications are not enabled';
|
||||
}
|
||||
|
||||
return (
|
||||
<SectionItem
|
||||
description={(
|
||||
<FormattedText
|
||||
id={i18nId}
|
||||
defaultMessage={i18nMessage}
|
||||
/>
|
||||
)}
|
||||
label={(
|
||||
<FormattedText
|
||||
id='user.settings.notifications.email.send'
|
||||
defaultMessage='Send email notifications'
|
||||
/>
|
||||
)}
|
||||
action={this.showEmailModal}
|
||||
actionType='default'
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderEmailNotificationsModal(style) {
|
||||
const {intl} = this.context;
|
||||
const {
|
||||
enableEmailBatching,
|
||||
sendEmailNotifications,
|
||||
siteName,
|
||||
} = this.props;
|
||||
const {interval} = this.state;
|
||||
|
||||
let helpText;
|
||||
if (sendEmailNotifications) {
|
||||
helpText = (
|
||||
<FormattedText
|
||||
id='user.settings.notifications.emailInfo'
|
||||
defaultMessage='Email notifications are sent for mentions and direct messages when you are offline or away from {siteName} for more than 5 minutes.'
|
||||
values={{siteName}}
|
||||
style={style.modalHelpText}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const emailOptions = [{
|
||||
label: intl.formatMessage({
|
||||
id: 'user.settings.notifications.email.immediately',
|
||||
defaultMessage: 'Immediately',
|
||||
}),
|
||||
value: Preferences.INTERVAL_IMMEDIATE.toString(),
|
||||
checked: interval === Preferences.INTERVAL_IMMEDIATE.toString(),
|
||||
}];
|
||||
|
||||
if (enableEmailBatching) {
|
||||
emailOptions.push({
|
||||
label: intl.formatMessage({
|
||||
id: 'mobile.user.settings.notifications.email.fifteenMinutes',
|
||||
defaultMessage: 'Every 15 minutes',
|
||||
}),
|
||||
value: Preferences.INTERVAL_FIFTEEN_MINUTES.toString(),
|
||||
checked: interval === Preferences.INTERVAL_FIFTEEN_MINUTES.toString(),
|
||||
}, {
|
||||
label: intl.formatMessage({
|
||||
id: 'user.settings.notifications.email.everyHour',
|
||||
defaultMessage: 'Every hour',
|
||||
}),
|
||||
value: Preferences.INTERVAL_HOUR.toString(),
|
||||
checked: interval === Preferences.INTERVAL_HOUR.toString(),
|
||||
});
|
||||
}
|
||||
|
||||
emailOptions.push({
|
||||
label: intl.formatMessage({
|
||||
id: 'user.settings.notifications.email.never',
|
||||
defaultMessage: 'Never',
|
||||
}),
|
||||
value: Preferences.INTERVAL_NEVER.toString(),
|
||||
checked: interval === Preferences.INTERVAL_NEVER.toString(),
|
||||
});
|
||||
|
||||
return (
|
||||
<Modal
|
||||
animationType='slide'
|
||||
transparent={true}
|
||||
visible={this.state.showEmailNotificationsModal}
|
||||
onRequestClose={this.handleClose}
|
||||
>
|
||||
<View style={style.modalOverlay}>
|
||||
<View style={style.modal}>
|
||||
<View style={style.modalBody}>
|
||||
<View style={style.modalTitleContainer}>
|
||||
<FormattedText
|
||||
id='user.settings.notifications.email.send'
|
||||
defaultMessage='Send email notifications'
|
||||
style={style.modalTitle}
|
||||
/>
|
||||
</View>
|
||||
{!sendEmailNotifications &&
|
||||
<FormattedText
|
||||
id='user.settings.general.emailHelp2'
|
||||
defaultMessage='Email has been disabled by your System Administrator. No notification emails will be sent until it is enabled.'
|
||||
style={style.modalOptionDisabled}
|
||||
/>
|
||||
}
|
||||
{sendEmailNotifications &&
|
||||
<RadioButtonGroup
|
||||
name='emailSettings'
|
||||
onSelect={this.setEmailNotifications}
|
||||
options={emailOptions}
|
||||
/>
|
||||
}
|
||||
{helpText}
|
||||
</View>
|
||||
<View style={style.modalFooter}>
|
||||
<View style={style.divider}/>
|
||||
<View style={style.modalFooterContainer}>
|
||||
<TouchableOpacity
|
||||
style={style.modalFooterOptionContainer}
|
||||
onPress={this.handleClose}
|
||||
>
|
||||
<FormattedText
|
||||
id='mobile.notification_settings.modal_cancel'
|
||||
defaultMessage='CANCEL'
|
||||
style={style.modalFooterOption}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
{sendEmailNotifications &&
|
||||
<View>
|
||||
<View style={{marginRight: 10}}/>
|
||||
<TouchableOpacity
|
||||
style={style.modalFooterOptionContainer}
|
||||
onPress={this.handleSaveEmailNotification}
|
||||
>
|
||||
<FormattedText
|
||||
id='mobile.notification_settings.modal_save'
|
||||
defaultMessage='SAVE'
|
||||
style={style.modalFooterOption}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {theme} = this.props;
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
return (
|
||||
<View style={style.container}>
|
||||
<ScrollView
|
||||
style={style.scrollView}
|
||||
contentContainerStyle={style.scrollViewContent}
|
||||
alwaysBounceVertical={false}
|
||||
>
|
||||
{this.renderEmailSection()}
|
||||
<View style={style.separator}/>
|
||||
{this.renderEmailNotificationsModal(style)}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
separator: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.1),
|
||||
height: 1,
|
||||
width: '100%',
|
||||
},
|
||||
divider: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.1),
|
||||
height: 1,
|
||||
width: '100%',
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.06),
|
||||
},
|
||||
scrollViewContent: {
|
||||
paddingVertical: 0,
|
||||
},
|
||||
modalOverlay: {
|
||||
backgroundColor: changeOpacity('#000000', 0.6),
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
},
|
||||
modal: {
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
borderRadius: 4,
|
||||
marginTop: 20,
|
||||
width: '95%',
|
||||
},
|
||||
modalBody: {
|
||||
paddingHorizontal: 24,
|
||||
},
|
||||
modalTitleContainer: {
|
||||
marginBottom: 30,
|
||||
marginTop: 20,
|
||||
},
|
||||
modalTitle: {
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 19,
|
||||
},
|
||||
modalOptionDisabled: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 17,
|
||||
},
|
||||
modalHelpText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
fontSize: 13,
|
||||
marginTop: 20,
|
||||
},
|
||||
modalFooter: {
|
||||
alignItems: 'flex-end',
|
||||
height: 58,
|
||||
marginTop: 40,
|
||||
width: '100%',
|
||||
},
|
||||
modalFooterContainer: {
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
paddingRight: 24,
|
||||
},
|
||||
modalFooterOptionContainer: {
|
||||
alignItems: 'center',
|
||||
height: 40,
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 10,
|
||||
paddingVertical: 5,
|
||||
},
|
||||
modalFooterOption: {
|
||||
color: theme.linkColor,
|
||||
fontSize: 14,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default NotificationSettingsEmailAndroid;
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {configure} from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
configure({adapter: new Adapter()});
|
||||
|
||||
import {shallowWithIntl} from 'test/intl-test-helper';
|
||||
|
||||
import NotificationSettingsMobileAndroid from './notification_settings_email.android.js';
|
||||
|
||||
describe('NotificationSettingsMobileAndroid', () => {
|
||||
const baseProps = {
|
||||
currentUserId: 'current_user_id',
|
||||
emailInterval: '30',
|
||||
enableEmailBatching: false,
|
||||
navigator: {setOnNavigatorEvent: () => {}}, // eslint-disable-line no-empty-function
|
||||
actions: {
|
||||
savePreferences: () => {}, // eslint-disable-line no-empty-function
|
||||
},
|
||||
sendEmailNotifications: true,
|
||||
siteName: 'Mattermost',
|
||||
theme: {
|
||||
centerChannelBg: '#aaa',
|
||||
centerChannelColor: '#aaa',
|
||||
},
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<NotificationSettingsMobileAndroid {...baseProps}/>
|
||||
);
|
||||
|
||||
const style = {
|
||||
divider: {},
|
||||
modal: {},
|
||||
modalBody: {},
|
||||
modalTitleContainer: {},
|
||||
modalTitle: {},
|
||||
modalOptionDisabled: {},
|
||||
modalHelpText: {},
|
||||
modalFooter: {},
|
||||
modalFooterContainer: {},
|
||||
modalFooterOptionContainer: {},
|
||||
modalFooterOption: {},
|
||||
};
|
||||
|
||||
expect(wrapper.instance().renderEmailSection()).toMatchSnapshot();
|
||||
expect(wrapper.instance().renderEmailNotificationsModal(style)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match state on setEmailNotifications', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<NotificationSettingsMobileAndroid {...baseProps}/>
|
||||
);
|
||||
|
||||
wrapper.setState({email: 'false', interval: '0'});
|
||||
wrapper.instance().setEmailNotifications('30');
|
||||
expect(wrapper.state({email: 'true', interval: '30'}));
|
||||
|
||||
wrapper.instance().setEmailNotifications('0');
|
||||
expect(wrapper.state({email: 'false', interval: '0'}));
|
||||
|
||||
wrapper.instance().setEmailNotifications('3600');
|
||||
expect(wrapper.state({email: 'true', interval: '3600'}));
|
||||
});
|
||||
|
||||
test('should match state on handleClose', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<NotificationSettingsMobileAndroid {...baseProps}/>
|
||||
);
|
||||
|
||||
wrapper.setState({showEmailNotificationsModal: true});
|
||||
wrapper.instance().handleClose();
|
||||
expect(wrapper.state('showEmailNotificationsModal')).toEqual(false);
|
||||
});
|
||||
|
||||
test('should saveEmailNotifyProps and handleClose on handleSaveEmailNotification', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<NotificationSettingsMobileAndroid {...baseProps}/>
|
||||
);
|
||||
|
||||
const instance = wrapper.instance();
|
||||
instance.saveEmailNotifyProps = jest.fn();
|
||||
instance.handleClose = jest.fn();
|
||||
|
||||
instance.handleSaveEmailNotification();
|
||||
expect(instance.saveEmailNotifyProps).toHaveBeenCalledTimes(1);
|
||||
expect(instance.handleClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should match state on showEmailModal', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<NotificationSettingsMobileAndroid {...baseProps}/>
|
||||
);
|
||||
|
||||
wrapper.setState({showEmailNotificationsModal: false});
|
||||
wrapper.instance().showEmailModal();
|
||||
expect(wrapper.state('showEmailNotificationsModal')).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
ScrollView,
|
||||
|
|
@ -10,120 +9,34 @@ import {
|
|||
} from 'react-native';
|
||||
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
import {getPreferencesByCategory} from 'mattermost-redux/utils/preference_utils';
|
||||
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
import StatusBar from 'app/components/status_bar';
|
||||
import {getNotificationProps} from 'app/utils/notify_props';
|
||||
import {changeOpacity, makeStyleSheetFromTheme, setNavigatorStyles} from 'app/utils/theme';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
||||
import Section from 'app/screens/settings/section';
|
||||
import SectionItem from 'app/screens/settings/section_item';
|
||||
|
||||
export default class NotificationSettingsEmail extends PureComponent {
|
||||
static propTypes = {
|
||||
config: PropTypes.object.isRequired,
|
||||
currentUser: PropTypes.object.isRequired,
|
||||
myPreferences: PropTypes.object.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
onBack: PropTypes.func.isRequired,
|
||||
theme: PropTypes.object.isRequired,
|
||||
};
|
||||
import NotificationSettingsEmailBase from './notification_settings_email_base';
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const {currentUser} = props;
|
||||
const notifyProps = getNotificationProps(currentUser);
|
||||
|
||||
props.navigator.setOnNavigatorEvent(this.onNavigatorEvent);
|
||||
this.state = this.setStateFromNotifyProps(notifyProps);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.theme !== nextProps.theme) {
|
||||
setNavigatorStyles(this.props.navigator, nextProps.theme);
|
||||
}
|
||||
}
|
||||
|
||||
onNavigatorEvent = (event) => {
|
||||
if (event.type === 'ScreenChangedEvent') {
|
||||
switch (event.id) {
|
||||
case 'willDisappear':
|
||||
this.saveUserNotifyProps();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setEmailNotifications = (value) => {
|
||||
const {config} = this.props;
|
||||
let email = value;
|
||||
let interval;
|
||||
|
||||
const emailBatchingEnabled = config.EnableEmailBatching === 'true';
|
||||
if (emailBatchingEnabled && value !== 'false') {
|
||||
interval = value;
|
||||
email = 'true';
|
||||
}
|
||||
|
||||
this.setState({
|
||||
email,
|
||||
interval,
|
||||
});
|
||||
};
|
||||
|
||||
setStateFromNotifyProps = (notifyProps) => {
|
||||
const {config, myPreferences} = this.props;
|
||||
let interval;
|
||||
if (config.SendEmailNotifications === 'true' && config.EnableEmailBatching === 'true') {
|
||||
const emailPreferences = getPreferencesByCategory(myPreferences, Preferences.CATEGORY_NOTIFICATIONS);
|
||||
if (emailPreferences.size) {
|
||||
interval = emailPreferences.get(Preferences.EMAIL_INTERVAL).value;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...notifyProps,
|
||||
interval,
|
||||
};
|
||||
};
|
||||
|
||||
saveUserNotifyProps = () => {
|
||||
this.props.onBack({
|
||||
...this.state,
|
||||
user_id: this.props.currentUser.id,
|
||||
});
|
||||
};
|
||||
|
||||
renderEmailSection = () => {
|
||||
const {config, theme} = this.props;
|
||||
class NotificationSettingsEmailIos extends NotificationSettingsEmailBase {
|
||||
renderEmailSection() {
|
||||
const {
|
||||
enableEmailBatching,
|
||||
sendEmailNotifications,
|
||||
siteName,
|
||||
theme,
|
||||
} = this.props;
|
||||
const {interval} = this.state;
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
const sendEmailNotifications = config.SendEmailNotifications === 'true';
|
||||
const emailBatchingEnabled = sendEmailNotifications && config.EnableEmailBatching === 'true';
|
||||
|
||||
let sendImmediatley = this.state.email === 'true';
|
||||
let sendImmediatleyValue = 'true';
|
||||
let fifteenMinutes;
|
||||
let hourly;
|
||||
const never = this.state.email === 'false';
|
||||
|
||||
if (emailBatchingEnabled && this.state.email !== 'false') {
|
||||
sendImmediatley = this.state.interval === Preferences.INTERVAL_IMMEDIATE.toString();
|
||||
fifteenMinutes = this.state.interval === Preferences.INTERVAL_FIFTEEN_MINUTES.toString();
|
||||
hourly = this.state.interval === Preferences.INTERVAL_HOUR.toString();
|
||||
|
||||
sendImmediatleyValue = Preferences.INTERVAL_IMMEDIATE.toString();
|
||||
}
|
||||
|
||||
return (
|
||||
<Section
|
||||
headerId='mobile.notification_settings.email.send'
|
||||
headerDefaultMessage='SEND EMAIL NOTIFICATIONS'
|
||||
footerId='user.settings.notifications.emailInfo'
|
||||
footerDefaultMessage='Email notifications are sent for mentions and direct messages when you are offline or away from {siteName} for more than 5 minutes.'
|
||||
footerValues={{siteName: config.SiteName}}
|
||||
footerValues={{siteName}}
|
||||
disableFooter={!sendEmailNotifications}
|
||||
theme={theme}
|
||||
>
|
||||
|
|
@ -138,25 +51,24 @@ export default class NotificationSettingsEmail extends PureComponent {
|
|||
)}
|
||||
action={this.setEmailNotifications}
|
||||
actionType='select'
|
||||
actionValue={sendImmediatleyValue}
|
||||
selected={sendImmediatley}
|
||||
actionValue={Preferences.INTERVAL_IMMEDIATE.toString()}
|
||||
selected={interval === Preferences.INTERVAL_IMMEDIATE.toString()}
|
||||
theme={theme}
|
||||
/>
|
||||
<View style={style.separator}/>
|
||||
{emailBatchingEnabled &&
|
||||
{enableEmailBatching &&
|
||||
<View>
|
||||
<SectionItem
|
||||
label={(
|
||||
<FormattedText
|
||||
id='user.settings.notifications.email.everyXMinutes'
|
||||
defaultMessage='Every {count, plural, one {minute} other {{count, number} minutes}}'
|
||||
values={{count: Preferences.INTERVAL_FIFTEEN_MINUTES / 60}}
|
||||
id='mobile.user.settings.notifications.email.fifteenMinutes'
|
||||
defaultMessage='Every 15 minutes'
|
||||
/>
|
||||
)}
|
||||
action={this.setEmailNotifications}
|
||||
actionType='select'
|
||||
actionValue={Preferences.INTERVAL_FIFTEEN_MINUTES.toString()}
|
||||
selected={fifteenMinutes}
|
||||
selected={interval === Preferences.INTERVAL_FIFTEEN_MINUTES.toString()}
|
||||
theme={theme}
|
||||
/>
|
||||
<View style={style.separator}/>
|
||||
|
|
@ -170,7 +82,7 @@ export default class NotificationSettingsEmail extends PureComponent {
|
|||
action={this.setEmailNotifications}
|
||||
actionType='select'
|
||||
actionValue={Preferences.INTERVAL_HOUR.toString()}
|
||||
selected={hourly}
|
||||
selected={interval === Preferences.INTERVAL_HOUR.toString()}
|
||||
theme={theme}
|
||||
/>
|
||||
<View style={style.separator}/>
|
||||
|
|
@ -185,8 +97,8 @@ export default class NotificationSettingsEmail extends PureComponent {
|
|||
)}
|
||||
action={this.setEmailNotifications}
|
||||
actionType='select'
|
||||
actionValue='false'
|
||||
selected={never}
|
||||
actionValue={Preferences.INTERVAL_NEVER.toString()}
|
||||
selected={interval === Preferences.INTERVAL_NEVER.toString()}
|
||||
theme={theme}
|
||||
/>
|
||||
</View>
|
||||
|
|
@ -200,7 +112,7 @@ export default class NotificationSettingsEmail extends PureComponent {
|
|||
}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const {theme} = this.props;
|
||||
|
|
@ -227,11 +139,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
flex: 1,
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
input: {
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 12,
|
||||
height: 40,
|
||||
},
|
||||
separator: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.1),
|
||||
flex: 1,
|
||||
|
|
@ -253,3 +160,5 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default NotificationSettingsEmailIos;
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {configure, shallow} from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
configure({adapter: new Adapter()});
|
||||
|
||||
import NotificationSettingsEmailIos from './notification_settings_email.ios.js';
|
||||
|
||||
jest.mock('app/utils/theme', () => {
|
||||
const original = require.requireActual('app/utils/theme');
|
||||
return {
|
||||
...original,
|
||||
changeOpacity: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
describe('NotificationSettingsEmailIos', () => {
|
||||
const baseProps = {
|
||||
currentUserId: 'current_user_id',
|
||||
emailInterval: '30',
|
||||
enableEmailBatching: false,
|
||||
navigator: {setOnNavigatorEvent: () => {}}, // eslint-disable-line no-empty-function
|
||||
actions: {
|
||||
savePreferences: () => {}, // eslint-disable-line no-empty-function
|
||||
},
|
||||
sendEmailNotifications: true,
|
||||
siteName: 'Mattermost',
|
||||
theme: {
|
||||
centerChannelBg: '#aaa',
|
||||
centerChannelColor: '#aaa',
|
||||
},
|
||||
};
|
||||
|
||||
test('should match snapshot, renderEmailSection', () => {
|
||||
const wrapper = shallow(
|
||||
<NotificationSettingsEmailIos {...baseProps}/>
|
||||
);
|
||||
|
||||
expect(wrapper.instance().renderEmailSection()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should call saveEmailNotifyProps on onNavigatorEvent', () => {
|
||||
const wrapper = shallow(
|
||||
<NotificationSettingsEmailIos {...baseProps}/>
|
||||
);
|
||||
|
||||
const instance = wrapper.instance();
|
||||
instance.saveEmailNotifyProps = jest.fn();
|
||||
instance.onNavigatorEvent({type: 'ScreenChangedEvent', id: 'willDisappear'});
|
||||
|
||||
expect(instance.saveEmailNotifyProps).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should macth state on setEmailNotifications', () => {
|
||||
const wrapper = shallow(
|
||||
<NotificationSettingsEmailIos {...baseProps}/>
|
||||
);
|
||||
|
||||
wrapper.setState({email: 'false', interval: '0'});
|
||||
wrapper.instance().setEmailNotifications('30');
|
||||
expect(wrapper.state({email: 'true', interval: '30'}));
|
||||
|
||||
wrapper.instance().setEmailNotifications('0');
|
||||
expect(wrapper.state({email: 'false', interval: '0'}));
|
||||
|
||||
wrapper.instance().setEmailNotifications('3600');
|
||||
expect(wrapper.state({email: 'true', interval: '3600'}));
|
||||
});
|
||||
|
||||
test('should call props.actions.savePreferences on saveUserNotifyProps', () => {
|
||||
const props = {...baseProps, actions: {savePreferences: jest.fn()}};
|
||||
const wrapper = shallow(
|
||||
<NotificationSettingsEmailIos {...props}/>
|
||||
);
|
||||
|
||||
wrapper.setState({email: 'true', interval: '3600'});
|
||||
wrapper.instance().saveEmailNotifyProps();
|
||||
expect(props.actions.savePreferences).toHaveBeenCalledTimes(1);
|
||||
expect(props.actions.savePreferences).toBeCalledWith(
|
||||
'current_user_id',
|
||||
[
|
||||
{category: 'notifications', name: 'email', user_id: 'current_user_id', value: 'true'},
|
||||
{category: 'notifications', name: 'email_interval', user_id: 'current_user_id', value: '3600'},
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
import {getEmailInterval} from 'mattermost-redux/utils/notify_props';
|
||||
|
||||
import {setNavigatorStyles} from 'app/utils/theme';
|
||||
|
||||
export default class NotificationSettingsEmailBase extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
savePreferences: PropTypes.func.isRequired,
|
||||
}),
|
||||
currentUserId: PropTypes.string.isRequired,
|
||||
emailInterval: PropTypes.string.isRequired,
|
||||
enableEmailBatching: PropTypes.bool.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
sendEmailNotifications: PropTypes.bool.isRequired,
|
||||
siteName: PropTypes.string,
|
||||
theme: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const {
|
||||
emailInterval,
|
||||
enableEmailBatching,
|
||||
navigator,
|
||||
sendEmailNotifications,
|
||||
} = props;
|
||||
|
||||
this.state = {
|
||||
interval: getEmailInterval(
|
||||
sendEmailNotifications,
|
||||
enableEmailBatching,
|
||||
parseInt(emailInterval, 10),
|
||||
).toString(),
|
||||
showEmailNotificationsModal: false,
|
||||
};
|
||||
|
||||
navigator.setOnNavigatorEvent(this.onNavigatorEvent);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.theme !== nextProps.theme) {
|
||||
setNavigatorStyles(this.props.navigator, nextProps.theme);
|
||||
}
|
||||
|
||||
if (
|
||||
this.props.sendEmailNotifications !== nextProps.sendEmailNotifications ||
|
||||
this.props.enableEmailBatching !== nextProps.enableEmailBatching ||
|
||||
this.props.emailInterval !== nextProps.emailInterval
|
||||
) {
|
||||
this.setState({
|
||||
interval: getEmailInterval(
|
||||
nextProps.sendEmailNotifications,
|
||||
nextProps.enableEmailBatching,
|
||||
parseInt(nextProps.emailInterval, 10),
|
||||
).toString(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onNavigatorEvent = (event) => {
|
||||
if (event.type === 'ScreenChangedEvent') {
|
||||
switch (event.id) {
|
||||
case 'willDisappear':
|
||||
this.saveEmailNotifyProps();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setEmailNotifications = (interval) => {
|
||||
const {sendEmailNotifications} = this.props;
|
||||
|
||||
let email = 'false';
|
||||
if (sendEmailNotifications && interval !== Preferences.INTERVAL_NEVER.toString()) {
|
||||
email = 'true';
|
||||
}
|
||||
|
||||
this.setState({
|
||||
email,
|
||||
interval,
|
||||
});
|
||||
};
|
||||
|
||||
saveEmailNotifyProps = () => {
|
||||
const {currentUserId} = this.props;
|
||||
const {email, interval} = this.state;
|
||||
const emailNotify = {category: Preferences.CATEGORY_NOTIFICATIONS, user_id: currentUserId, name: 'email', value: email};
|
||||
const emailInterval = {category: Preferences.CATEGORY_NOTIFICATIONS, user_id: currentUserId, name: Preferences.EMAIL_INTERVAL, value: interval};
|
||||
this.props.actions.savePreferences(currentUserId, [emailNotify, emailInterval]);
|
||||
};
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
|||
|
||||
import NotificationSettingsMentionsBase from './notification_settings_mention_base';
|
||||
|
||||
class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase {
|
||||
class NotificationSettingsMentionsAndroid extends NotificationSettingsMentionsBase {
|
||||
cancelMentionKeys = () => {
|
||||
this.setState({showKeywordsModal: false});
|
||||
this.keywords = this.state.mention_keys;
|
||||
|
|
@ -442,4 +442,4 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
};
|
||||
});
|
||||
|
||||
export default injectIntl(NotificationSettingsMentionsIos);
|
||||
export default injectIntl(NotificationSettingsMentionsAndroid);
|
||||
|
|
|
|||
|
|
@ -3318,6 +3318,7 @@
|
|||
"user.settings.notifications.email.disabled_long": "Email notifications have not been enabled by your System Administrator.",
|
||||
"user.settings.notifications.email.everyHour": "Every hour",
|
||||
"user.settings.notifications.email.everyXMinutes": "Every {count, plural, one {minute} other {{count, number} minutes}}",
|
||||
"mobile.user.settings.notifications.email.fifteenMinutes": "Every 15 minutes",
|
||||
"user.settings.notifications.email.immediately": "Immediately",
|
||||
"user.settings.notifications.email.never": "Never",
|
||||
"user.settings.notifications.email.send": "Send email notifications",
|
||||
|
|
|
|||
Loading…
Reference in a new issue