[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:
parent
78441bf345
commit
c313a63d8a
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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} />
|
||||
|
|
|
@ -24,9 +24,6 @@ export default StyleSheet.create({
|
|||
paddingVertical: 10,
|
||||
fontSize: 14
|
||||
},
|
||||
viewContainer: {
|
||||
justifyContent: 'center'
|
||||
},
|
||||
pickerText: {
|
||||
...sharedStyles.textRegular,
|
||||
fontSize: 16
|
||||
|
|
|
@ -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);
|
Loading…
Reference in New Issue