diff --git a/package.json b/package.json index 600597528c2a..894e568fbf08 100644 --- a/package.json +++ b/package.json @@ -37,10 +37,10 @@ "@react-native-firebase/analytics": "^7.6.7", "@react-native-firebase/app": "^8.4.5", "@react-native-firebase/crashlytics": "^8.4.9", + "@react-native-picker/picker": "^1.9.11", "@react-navigation/drawer": "5.12.3", "@react-navigation/native": "5.9.2", "@react-navigation/stack": "5.14.2", - "@react-native-picker/picker": "^1.9.11", "babel-plugin-transform-remove-console": "^6.9.4", "dotenv": "^8.2.0", "electron-context-menu": "^2.3.0", @@ -71,8 +71,8 @@ "react-native-modal": "^11.5.6", "react-native-onyx": "git+https://github.com/Expensify/react-native-onyx.git#9c965c8bc7dd7c080cdcb79f54409e8cd8ee2d44", "react-native-pdf": "^6.2.2", - "react-native-reanimated": "1.13.2", "react-native-picker-select": "8.0.4", + "react-native-reanimated": "1.13.2", "react-native-render-html": "^6.0.0-alpha.10", "react-native-safe-area-context": "^3.1.4", "react-native-screens": "2.17.1", diff --git a/src/components/Switch.js b/src/components/Switch.js new file mode 100644 index 000000000000..bbca38e95a38 --- /dev/null +++ b/src/components/Switch.js @@ -0,0 +1,54 @@ +import React, {Component} from 'react'; +import {TouchableOpacity, Animated} from 'react-native'; +import PropTypes from 'prop-types'; +import styles from '../styles/styles'; + +const propTypes = { + isOn: PropTypes.bool.isRequired, + onToggle: PropTypes.func.isRequired, +}; + +class Switch extends Component { + constructor(props) { + super(props); + this.offPosition = 0; + this.onPosition = 20; + this.offsetX = new Animated.Value(props.isOn ? this.onPosition : this.offPosition); + + this.toggleSwitch = this.toggleSwitch.bind(this); + } + + componentDidUpdate(prevProps) { + if (prevProps.isOn !== this.props.isOn) { + this.toggleSwitch(); + } + } + + toggleSwitch() { + Animated.timing(this.offsetX, { + toValue: this.props.isOn ? this.onPosition : this.offPosition, + duration: 300, + useNativeDriver: true, + }).start(); + } + + render() { + const switchTransform = {transform: [{translateX: this.offsetX}]}; + const {isOn, onToggle} = this.props; + + return ( + onToggle(!isOn)} + > + + + ); + } +} + +Switch.propTypes = propTypes; +Switch.displayName = 'Switch'; + +export default Switch; diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index a7a3b4074ebc..01e4870d4f07 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -72,11 +72,17 @@ function resendValidateCode(email) { * @param {Boolean} subscribed */ function setExpensifyNewsStatus(subscribed) { - API.UpdateAccount({subscribed}).then((response) => { - if (response.jsonCode === 200) { - Onyx.merge(ONYXKEYS.USER, {expensifyNewsStatus: subscribed}); - } - }); + Onyx.merge(ONYXKEYS.USER, {expensifyNewsStatus: subscribed}); + + API.UpdateAccount({subscribed}) + .then((response) => { + if (response.jsonCode !== 200) { + Onyx.merge(ONYXKEYS.USER, {expensifyNewsStatus: !subscribed}); + } + }) + .catch(() => { + Onyx.merge(ONYXKEYS.USER, {expensifyNewsStatus: !subscribed}); + }); } /** diff --git a/src/pages/settings/PreferencesPage.js b/src/pages/settings/PreferencesPage.js index f3da3c89fa83..2837ecc02942 100644 --- a/src/pages/settings/PreferencesPage.js +++ b/src/pages/settings/PreferencesPage.js @@ -14,15 +14,24 @@ import Icon from '../../components/Icon'; import NameValuePair from '../../libs/actions/NameValuePair'; import CONST from '../../CONST'; import {DownArrow} from '../../components/Icon/Expensicons'; +import {setExpensifyNewsStatus} from '../../libs/actions/User'; import ScreenWrapper from '../../components/ScreenWrapper'; +import Switch from '../../components/Switch'; const propTypes = { // The chat priority mode priorityMode: PropTypes.string, + + // The details about the user that is signed in + user: PropTypes.shape({ + // Whether or not the user is subscribed to news updates + expensifyNewsStatus: PropTypes.bool, + }), }; const defaultProps = { priorityMode: CONST.PRIORITY_MODE.DEFAULT, + user: {}, }; const priorityModes = { @@ -38,16 +47,31 @@ const priorityModes = { }, }; -const PreferencesPage = ({priorityMode}) => ( + +const PreferencesPage = ({priorityMode, user}) => ( Navigation.navigate(ROUTES.SETTINGS)} - onCloseButtonPress={() => Navigation.dismissModal()} + onCloseButtonPress={Navigation.dismissModal} /> + Notifications + + + + Receive relevant feature updates and Expensify news + + + + + + Priority Mode @@ -82,4 +106,7 @@ export default withOnyx({ priorityMode: { key: ONYXKEYS.NVP_PRIORITY_MODE, }, + user: { + key: ONYXKEYS.USER, + }, })(PreferencesPage); diff --git a/src/styles/styles.js b/src/styles/styles.js index 2f2d808aca7c..7205fb337d2b 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1127,6 +1127,28 @@ const styles = { lineHeight: 20, }, + switchTrack: { + width: 50, + height: 28, + justifyContent: 'center', + borderRadius: 20, + padding: 15, + backgroundColor: colors.green, + }, + + switchInactive: { + backgroundColor: colors.gray2, + }, + + switchThumb: { + width: 22, + height: 22, + borderRadius: 11, + position: 'absolute', + left: 4, + backgroundColor: colors.white, + }, + checkboxContainer: { backgroundColor: themeColors.componentBG, borderRadius: 2, diff --git a/src/styles/utilities/flex.js b/src/styles/utilities/flex.js index 6a66532e0601..d8d115bf5c38 100644 --- a/src/styles/utilities/flex.js +++ b/src/styles/utilities/flex.js @@ -48,6 +48,10 @@ export default { alignItems: 'center', }, + alignItemsEnd: { + alignItems: 'flex-end', + }, + flexWrap: { flexWrap: 'wrap', }, diff --git a/src/styles/variables.js b/src/styles/variables.js index 6463935aa836..35408dddb2ae 100644 --- a/src/styles/variables.js +++ b/src/styles/variables.js @@ -3,6 +3,7 @@ export default { componentSizeSmall: 28, componentSizeNormal: 40, componentSizeLarge: 52, + componentBorderRadius: 8, componentBorderRadiusSmall: 4, componentBorderRadiusNormal: 8, fontSizeSmall: 11,