[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 = {
|
Check.propTypes = {
|
||||||
|
style: PropTypes.object,
|
||||||
theme: PropTypes.string
|
theme: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ const Button = React.memo(({
|
||||||
onPress, ...props
|
onPress, ...props
|
||||||
}) => (
|
}) => (
|
||||||
<Touch
|
<Touch
|
||||||
onPress={onPress}
|
onPress={() => onPress(props.title)}
|
||||||
style={{ backgroundColor: themes[props.theme].backgroundColor }}
|
style={{ backgroundColor: themes[props.theme].backgroundColor }}
|
||||||
enabled={!props.disabled}
|
enabled={!props.disabled}
|
||||||
theme={props.theme}
|
theme={props.theme}
|
||||||
|
@ -89,6 +89,7 @@ Content.propTypes = {
|
||||||
};
|
};
|
||||||
|
|
||||||
Button.propTypes = {
|
Button.propTypes = {
|
||||||
|
title: PropTypes.string,
|
||||||
onPress: PropTypes.func,
|
onPress: PropTypes.func,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
theme: PropTypes.string
|
theme: PropTypes.string
|
||||||
|
|
|
@ -414,6 +414,7 @@ export default {
|
||||||
Select_Server: 'Select Server',
|
Select_Server: 'Select Server',
|
||||||
Select_Users: 'Select Users',
|
Select_Users: 'Select Users',
|
||||||
Select_a_Channel: 'Select a Channel',
|
Select_a_Channel: 'Select a Channel',
|
||||||
|
Select_an_option: 'Select an option',
|
||||||
Send: 'Send',
|
Send: 'Send',
|
||||||
Send_audio_message: 'Send audio message',
|
Send_audio_message: 'Send audio message',
|
||||||
Send_crash_report: 'Send crash report',
|
Send_crash_report: 'Send crash report',
|
||||||
|
|
|
@ -377,6 +377,7 @@ export default {
|
||||||
Select_Server: 'Selecionar Servidor',
|
Select_Server: 'Selecionar Servidor',
|
||||||
Select_Users: 'Selecionar Usuários',
|
Select_Users: 'Selecionar Usuários',
|
||||||
Select_a_Channel: 'Selecione um canal',
|
Select_a_Channel: 'Selecione um canal',
|
||||||
|
Select_an_option: 'Selecione uma opção',
|
||||||
Send: 'Enviar',
|
Send: 'Enviar',
|
||||||
Send_audio_message: 'Enviar mensagem de áudio',
|
Send_audio_message: 'Enviar mensagem de áudio',
|
||||||
Send_message: 'Enviar mensagem',
|
Send_message: 'Enviar mensagem',
|
||||||
|
|
|
@ -166,6 +166,9 @@ const ChatsStack = createStackNavigator({
|
||||||
NotificationPrefView: {
|
NotificationPrefView: {
|
||||||
getScreen: () => require('./views/NotificationPreferencesView').default
|
getScreen: () => require('./views/NotificationPreferencesView').default
|
||||||
},
|
},
|
||||||
|
PickerView: {
|
||||||
|
getScreen: () => require('./views/PickerView').default
|
||||||
|
},
|
||||||
...RoomRoutes
|
...RoomRoutes
|
||||||
}, {
|
}, {
|
||||||
defaultNavigationOptions: defaultHeader,
|
defaultNavigationOptions: defaultHeader,
|
||||||
|
@ -448,6 +451,9 @@ const RoomActionsStack = createStackNavigator({
|
||||||
},
|
},
|
||||||
AttachmentView: {
|
AttachmentView: {
|
||||||
getScreen: () => require('./views/AttachmentView').default
|
getScreen: () => require('./views/AttachmentView').default
|
||||||
|
},
|
||||||
|
PickerView: {
|
||||||
|
getScreen: () => require('./views/PickerView').default
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
defaultNavigationOptions: defaultHeader,
|
defaultNavigationOptions: defaultHeader,
|
||||||
|
|
|
@ -3,9 +3,9 @@ import {
|
||||||
View, ScrollView, Switch, Text
|
View, ScrollView, Switch, Text
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import RNPickerSelect from 'react-native-picker-select';
|
|
||||||
import { SafeAreaView } from 'react-navigation';
|
import { SafeAreaView } from 'react-navigation';
|
||||||
|
|
||||||
|
import database from '../../lib/database';
|
||||||
import { SWITCH_TRACK_COLOR, themes } from '../../constants/colors';
|
import { SWITCH_TRACK_COLOR, themes } from '../../constants/colors';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import ListItem from '../../containers/ListItem';
|
import ListItem from '../../containers/ListItem';
|
||||||
|
@ -15,9 +15,9 @@ import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import sharedStyles from '../Styles';
|
import sharedStyles from '../Styles';
|
||||||
import RocketChat from '../../lib/rocketchat';
|
import RocketChat from '../../lib/rocketchat';
|
||||||
import log from '../../utils/log';
|
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
import { themedHeader } from '../../utils/navigation';
|
import { themedHeader } from '../../utils/navigation';
|
||||||
|
import protectedFunction from '../../lib/methods/helpers/protectedFunction';
|
||||||
|
|
||||||
const SectionTitle = React.memo(({ title, theme }) => (
|
const SectionTitle = React.memo(({ title, theme }) => (
|
||||||
<Text
|
<Text
|
||||||
|
@ -181,43 +181,52 @@ class NotificationPreferencesView extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onValueChangeSwitch = async(key, value) => {
|
saveNotificationSettings = async(key, value, params) => {
|
||||||
const params = {
|
const { room } = this.state;
|
||||||
[key]: value ? '1' : '0'
|
const db = database.active;
|
||||||
};
|
|
||||||
|
await db.action(async() => {
|
||||||
|
await room.update(protectedFunction((r) => {
|
||||||
|
r[key] = value;
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await RocketChat.saveNotificationSettings(this.rid, params);
|
const result = await RocketChat.saveNotificationSettings(this.rid, params);
|
||||||
} catch (e) {
|
if (result.success) {
|
||||||
log(e);
|
return;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await db.action(async() => {
|
||||||
|
await room.update(protectedFunction((r) => {
|
||||||
|
r[key] = room[key];
|
||||||
|
}));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onValueChangePicker = async(key, value) => {
|
onValueChangeSwitch = (key, value) => this.saveNotificationSettings(key, value, { [key]: value ? '1' : '0' });
|
||||||
const params = {
|
|
||||||
[key]: value.toString()
|
onValueChangePicker = (key, value) => this.saveNotificationSettings(key, value, { [key]: value.toString() });
|
||||||
};
|
|
||||||
try {
|
pickerSelection = (title, key) => {
|
||||||
await RocketChat.saveNotificationSettings(this.rid, params);
|
const { room } = this.state;
|
||||||
} catch (e) {
|
const { navigation } = this.props;
|
||||||
log(e);
|
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 { room } = this.state;
|
||||||
const { theme } = this.props;
|
const { theme } = this.props;
|
||||||
return (
|
const text = room[key] ? OPTIONS[key].find(option => option.value === room[key]) : OPTIONS[key][0];
|
||||||
<RNPickerSelect
|
return <Text style={[styles.pickerText, { color: themes[theme].actionTintColor }]}>{text?.label}</Text>;
|
||||||
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]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSwitch = (key) => {
|
renderSwitch = (key) => {
|
||||||
|
@ -283,7 +292,8 @@ class NotificationPreferencesView extends React.Component {
|
||||||
<ListItem
|
<ListItem
|
||||||
title={I18n.t('Alert')}
|
title={I18n.t('Alert')}
|
||||||
testID='notification-preference-view-alert'
|
testID='notification-preference-view-alert'
|
||||||
right={() => this.renderPicker('desktopNotifications')}
|
onPress={title => this.pickerSelection(title, 'desktopNotifications')}
|
||||||
|
right={() => this.renderPickerOption('desktopNotifications')}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
<Separator theme={theme} />
|
<Separator theme={theme} />
|
||||||
|
@ -296,7 +306,8 @@ class NotificationPreferencesView extends React.Component {
|
||||||
<ListItem
|
<ListItem
|
||||||
title={I18n.t('Alert')}
|
title={I18n.t('Alert')}
|
||||||
testID='notification-preference-view-push-notification'
|
testID='notification-preference-view-push-notification'
|
||||||
right={() => this.renderPicker('mobilePushNotifications')}
|
onPress={title => this.pickerSelection(title, 'mobilePushNotifications')}
|
||||||
|
right={() => this.renderPickerOption('mobilePushNotifications')}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
<Separator theme={theme} />
|
<Separator theme={theme} />
|
||||||
|
@ -309,21 +320,24 @@ class NotificationPreferencesView extends React.Component {
|
||||||
<ListItem
|
<ListItem
|
||||||
title={I18n.t('Audio')}
|
title={I18n.t('Audio')}
|
||||||
testID='notification-preference-view-audio'
|
testID='notification-preference-view-audio'
|
||||||
right={() => this.renderPicker('audioNotifications')}
|
onPress={title => this.pickerSelection(title, 'audioNotifications')}
|
||||||
|
right={() => this.renderPickerOption('audioNotifications')}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
<Separator theme={theme} />
|
<Separator theme={theme} />
|
||||||
<ListItem
|
<ListItem
|
||||||
title={I18n.t('Sound')}
|
title={I18n.t('Sound')}
|
||||||
testID='notification-preference-view-sound'
|
testID='notification-preference-view-sound'
|
||||||
right={() => this.renderPicker('audioNotificationValue')}
|
onPress={title => this.pickerSelection(title, 'audioNotificationValue')}
|
||||||
|
right={() => this.renderPickerOption('audioNotificationValue')}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
<Separator theme={theme} />
|
<Separator theme={theme} />
|
||||||
<ListItem
|
<ListItem
|
||||||
title={I18n.t('Notification_Duration')}
|
title={I18n.t('Notification_Duration')}
|
||||||
testID='notification-preference-view-notification-duration'
|
testID='notification-preference-view-notification-duration'
|
||||||
right={() => this.renderPicker('desktopNotificationDuration')}
|
onPress={title => this.pickerSelection(title, 'desktopNotificationDuration')}
|
||||||
|
right={() => this.renderPickerOption('desktopNotificationDuration')}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
<Separator theme={theme} />
|
<Separator theme={theme} />
|
||||||
|
@ -335,7 +349,8 @@ class NotificationPreferencesView extends React.Component {
|
||||||
<ListItem
|
<ListItem
|
||||||
title={I18n.t('Alert')}
|
title={I18n.t('Alert')}
|
||||||
testID='notification-preference-view-email-alert'
|
testID='notification-preference-view-email-alert'
|
||||||
right={() => this.renderPicker('emailNotifications')}
|
onPress={title => this.pickerSelection(title, 'emailNotifications')}
|
||||||
|
right={() => this.renderPickerOption('emailNotifications')}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
<Separator theme={theme} />
|
<Separator theme={theme} />
|
||||||
|
|
|
@ -24,9 +24,6 @@ export default StyleSheet.create({
|
||||||
paddingVertical: 10,
|
paddingVertical: 10,
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
},
|
},
|
||||||
viewContainer: {
|
|
||||||
justifyContent: 'center'
|
|
||||||
},
|
|
||||||
pickerText: {
|
pickerText: {
|
||||||
...sharedStyles.textRegular,
|
...sharedStyles.textRegular,
|
||||||
fontSize: 16
|
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