Fix Android crash for mobile notifications screen (#1233)
This commit is contained in:
parent
159507891c
commit
7068cbd043
5 changed files with 164 additions and 161 deletions
|
|
@ -8,3 +8,5 @@ export {
|
|||
RadioButton,
|
||||
RadioButtonGroup
|
||||
};
|
||||
|
||||
export default RadioButtonGroup;
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<View>
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Modal
|
||||
animationType='slide'
|
||||
|
|
@ -254,44 +292,8 @@ class NotificationSettings extends PureComponent {
|
|||
<RadioButtonGroup
|
||||
name='emailSettings'
|
||||
onSelect={this.setEmailNotifications}
|
||||
>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'user.settings.notifications.email.immediately',
|
||||
defaultMessage: 'Immediately'
|
||||
})}
|
||||
value={sendImmediatleyValue}
|
||||
checked={sendImmediatley}
|
||||
/>
|
||||
{emailBatchingEnabled &&
|
||||
<RadioButton
|
||||
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}
|
||||
/>
|
||||
}
|
||||
{emailBatchingEnabled &&
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'user.settings.notifications.email.everyHour',
|
||||
defaultMessage: 'Every hour'
|
||||
})}
|
||||
value={Preferences.INTERVAL_HOUR.toString()}
|
||||
checked={hourly}
|
||||
/>
|
||||
}
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'user.settings.notifications.email.never',
|
||||
defaultMessage: 'Never'
|
||||
})}
|
||||
value='false'
|
||||
checked={never}
|
||||
/>
|
||||
</RadioButtonGroup>
|
||||
options={emailOptions}
|
||||
/>
|
||||
}
|
||||
{helpText}
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Modal
|
||||
animationType='slide'
|
||||
|
|
@ -134,32 +157,8 @@ class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase {
|
|||
<RadioButtonGroup
|
||||
name='replySettings'
|
||||
onSelect={this.onReplyChanged}
|
||||
>
|
||||
<RadioButton
|
||||
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'}
|
||||
/>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'mobile.account_notifications.threads_start',
|
||||
defaultMessage: 'Threads that I start'
|
||||
})}
|
||||
value='root'
|
||||
checked={this.state.comments === 'root'}
|
||||
/>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'mobile.account_notifications.threads_mentions',
|
||||
defaultMessage: 'Mentions in threads'
|
||||
})}
|
||||
value='never'
|
||||
checked={this.state.comments === 'never'}
|
||||
/>
|
||||
</RadioButtonGroup>
|
||||
options={options}
|
||||
/>
|
||||
</View>
|
||||
<View style={style.modalFooter}>
|
||||
<View style={style.separator}/>
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Modal
|
||||
animationType='slide'
|
||||
|
|
@ -105,32 +128,8 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
|
|||
<RadioButtonGroup
|
||||
name='pushSettings'
|
||||
onSelect={this.onMobilePushChanged}
|
||||
>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'user.settings.notifications.allActivity',
|
||||
defaultMessage: 'For all activity'
|
||||
})}
|
||||
value='all'
|
||||
checked={this.state.push === 'all'}
|
||||
/>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'user.settings.notifications.onlyMentions',
|
||||
defaultMessage: 'Only for mentions and direct messages'
|
||||
})}
|
||||
value='mention'
|
||||
checked={this.state.push === 'mention'}
|
||||
/>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'user.settings.notifications.never',
|
||||
defaultMessage: 'Never'
|
||||
})}
|
||||
value='none'
|
||||
checked={this.state.push === 'none'}
|
||||
/>
|
||||
</RadioButtonGroup>
|
||||
options={options}
|
||||
/>
|
||||
}
|
||||
{!pushNotificationsEnabled &&
|
||||
<FormattedText
|
||||
|
|
@ -179,6 +178,29 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
|
|||
renderMobilePushStatusModal(style) {
|
||||
const {intl} = this.props;
|
||||
|
||||
const options = [{
|
||||
label: intl.formatMessage({
|
||||
id: 'user.settings.push_notification.online',
|
||||
defaultMessage: 'Online, away or offline'
|
||||
}),
|
||||
value: 'online',
|
||||
checked: this.state.push_status === 'online'
|
||||
}, {
|
||||
label: intl.formatMessage({
|
||||
id: 'user.settings.push_notification.away',
|
||||
defaultMessage: 'Away or offline'
|
||||
}),
|
||||
value: 'away',
|
||||
checked: this.state.push_status === 'away'
|
||||
}, {
|
||||
label: intl.formatMessage({
|
||||
id: 'user.settings.push_notification.offline',
|
||||
defaultMessage: 'Offline'
|
||||
}),
|
||||
value: 'offline',
|
||||
checked: this.state.push_status === 'offline'
|
||||
}];
|
||||
|
||||
return (
|
||||
<Modal
|
||||
animationType='slide'
|
||||
|
|
@ -199,32 +221,8 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
|
|||
<RadioButtonGroup
|
||||
name='pushStatusSettings'
|
||||
onSelect={this.onMobilePushStatusChanged}
|
||||
>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'user.settings.push_notification.online',
|
||||
defaultMessage: 'Online, away or offline'
|
||||
})}
|
||||
value='online'
|
||||
checked={this.state.push_status === 'online'}
|
||||
/>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'user.settings.push_notification.away',
|
||||
defaultMessage: 'Away or offline'
|
||||
})}
|
||||
value='away'
|
||||
checked={this.state.push_status === 'away'}
|
||||
/>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'user.settings.push_notification.offline',
|
||||
defaultMessage: 'Offline'
|
||||
})}
|
||||
value='offline'
|
||||
checked={this.state.push_status === 'offline'}
|
||||
/>
|
||||
</RadioButtonGroup>
|
||||
options={options}
|
||||
/>
|
||||
</View>
|
||||
<View style={style.modalFooter}>
|
||||
<View style={style.separator}/>
|
||||
|
|
@ -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 (
|
||||
<RadioButton
|
||||
key={`sound-${i}`}
|
||||
label={s.name}
|
||||
value={s.uri}
|
||||
checked={s.uri === selectedUri}
|
||||
/>
|
||||
);
|
||||
});
|
||||
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 (
|
||||
<Modal
|
||||
|
|
@ -294,25 +308,8 @@ class NotificationSettingsMobileAndroid extends NotificationSettingsMobileBase {
|
|||
<RadioButtonGroup
|
||||
name='soundsSettings'
|
||||
onSelect={this.onMobileSoundChanged}
|
||||
>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'mobile.notification_settings_mobile.default_sound',
|
||||
defaultMessage: 'Default ({sound})'
|
||||
}, {sound: defaultSound})}
|
||||
value={defaultUri}
|
||||
checked={selectedUri === null}
|
||||
/>
|
||||
<RadioButton
|
||||
label={intl.formatMessage({
|
||||
id: 'mobile.notification_settings_mobile.no_sound',
|
||||
defaultMessage: 'None'
|
||||
})}
|
||||
value='none'
|
||||
checked={selectedUri === 'none'}
|
||||
/>
|
||||
{soundsArray}
|
||||
</RadioButtonGroup>
|
||||
options={soundsArray}
|
||||
/>
|
||||
</ScrollView>
|
||||
</View>
|
||||
<View style={style.modalFooter}>
|
||||
|
|
|
|||
Loading…
Reference in a new issue