diff --git a/app/containers/Check.js b/app/containers/Check.js index e3f4f514..e9a6b73b 100644 --- a/app/containers/Check.js +++ b/app/containers/Check.js @@ -13,9 +13,10 @@ const styles = StyleSheet.create({ } }); -const Check = React.memo(({ theme }) => ); +const Check = React.memo(({ theme, style }) => ); Check.propTypes = { + style: PropTypes.object, theme: PropTypes.string }; diff --git a/app/containers/ListItem.js b/app/containers/ListItem.js index faccf4c0..6b7498dd 100644 --- a/app/containers/ListItem.js +++ b/app/containers/ListItem.js @@ -52,7 +52,7 @@ const Button = React.memo(({ onPress, ...props }) => ( 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 diff --git a/app/i18n/locales/en.js b/app/i18n/locales/en.js index c4b92596..6b485ea7 100644 --- a/app/i18n/locales/en.js +++ b/app/i18n/locales/en.js @@ -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', diff --git a/app/i18n/locales/pt-BR.js b/app/i18n/locales/pt-BR.js index 78210f2d..5cd3fb3e 100644 --- a/app/i18n/locales/pt-BR.js +++ b/app/i18n/locales/pt-BR.js @@ -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', diff --git a/app/index.js b/app/index.js index 9a10476b..cbc09945 100644 --- a/app/index.js +++ b/app/index.js @@ -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, diff --git a/app/views/NotificationPreferencesView/index.js b/app/views/NotificationPreferencesView/index.js index b6f8790e..52acad33 100644 --- a/app/views/NotificationPreferencesView/index.js +++ b/app/views/NotificationPreferencesView/index.js @@ -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 }) => ( { - 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 ( - this.onValueChangePicker(key, value)} - items={OPTIONS[key]} - /> - ); + const text = room[key] ? OPTIONS[key].find(option => option.value === room[key]) : OPTIONS[key][0]; + return {text?.label}; } renderSwitch = (key) => { @@ -283,7 +292,8 @@ class NotificationPreferencesView extends React.Component { this.renderPicker('desktopNotifications')} + onPress={title => this.pickerSelection(title, 'desktopNotifications')} + right={() => this.renderPickerOption('desktopNotifications')} theme={theme} /> @@ -296,7 +306,8 @@ class NotificationPreferencesView extends React.Component { this.renderPicker('mobilePushNotifications')} + onPress={title => this.pickerSelection(title, 'mobilePushNotifications')} + right={() => this.renderPickerOption('mobilePushNotifications')} theme={theme} /> @@ -309,21 +320,24 @@ class NotificationPreferencesView extends React.Component { this.renderPicker('audioNotifications')} + onPress={title => this.pickerSelection(title, 'audioNotifications')} + right={() => this.renderPickerOption('audioNotifications')} theme={theme} /> this.renderPicker('audioNotificationValue')} + onPress={title => this.pickerSelection(title, 'audioNotificationValue')} + right={() => this.renderPickerOption('audioNotificationValue')} theme={theme} /> this.renderPicker('desktopNotificationDuration')} + onPress={title => this.pickerSelection(title, 'desktopNotificationDuration')} + right={() => this.renderPickerOption('desktopNotificationDuration')} theme={theme} /> @@ -335,7 +349,8 @@ class NotificationPreferencesView extends React.Component { this.renderPicker('emailNotifications')} + onPress={title => this.pickerSelection(title, 'emailNotifications')} + right={() => this.renderPickerOption('emailNotifications')} theme={theme} /> diff --git a/app/views/NotificationPreferencesView/styles.js b/app/views/NotificationPreferencesView/styles.js index 61b39cb6..9b4c9e0e 100644 --- a/app/views/NotificationPreferencesView/styles.js +++ b/app/views/NotificationPreferencesView/styles.js @@ -24,9 +24,6 @@ export default StyleSheet.create({ paddingVertical: 10, fontSize: 14 }, - viewContainer: { - justifyContent: 'center' - }, pickerText: { ...sharedStyles.textRegular, fontSize: 16 diff --git a/app/views/PickerView.js b/app/views/PickerView.js new file mode 100644 index 00000000..5a8c73f2 --- /dev/null +++ b/app/views/PickerView.js @@ -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 +}) => ( + )} + 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 ( + item.value} + renderItem={({ item }) => ( + this.onChangeValue(item.value)} + /> + )} + ItemSeparatorComponent={() => } + contentContainerStyle={[ + sharedStyles.listContentContainer, + { + backgroundColor: themes[theme].auxiliaryBackground, + borderColor: themes[theme].separatorColor + } + ]} + style={{ backgroundColor: themes[theme].auxiliaryBackground }} + /> + ); + } +} + +export default withTheme(PickerView);