[FIX] Change notifications preferences (#2000)

* [FIX] Change notifications preferences

* [IMPROVEMENT] Picker View

* [I18N] Translations

* [FIX] Picker Selection

* [FIX] List border

* [FIX] Prevent crash

* [FIX] Not-Pref tablet

* [FIX] Use same style of LanguageView

* [IMPROVEMENT] Send listItem title

Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Djorkaeff Alexandre 2020-04-06 18:40:18 -03:00 committed by GitHub
parent 78441bf345
commit c313a63d8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 160 additions and 42 deletions

View File

@ -13,9 +13,10 @@ const styles = StyleSheet.create({
}
});
const Check = React.memo(({ theme }) => <CustomIcon style={styles.icon} color={themes[theme].tintColor} size={22} name='check' />);
const Check = React.memo(({ theme, style }) => <CustomIcon style={[styles.icon, style]} color={themes[theme].tintColor} size={22} name='check' />);
Check.propTypes = {
style: PropTypes.object,
theme: PropTypes.string
};

View File

@ -52,7 +52,7 @@ const Button = React.memo(({
onPress, ...props
}) => (
<Touch
onPress={onPress}
onPress={() => onPress(props.title)}
style={{ backgroundColor: themes[props.theme].backgroundColor }}
enabled={!props.disabled}
theme={props.theme}
@ -89,6 +89,7 @@ Content.propTypes = {
};
Button.propTypes = {
title: PropTypes.string,
onPress: PropTypes.func,
disabled: PropTypes.bool,
theme: PropTypes.string

View File

@ -414,6 +414,7 @@ export default {
Select_Server: 'Select Server',
Select_Users: 'Select Users',
Select_a_Channel: 'Select a Channel',
Select_an_option: 'Select an option',
Send: 'Send',
Send_audio_message: 'Send audio message',
Send_crash_report: 'Send crash report',

View File

@ -377,6 +377,7 @@ export default {
Select_Server: 'Selecionar Servidor',
Select_Users: 'Selecionar Usuários',
Select_a_Channel: 'Selecione um canal',
Select_an_option: 'Selecione uma opção',
Send: 'Enviar',
Send_audio_message: 'Enviar mensagem de áudio',
Send_message: 'Enviar mensagem',

View File

@ -166,6 +166,9 @@ const ChatsStack = createStackNavigator({
NotificationPrefView: {
getScreen: () => require('./views/NotificationPreferencesView').default
},
PickerView: {
getScreen: () => require('./views/PickerView').default
},
...RoomRoutes
}, {
defaultNavigationOptions: defaultHeader,
@ -448,6 +451,9 @@ const RoomActionsStack = createStackNavigator({
},
AttachmentView: {
getScreen: () => require('./views/AttachmentView').default
},
PickerView: {
getScreen: () => require('./views/PickerView').default
}
}, {
defaultNavigationOptions: defaultHeader,

View File

@ -3,9 +3,9 @@ import {
View, ScrollView, Switch, Text
} from 'react-native';
import PropTypes from 'prop-types';
import RNPickerSelect from 'react-native-picker-select';
import { SafeAreaView } from 'react-navigation';
import database from '../../lib/database';
import { SWITCH_TRACK_COLOR, themes } from '../../constants/colors';
import StatusBar from '../../containers/StatusBar';
import ListItem from '../../containers/ListItem';
@ -15,9 +15,9 @@ import scrollPersistTaps from '../../utils/scrollPersistTaps';
import styles from './styles';
import sharedStyles from '../Styles';
import RocketChat from '../../lib/rocketchat';
import log from '../../utils/log';
import { withTheme } from '../../theme';
import { themedHeader } from '../../utils/navigation';
import protectedFunction from '../../lib/methods/helpers/protectedFunction';
const SectionTitle = React.memo(({ title, theme }) => (
<Text
@ -181,43 +181,52 @@ class NotificationPreferencesView extends React.Component {
}
}
onValueChangeSwitch = async(key, value) => {
const params = {
[key]: value ? '1' : '0'
};
saveNotificationSettings = async(key, value, params) => {
const { room } = this.state;
const db = database.active;
await db.action(async() => {
await room.update(protectedFunction((r) => {
r[key] = value;
}));
});
try {
await RocketChat.saveNotificationSettings(this.rid, params);
} catch (e) {
log(e);
const result = await RocketChat.saveNotificationSettings(this.rid, params);
if (result.success) {
return;
}
} catch {
// do nothing
}
await db.action(async() => {
await room.update(protectedFunction((r) => {
r[key] = room[key];
}));
});
}
onValueChangePicker = async(key, value) => {
const params = {
[key]: value.toString()
};
try {
await RocketChat.saveNotificationSettings(this.rid, params);
} catch (e) {
log(e);
}
onValueChangeSwitch = (key, value) => this.saveNotificationSettings(key, value, { [key]: value ? '1' : '0' });
onValueChangePicker = (key, value) => this.saveNotificationSettings(key, value, { [key]: value.toString() });
pickerSelection = (title, key) => {
const { room } = this.state;
const { navigation } = this.props;
navigation.navigate('PickerView', {
title,
data: OPTIONS[key],
value: room[key],
onChangeValue: value => this.onValueChangePicker(key, value)
});
}
renderPicker = (key) => {
renderPickerOption = (key) => {
const { room } = this.state;
const { theme } = this.props;
return (
<RNPickerSelect
testID={key}
style={{ viewContainer: styles.viewContainer }}
value={room[key]}
textInputProps={{ style: { ...styles.pickerText, color: themes[theme].actionTintColor } }}
useNativeAndroidPickerStyle={false}
placeholder={{}}
onValueChange={value => this.onValueChangePicker(key, value)}
items={OPTIONS[key]}
/>
);
const text = room[key] ? OPTIONS[key].find(option => option.value === room[key]) : OPTIONS[key][0];
return <Text style={[styles.pickerText, { color: themes[theme].actionTintColor }]}>{text?.label}</Text>;
}
renderSwitch = (key) => {
@ -283,7 +292,8 @@ class NotificationPreferencesView extends React.Component {
<ListItem
title={I18n.t('Alert')}
testID='notification-preference-view-alert'
right={() => this.renderPicker('desktopNotifications')}
onPress={title => this.pickerSelection(title, 'desktopNotifications')}
right={() => this.renderPickerOption('desktopNotifications')}
theme={theme}
/>
<Separator theme={theme} />
@ -296,7 +306,8 @@ class NotificationPreferencesView extends React.Component {
<ListItem
title={I18n.t('Alert')}
testID='notification-preference-view-push-notification'
right={() => this.renderPicker('mobilePushNotifications')}
onPress={title => this.pickerSelection(title, 'mobilePushNotifications')}
right={() => this.renderPickerOption('mobilePushNotifications')}
theme={theme}
/>
<Separator theme={theme} />
@ -309,21 +320,24 @@ class NotificationPreferencesView extends React.Component {
<ListItem
title={I18n.t('Audio')}
testID='notification-preference-view-audio'
right={() => this.renderPicker('audioNotifications')}
onPress={title => this.pickerSelection(title, 'audioNotifications')}
right={() => this.renderPickerOption('audioNotifications')}
theme={theme}
/>
<Separator theme={theme} />
<ListItem
title={I18n.t('Sound')}
testID='notification-preference-view-sound'
right={() => this.renderPicker('audioNotificationValue')}
onPress={title => this.pickerSelection(title, 'audioNotificationValue')}
right={() => this.renderPickerOption('audioNotificationValue')}
theme={theme}
/>
<Separator theme={theme} />
<ListItem
title={I18n.t('Notification_Duration')}
testID='notification-preference-view-notification-duration'
right={() => this.renderPicker('desktopNotificationDuration')}
onPress={title => this.pickerSelection(title, 'desktopNotificationDuration')}
right={() => this.renderPickerOption('desktopNotificationDuration')}
theme={theme}
/>
<Separator theme={theme} />
@ -335,7 +349,8 @@ class NotificationPreferencesView extends React.Component {
<ListItem
title={I18n.t('Alert')}
testID='notification-preference-view-email-alert'
right={() => this.renderPicker('emailNotifications')}
onPress={title => this.pickerSelection(title, 'emailNotifications')}
right={() => this.renderPickerOption('emailNotifications')}
theme={theme}
/>
<Separator theme={theme} />

View File

@ -24,9 +24,6 @@ export default StyleSheet.create({
paddingVertical: 10,
fontSize: 14
},
viewContainer: {
justifyContent: 'center'
},
pickerText: {
...sharedStyles.textRegular,
fontSize: 16

96
app/views/PickerView.js Normal file
View File

@ -0,0 +1,96 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FlatList, StyleSheet } from 'react-native';
import I18n from '../i18n';
import { themedHeader } from '../utils/navigation';
import { withTheme } from '../theme';
import { themes } from '../constants/colors';
import sharedStyles from './Styles';
import ListItem from '../containers/ListItem';
import Check from '../containers/Check';
import Separator from '../containers/Separator';
const styles = StyleSheet.create({
check: {
marginHorizontal: 0
}
});
const Item = React.memo(({
item,
selected,
onItemPress,
theme
}) => (
<ListItem
title={item.label}
right={selected && (() => <Check theme={theme} style={styles.check} />)}
onPress={onItemPress}
theme={theme}
/>
));
Item.propTypes = {
item: PropTypes.object,
selected: PropTypes.bool,
onItemPress: PropTypes.func,
theme: PropTypes.string
};
class PickerView extends React.PureComponent {
static navigationOptions = ({ navigation, screenProps }) => ({
title: navigation.getParam('title', I18n.t('Select_an_option')),
...themedHeader(screenProps.theme)
})
static propTypes = {
navigation: PropTypes.object,
theme: PropTypes.string
}
constructor(props) {
super(props);
const data = props.navigation.getParam('data', []);
const value = props.navigation.getParam('value');
this.state = { data, value };
}
onChangeValue = (value) => {
const { navigation } = this.props;
const onChange = navigation.getParam('onChangeValue', () => {});
onChange(value);
navigation.goBack();
}
render() {
const { data, value } = this.state;
const { theme } = this.props;
return (
<FlatList
data={data}
keyExtractor={item => item.value}
renderItem={({ item }) => (
<Item
item={item}
theme={theme}
selected={(value || data[0]?.value) === item.value}
onItemPress={() => this.onChangeValue(item.value)}
/>
)}
ItemSeparatorComponent={() => <Separator theme={theme} />}
contentContainerStyle={[
sharedStyles.listContentContainer,
{
backgroundColor: themes[theme].auxiliaryBackground,
borderColor: themes[theme].separatorColor
}
]}
style={{ backgroundColor: themes[theme].auxiliaryBackground }}
/>
);
}
}
export default withTheme(PickerView);