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,