From 7068cbd043420c471f8deb56da1aa6c67ac5340d Mon Sep 17 00:00:00 2001 From: enahum Date: Wed, 29 Nov 2017 19:42:41 -0300 Subject: [PATCH] Fix Android crash for mobile notifications screen (#1233) --- app/components/radio_button/index.js | 2 + .../radio_button/radio_button_group.js | 29 ++-- .../notification_settings.js | 80 ++++----- .../notification_settings_mentions.android.js | 53 +++--- .../notification_settings_mobile.android.js | 161 +++++++++--------- 5 files changed, 164 insertions(+), 161 deletions(-) diff --git a/app/components/radio_button/index.js b/app/components/radio_button/index.js index e27256510..1723fb7f7 100644 --- a/app/components/radio_button/index.js +++ b/app/components/radio_button/index.js @@ -8,3 +8,5 @@ export { RadioButton, RadioButtonGroup }; + +export default RadioButtonGroup; diff --git a/app/components/radio_button/radio_button_group.js b/app/components/radio_button/radio_button_group.js index d2e061bc1..9fa37ef6d 100644 --- a/app/components/radio_button/radio_button_group.js +++ b/app/components/radio_button/radio_button_group.js @@ -8,29 +8,33 @@ import RadioButton from './radio_button'; export default class RadioButtonGroup extends PureComponent { static propTypes = { - children: PropTypes.node.isRequired, + options: PropTypes.array, name: PropTypes.string.isRequired, onSelect: PropTypes.func }; + static defaultProps: { + options: [] + }; + state = {}; constructor(props) { super(props); this.selected = null; - React.Children.forEach(this.props.children, (option) => { - if (option) { + if (this.props.options.length) { + this.props.options.forEach((option) => { const { value, checked - } = option.props; + } = option; if (!this.state.selected && checked) { this.selected = value; } - } - }); + }); + } this.state = {selected: this.selected}; } @@ -55,14 +59,15 @@ export default class RadioButtonGroup extends PureComponent { }; render = () => { - const options = React.Children.map(this.props.children, (option) => { - if (option) { + let options; + if (this.props.options.length) { + options = this.props.options.map((option) => { const { value, label, disabled, ...other - } = option.props; + } = option; const {name} = this.props; @@ -79,10 +84,8 @@ export default class RadioButtonGroup extends PureComponent { checked={this.state.selected && value === this.state.selected} /> ); - } - - return null; - }, this); + }); + } return ( diff --git a/app/screens/settings/notification_settings/notification_settings.js b/app/screens/settings/notification_settings/notification_settings.js index 3a87f0be1..9b2bdcf02 100644 --- a/app/screens/settings/notification_settings/notification_settings.js +++ b/app/screens/settings/notification_settings/notification_settings.js @@ -17,7 +17,7 @@ import {Preferences, RequestStatus} from 'mattermost-redux/constants'; import {getPreferencesByCategory} from 'mattermost-redux/utils/preference_utils'; import FormattedText from 'app/components/formatted_text'; -import {RadioButton, RadioButtonGroup} from 'app/components/radio_button'; +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'; @@ -135,6 +135,8 @@ class NotificationSettings extends PureComponent { notificationPreferences } }); + }).catch((e) => { + Alert.alert('There was a problem getting the device preferences', e.message); }); }; @@ -226,6 +228,42 @@ class NotificationSettings extends PureComponent { ); } + 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 ( - - {emailBatchingEnabled && - - } - {emailBatchingEnabled && - - } - - + options={emailOptions} + /> } {helpText} diff --git a/app/screens/settings/notification_settings_mentions/notification_settings_mentions.android.js b/app/screens/settings/notification_settings_mentions/notification_settings_mentions.android.js index 43384c356..f98cbf74c 100644 --- a/app/screens/settings/notification_settings_mentions/notification_settings_mentions.android.js +++ b/app/screens/settings/notification_settings_mentions/notification_settings_mentions.android.js @@ -12,7 +12,7 @@ import { import {injectIntl} from 'react-intl'; import FormattedText from 'app/components/formatted_text'; -import {RadioButton, RadioButtonGroup} from 'app/components/radio_button'; +import RadioButtonGroup from 'app/components/radio_button'; import StatusBar from 'app/components/status_bar'; import TextInputWithLocalizedPlaceholder from 'app/components/text_input_with_localized_placeholder'; import SectionItem from 'app/screens/settings/section_item'; @@ -114,6 +114,29 @@ class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase { renderReplyModal(style) { const {intl} = this.props; + const options = [{ + label: intl.formatMessage({ + id: 'mobile.account_notifications.threads_start_participate', + defaultMessage: 'Threads that I start or participate in' + }), + value: 'any', + checked: this.state.comments === 'any' + }, { + label: intl.formatMessage({ + id: 'mobile.account_notifications.threads_start', + defaultMessage: 'Threads that I start' + }), + value: 'root', + checked: this.state.comments === 'root' + }, { + label: intl.formatMessage({ + id: 'mobile.account_notifications.threads_mentions', + defaultMessage: 'Mentions in threads' + }), + value: 'never', + checked: this.state.comments === 'never' + }]; + return ( - - - - + options={options} + /> diff --git a/app/screens/settings/notification_settings_mobile/notification_settings_mobile.android.js b/app/screens/settings/notification_settings_mobile/notification_settings_mobile.android.js index d82d9d1ba..df1a2c7fd 100644 --- a/app/screens/settings/notification_settings_mobile/notification_settings_mobile.android.js +++ b/app/screens/settings/notification_settings_mobile/notification_settings_mobile.android.js @@ -12,7 +12,7 @@ import { } from 'react-native'; import FormattedText from 'app/components/formatted_text'; -import {RadioButton, RadioButtonGroup} from 'app/components/radio_button'; +import RadioButtonGroup from 'app/components/radio_button'; import NotificationPreferences from 'app/notification_preferences'; import PushNotifications from 'app/push_notifications'; import StatusBar from 'app/components/status_bar'; @@ -84,6 +84,29 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase { const {config, intl} = this.props; const pushNotificationsEnabled = config.SendPushNotifications === 'true'; + const options = [{ + label: intl.formatMessage({ + id: 'user.settings.notifications.allActivity', + defaultMessage: 'For all activity' + }), + value: 'all', + checked: this.state.push === 'all' + }, { + label: intl.formatMessage({ + id: 'user.settings.notifications.onlyMentions', + defaultMessage: 'Only for mentions and direct messages' + }), + value: 'mention', + checked: this.state.push === 'mention' + }, { + label: intl.formatMessage({ + id: 'user.settings.notifications.never', + defaultMessage: 'Never' + }), + value: 'none', + checked: this.state.push === 'none' + }]; + return ( - - - - + options={options} + /> } {!pushNotificationsEnabled && - - - - + options={options} + /> @@ -262,16 +260,32 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase { const {defaultSound, selectedUri} = this.state; const {intl, notificationPreferences} = this.props; const {defaultUri, sounds} = notificationPreferences; - const soundsArray = sounds.filter((s) => s.uri !== defaultUri).map((s, i) => { - return ( - - ); - }); + const soundsArray = [{ + label: intl.formatMessage({ + id: 'mobile.notification_settings_mobile.default_sound', + defaultMessage: 'Default ({sound})' + }, {sound: defaultSound}), + value: defaultUri, + checked: selectedUri === null + }, { + label: intl.formatMessage({ + id: 'mobile.notification_settings_mobile.no_sound', + defaultMessage: 'None' + }), + value: 'none', + checked: selectedUri === 'none' + }]; + + if (sounds && sounds.length) { + const filteredSounds = sounds.filter((s) => s.uri !== defaultUri).map((s) => { + return { + label: s.name, + value: s.uri, + checked: s.uri === selectedUri + }; + }); + soundsArray.push(...filteredSounds); + } return ( - - - {soundsArray} - + options={soundsArray} + />