diff --git a/.github/ISSUE_TEMPLATE/Performance.md b/.github/ISSUE_TEMPLATE/Performance.md
index df1881aaf5d2..49871a616bc3 100644
--- a/.github/ISSUE_TEMPLATE/Performance.md
+++ b/.github/ISSUE_TEMPLATE/Performance.md
@@ -2,7 +2,7 @@
 name: Report a performance issue
 about: Use to report an issue or propose a solution related to app performance
 title: "[Performance] "
-labels: Engineering
+labels: Engineering, Daily
 ---
 
 If you haven’t already, check out our [contributing guidelines](https://github.com/Expensify/ReactNativeChat/blob/main/CONTRIBUTING.md) for onboarding and email contributors@expensify.com to request to join our Slack channel!
diff --git a/.github/ISSUE_TEMPLATE/Standard.md b/.github/ISSUE_TEMPLATE/Standard.md
index f0c8561d2a8a..514d25f8b29f 100644
--- a/.github/ISSUE_TEMPLATE/Standard.md
+++ b/.github/ISSUE_TEMPLATE/Standard.md
@@ -1,7 +1,7 @@
 ---
 name: Standard issue template
 about: A standard template to follow when creating a new issue in this repository
-labels: AutoAssignerTriage
+labels: AutoAssignerTriage, Daily
 ---
 
 If you haven’t already, check out our [contributing guidelines](https://github.com/Expensify/ReactNativeChat/blob/main/CONTRIBUTING.md) for onboarding and email contributors@expensify.com to request to join our Slack channel!
diff --git a/.github/workflows/deployBlocker.yml b/.github/workflows/deployBlocker.yml
index fcbcdf9c5aa6..cce29a3112c1 100644
--- a/.github/workflows/deployBlocker.yml
+++ b/.github/workflows/deployBlocker.yml
@@ -24,7 +24,7 @@ jobs:
         run: |
           echo "DEPLOY_BLOCKER_URL=${{ github.event.issue.html_url }}" >> $GITHUB_ENV
           echo "DEPLOY_BLOCKER_NUMBER=${{ github.event.issue.number }}" >> $GITHUB_ENV
-          echo "DEPLOY_BLOCKER_TITLE=${{ github.event.issue.title }}" >> $GITHUB_ENV
+          echo "DEPLOY_BLOCKER_TITLE=$(sed -e "s/'/'\\\\''/g; s/\`/\\\\\`/g; 1s/^/'/; \$s/\$/'/" <<< ${{ github.event.issue.title }})" >> $GITHUB_ENV
 
       - name: Get URL, title, & number of new deploy blocker (pull request)
         if: ${{ github.event_name == 'pull_request' }}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 947cfba1851d..c55a3f68ca0c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -34,7 +34,7 @@ This is the most common scenario for contributors. The Expensify team posts new
 
 #### Proposing a job that Expensify hasn’t posted
 
-In this scenario, it’s possible that you found a bug or enhancement that we haven’t posted to the [Upwork job list](https://www.upwork.com/ab/jobs/search/?q=Expensify%20React%20Native&sort=recency&user_location_match=2) or [Github repository](https://github.com/Expensify/Expensify.cash/issues?q=is%3Aissue). This is an opportunity to propose a job, and (optionally) a solution. If it's a valid job proposal, we will compensate you for the solution and give an additional bonus of $150 for proactively proposing the job. In this case, please take the following steps:
+In this scenario, it’s possible that you found a bug or enhancement that we haven’t posted to the [Upwork job list](https://www.upwork.com/ab/jobs/search/?q=Expensify%20React%20Native&sort=recency&user_location_match=2) or [Github repository](https://github.com/Expensify/Expensify.cash/issues?q=is%3Aissue). This is an opportunity to propose a job, and (optionally) a solution. If it's a valid job proposal, we will compensate you for the solution and give an additional bonus of $250 for proactively proposing the job. In this case, please take the following steps:
 
     1. Check to ensure an issue does not already exist in the New Expensify Issue list or Upwork job list. Please use your best judgement to search for similar titles and issue descriptions.
     2. If your bug or enhancement matches an existing issue, please feel free to comment on that GitHub issue with your findings if you think it’ll help solve a problem.
diff --git a/README.md b/README.md
index 104687db9a5e..c3ee08137fc0 100644
--- a/README.md
+++ b/README.md
@@ -204,7 +204,7 @@ This application is built with the following principles.
     1. UI inputs push data to the server (React component -> Action -> XHR to server).
     1. Go to 1
 1. **Offline first**
-    - All data that is brought into the app and is necessary to display the app when offline should be stored on disk in persistent storage (eg. localStorage on browser platforms). [AsyncStorage](https://react-native-community.github.io/async-storage/) is a cross-platform abstraction layer that is used to access persistent storage.
+    - All data that is brought into the app and is necessary to display the app when offline should be stored on disk in persistent storage (eg. localStorage on browser platforms). [AsyncStorage](https://reactnative.dev/docs/asyncstorage) is a cross-platform abstraction layer that is used to access persistent storage.
     - All data that is displayed, comes from persistent storage.
 1. **UI Binds to data on disk**
     - Onyx is a Pub/Sub library to connect the application to the data stored on disk.
diff --git a/__mocks__/@react-native-firebase/perf.js b/__mocks__/@react-native-firebase/perf.js
new file mode 100644
index 000000000000..2d1ec238274a
--- /dev/null
+++ b/__mocks__/@react-native-firebase/perf.js
@@ -0,0 +1 @@
+export default () => {};
diff --git a/android/app/build.gradle b/android/app/build.gradle
index a3a6cd83df46..004a45bedeee 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -150,8 +150,8 @@ android {
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
         multiDexEnabled rootProject.ext.multiDexEnabled
-        versionCode 1001008002
-        versionName "1.0.80-2"
+        versionCode 1001008003
+        versionName "1.0.80-3"
     }
     splits {
         abi {
diff --git a/android/build.gradle b/android/build.gradle
index 66a9c1a64a72..0f9aece0cfa0 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -28,8 +28,6 @@ buildscript {
 
 allprojects {
     repositories {
-        maven { url "https://dl.bintray.com/onfido/maven" }
-
         mavenLocal()
         maven {
             // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
diff --git a/ios/ExpensifyCash.xcodeproj/project.pbxproj b/ios/ExpensifyCash.xcodeproj/project.pbxproj
index eb03211ebd49..18e0eafb0d1f 100644
--- a/ios/ExpensifyCash.xcodeproj/project.pbxproj
+++ b/ios/ExpensifyCash.xcodeproj/project.pbxproj
@@ -527,12 +527,14 @@
 			);
 			inputPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh",
+				"${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/iphoneos/hermes.framework",
 				"${PODS_XCFRAMEWORKS_BUILD_DIR}/Onfido/Onfido.framework/Onfido",
 				"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL",
 				"${PODS_XCFRAMEWORKS_BUILD_DIR}/LinkKit/LinkKit.framework/LinkKit",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Onfido.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LinkKit.framework",
@@ -712,12 +714,14 @@
 			);
 			inputPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh",
+				"${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/iphoneos/hermes.framework",
 				"${PODS_XCFRAMEWORKS_BUILD_DIR}/Onfido/Onfido.framework/Onfido",
 				"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL",
 				"${PODS_XCFRAMEWORKS_BUILD_DIR}/LinkKit/LinkKit.framework/LinkKit",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Onfido.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LinkKit.framework",
@@ -926,6 +930,7 @@
 				COPY_PHASE_STRIP = NO;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
+				"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 i386";
 				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_DYNAMIC_NO_PIC = NO;
 				GCC_NO_COMMON_BLOCKS = YES;
@@ -986,6 +991,7 @@
 				COPY_PHASE_STRIP = YES;
 				ENABLE_NS_ASSERTIONS = NO;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 i386";
 				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
diff --git a/ios/ExpensifyCash/Info.plist b/ios/ExpensifyCash/Info.plist
index c69435b11314..8fa71fe6b76f 100644
--- a/ios/ExpensifyCash/Info.plist
+++ b/ios/ExpensifyCash/Info.plist
@@ -30,7 +30,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>1.0.80.2</string>
+	<string>1.0.80.3</string>
 	<key>ITSAppUsesNonExemptEncryption</key>
 	<false/>
 	<key>LSApplicationQueriesSchemes</key>
diff --git a/ios/ExpensifyCashTests/Info.plist b/ios/ExpensifyCashTests/Info.plist
index ced27dd4ac02..978608834649 100644
--- a/ios/ExpensifyCashTests/Info.plist
+++ b/ios/ExpensifyCashTests/Info.plist
@@ -19,6 +19,6 @@
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>
-	<string>1.0.80.2</string>
+	<string>1.0.80.3</string>
 </dict>
 </plist>
diff --git a/ios/Podfile b/ios/Podfile
index 78bd8b4ce645..f0fff9d30d96 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -14,7 +14,10 @@ target 'ExpensifyCash' do
   pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse"
 
   config = use_native_modules!
-  use_react_native!(:path => config["reactNativePath"])
+  use_react_native!(
+    :path => config["reactNativePath"],
+    :hermes_enabled => true
+  )
 
   target 'ExpensifyCashTests' do
     inherit! :complete
@@ -24,10 +27,11 @@ target 'ExpensifyCash' do
   # Enables Flipper.
   #
   # Note that if you have use_frameworks! enabled, Flipper will not work and
-  # you should disable these next few lines.
-  use_flipper!('Flipper' => '0.75.1', 'Flipper-Folly' => '2.5.3', 'Flipper-RSocket' => '1.3.1')
+  # you should disable the next line.
+  use_flipper!()
+
   post_install do |installer|
-    flipper_post_install(installer)
+    react_native_post_install(installer)
 
     installer.pods_project.build_configurations.each do |config|
       config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 3f4e4773ee98..3be3a461ff59 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -177,6 +177,7 @@ PODS:
     - GoogleUtilities/Logger
   - GoogleUtilities/UserDefaults (7.5.0):
     - GoogleUtilities/Logger
+  - hermes-engine (0.7.2)
   - libevent (2.1.12)
   - nanopb (2.30908.0):
     - nanopb/decode (= 2.30908.0)
@@ -194,7 +195,7 @@ PODS:
     - RNPermissions
   - Permission-LocationWhenInUse (3.0.1):
     - RNPermissions
-  - Plaid (2.1.2)
+  - Plaid (2.1.3)
   - PromisesObjC (2.0.0)
   - Protobuf (3.17.0)
   - RCT-Folly (2020.01.13.00):
@@ -206,6 +207,11 @@ PODS:
     - boost-for-react-native
     - DoubleConversion
     - glog
+  - RCT-Folly/Futures (2020.01.13.00):
+    - boost-for-react-native
+    - DoubleConversion
+    - glog
+    - libevent
   - RCTRequired (0.64.1)
   - RCTTypeSafety (0.64.1):
     - FBLazyVector (= 0.64.1)
@@ -263,6 +269,16 @@ PODS:
     - React-jsinspector (= 0.64.1)
     - React-perflogger (= 0.64.1)
     - Yoga
+  - React-Core/Hermes (0.64.1):
+    - glog
+    - hermes-engine
+    - RCT-Folly (= 2020.01.13.00)
+    - RCT-Folly/Futures
+    - React-cxxreact (= 0.64.1)
+    - React-jsi (= 0.64.1)
+    - React-jsiexecutor (= 0.64.1)
+    - React-perflogger (= 0.64.1)
+    - Yoga
   - React-Core/RCTActionSheetHeaders (0.64.1):
     - glog
     - RCT-Folly (= 2020.01.13.00)
@@ -573,26 +589,28 @@ DEPENDENCIES:
   - EXHaptics (from `../node_modules/expo-haptics/ios`)
   - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
   - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
-  - Flipper (= 0.75.1)
+  - Flipper (~> 0.75.1)
   - Flipper-DoubleConversion (= 1.1.7)
-  - Flipper-Folly (= 2.5.3)
+  - Flipper-Folly (~> 2.5.3)
   - Flipper-Glog (= 0.3.6)
   - Flipper-PeerTalk (~> 0.0.4)
-  - Flipper-RSocket (= 1.3.1)
-  - FlipperKit (= 0.75.1)
-  - FlipperKit/Core (= 0.75.1)
-  - FlipperKit/CppBridge (= 0.75.1)
-  - FlipperKit/FBCxxFollyDynamicConvert (= 0.75.1)
-  - FlipperKit/FBDefines (= 0.75.1)
-  - FlipperKit/FKPortForwarding (= 0.75.1)
-  - FlipperKit/FlipperKitHighlightOverlay (= 0.75.1)
-  - FlipperKit/FlipperKitLayoutPlugin (= 0.75.1)
-  - FlipperKit/FlipperKitLayoutTextSearchable (= 0.75.1)
-  - FlipperKit/FlipperKitNetworkPlugin (= 0.75.1)
-  - FlipperKit/FlipperKitReactPlugin (= 0.75.1)
-  - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.75.1)
-  - FlipperKit/SKIOSNetworkPlugin (= 0.75.1)
+  - Flipper-RSocket (~> 1.3)
+  - FlipperKit (~> 0.75.1)
+  - FlipperKit/Core (~> 0.75.1)
+  - FlipperKit/CppBridge (~> 0.75.1)
+  - FlipperKit/FBCxxFollyDynamicConvert (~> 0.75.1)
+  - FlipperKit/FBDefines (~> 0.75.1)
+  - FlipperKit/FKPortForwarding (~> 0.75.1)
+  - FlipperKit/FlipperKitHighlightOverlay (~> 0.75.1)
+  - FlipperKit/FlipperKitLayoutPlugin (~> 0.75.1)
+  - FlipperKit/FlipperKitLayoutTextSearchable (~> 0.75.1)
+  - FlipperKit/FlipperKitNetworkPlugin (~> 0.75.1)
+  - FlipperKit/FlipperKitReactPlugin (~> 0.75.1)
+  - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.75.1)
+  - FlipperKit/SKIOSNetworkPlugin (~> 0.75.1)
   - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
+  - hermes-engine (~> 0.7.2)
+  - libevent (~> 2.1.12)
   - "onfido-react-native-sdk (from `../node_modules/@onfido/react-native-sdk`)"
   - Permission-LocationAccuracy (from `../node_modules/react-native-permissions/ios/LocationAccuracy`)
   - Permission-LocationAlways (from `../node_modules/react-native-permissions/ios/LocationAlways`)
@@ -605,6 +623,7 @@ DEPENDENCIES:
   - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
   - React-Core (from `../node_modules/react-native/`)
   - React-Core/DevSupport (from `../node_modules/react-native/`)
+  - React-Core/Hermes (from `../node_modules/react-native/`)
   - React-Core/RCTWebSocket (from `../node_modules/react-native/`)
   - React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
   - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
@@ -687,6 +706,7 @@ SPEC REPOS:
     - GoogleAppMeasurement
     - GoogleDataTransport
     - GoogleUtilities
+    - hermes-engine
     - libevent
     - nanopb
     - Onfido
@@ -868,6 +888,7 @@ SPEC CHECKSUMS:
   GoogleAppMeasurement: 6b6a08fd9c71f4dbc89e0e812acca81d797aa342
   GoogleDataTransport: 85fd18ff3019bb85d3f2c551d04c481dedf71fc9
   GoogleUtilities: eea970f4a389963963bffe8d8fabe43540678b9c
+  hermes-engine: 7d97ba46a1e29bacf3e3c61ecb2804a5ddd02d4f
   libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
   nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
   Onfido: 116a268e4cb8b767c15285e8071c2e8304673cdf
@@ -876,7 +897,7 @@ SPEC CHECKSUMS:
   Permission-LocationAccuracy: e8adff9ede1b23b43b7054a4500113d515fc87a8
   Permission-LocationAlways: 7f7f373d086af7a81b2f4f20d65d29266ca2043b
   Permission-LocationWhenInUse: 3ae82a9feb5da4e94e386dba17c7dd3531af9feb
-  Plaid: c02276ccc630a726a9ed790bf923d29839ff4017
+  Plaid: f55c6acdc249245c6778a4045757eb4e839cca61
   PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58
   Protobuf: 7327d4444215b5f18e560a97f879ff5503c4581c
   RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c
@@ -943,6 +964,6 @@ SPEC CHECKSUMS:
   Yoga: a7de31c64fe738607e7a3803e3f591a4b1df7393
   YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
 
-PODFILE CHECKSUM: 2b0558e25f01204512de38c2f656a63b5d86d19c
+PODFILE CHECKSUM: 2092930e33e7aa4d68cdf783d6174465bd3ce380
 
 COCOAPODS: 1.10.1
diff --git a/package-lock.json b/package-lock.json
index b955b2077ef8..fda49353ba70 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "expensify.cash",
-  "version": "1.0.80-2",
+  "version": "1.0.80-3",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/package.json b/package.json
index 868ff2d6e21b..b525b4fd9693 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "expensify.cash",
-  "version": "1.0.80-2",
+  "version": "1.0.80-3",
   "author": "Expensify, Inc.",
   "homepage": "https://new.expensify.com",
   "description": "Expensify.cash is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
diff --git a/src/CONST.js b/src/CONST.js
index 1b0a49e36d18..303f4f04611b 100755
--- a/src/CONST.js
+++ b/src/CONST.js
@@ -84,6 +84,7 @@ const CONST = {
         PAY_WITH_EXPENSIFY: 'payWithExpensify',
         FREE_PLAN: 'freePlan',
         DEFAULT_ROOMS: 'defaultRooms',
+        INTERNATIONALIZATION: 'internationalization',
     },
     BUTTON_STATES: {
         DEFAULT: 'default',
@@ -193,6 +194,7 @@ const CONST = {
         HOMEPAGE_INITIAL_RENDER: 'homepage_initial_render',
         HOMEPAGE_REPORTS_LOADED: 'homepage_reports_loaded',
         SWITCH_REPORT: 'switch_report',
+        SIDEBAR_LOADED: 'sidebar_loaded',
         COLD: 'cold',
         REPORT_ACTION_ITEM_LAYOUT_DEBOUNCE_TIME: 1500,
     },
diff --git a/src/Expensify.js b/src/Expensify.js
index d933be7ccc1d..53cef50574e6 100644
--- a/src/Expensify.js
+++ b/src/Expensify.js
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
 import React, {PureComponent} from 'react';
 import {View, AppState} from 'react-native';
 import Onyx, {withOnyx} from 'react-native-onyx';
+import _ from 'underscore';
 
 import BootSplash from './libs/BootSplash';
 import listenToStorageEvents from './libs/listenToStorageEvents';
@@ -21,6 +22,7 @@ import {growlRef} from './libs/Growl';
 import Navigation from './libs/Navigation/Navigation';
 import ROUTES from './ROUTES';
 import StartupTimer from './libs/StartupTimer';
+import {setRedirectToWorkspaceNewAfterSignIn} from './libs/actions/Session';
 
 // Initialize the store when the app loads for the first time
 Onyx.init({
@@ -35,6 +37,7 @@ Onyx.init({
         [ONYXKEYS.IOU]: {
             loading: false, error: false, creatingIOUTransaction: false, isRetrievingCurrency: false,
         },
+        [ONYXKEYS.IS_SIDEBAR_LOADED]: false,
     },
     registerStorageEventListener: (onStorageEvent) => {
         listenToStorageEvents(onStorageEvent);
@@ -69,6 +72,12 @@ const propTypes = {
 
     /** Whether the initial data needed to render the app is ready */
     initialReportDataLoaded: PropTypes.bool,
+
+    /** Tells us if the sidebar has rendered */
+    isSidebarLoaded: PropTypes.bool,
+
+    /** List of betas */
+    betas: PropTypes.arrayOf(PropTypes.string),
 };
 
 const defaultProps = {
@@ -79,6 +88,8 @@ const defaultProps = {
     },
     updateAvailable: false,
     initialReportDataLoaded: false,
+    isSidebarLoaded: false,
+    betas: [],
 };
 
 class Expensify extends PureComponent {
@@ -129,12 +140,16 @@ class Expensify extends PureComponent {
         const previousAuthToken = lodashGet(prevProps, 'session.authToken', null);
         if (this.getAuthToken() && !previousAuthToken) {
             BootSplash.show({fade: true});
-            if (lodashGet(this.props, 'session.redirectToWorkspaceNewAfterSignIn', false)) {
-                Navigation.navigate(ROUTES.WORKSPACE_NEW);
-            }
         }
 
-        if (this.getAuthToken() && this.props.initialReportDataLoaded) {
+        if (this.getAuthToken()
+            && !_.isEmpty(this.props.betas)
+            && lodashGet(this.props, 'session.redirectToWorkspaceNewAfterSignIn', false)) {
+            setRedirectToWorkspaceNewAfterSignIn(false);
+            Navigation.navigate(ROUTES.WORKSPACE_NEW);
+        }
+
+        if (this.getAuthToken() && this.props.initialReportDataLoaded && this.props.isSidebarLoaded) {
             BootSplash.getVisibilityStatus()
                 .then((value) => {
                     if (value !== 'visible') {
@@ -188,6 +203,9 @@ export default withOnyx({
     session: {
         key: ONYXKEYS.SESSION,
     },
+    betas: {
+        key: ONYXKEYS.BETAS,
+    },
     updateAvailable: {
         key: ONYXKEYS.UPDATE_AVAILABLE,
         initWithStoredValues: false,
@@ -195,4 +213,7 @@ export default withOnyx({
     initialReportDataLoaded: {
         key: ONYXKEYS.INITIAL_REPORT_DATA_LOADED,
     },
+    isSidebarLoaded: {
+        key: ONYXKEYS.IS_SIDEBAR_LOADED,
+    },
 })(Expensify);
diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js
index ded87710b8e1..71b269290712 100755
--- a/src/ONYXKEYS.js
+++ b/src/ONYXKEYS.js
@@ -16,6 +16,9 @@ export default {
     // Boolean flag set whenever we are waiting for the reconnection callbacks to finish.
     IS_LOADING_AFTER_RECONNECT: 'isLoadingAfterReconnect',
 
+    // Boolean flag set whenever the sidebar has loaded
+    IS_SIDEBAR_LOADED: 'isSidebarLoaded',
+
     NETWORK_REQUEST_QUEUE: 'networkRequestQueue',
 
     // What the active route is for our navigator. Global route that determines what views to display.
diff --git a/src/components/CommunicationsLink.js b/src/components/CommunicationsLink.js
index c60ced905fc8..bbaa924ebc08 100644
--- a/src/components/CommunicationsLink.js
+++ b/src/components/CommunicationsLink.js
@@ -44,16 +44,15 @@ const CommunicationsLink = props => (
                 >
                     {props.children}
                 </Pressable>
-            )
-            : props.children}
-        {!props.isSmallScreenWidth
-            && (
+            ) : (
                 <View style={[
-                    styles.pAbsolute,
+                    styles.flexRow,
                     styles.alignItemsCenter,
-                    styles.justifyContentCenter,
-                    styles.communicationsLinkIcon]}
+                    styles.w100,
+                    styles.communicationsLinkHeight,
+                ]}
                 >
+                    {props.children}
                     <ContextMenuItem
                         icon={ClipboardIcon}
                         text={props.translate('contextMenuItem.copyToClipboard')}
diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js
index 8b46974f39ad..7b121d6c366c 100755
--- a/src/components/IOUConfirmationList.js
+++ b/src/components/IOUConfirmationList.js
@@ -275,6 +275,7 @@ class IOUConfirmationList extends Component {
                             onChangeText={this.props.onUpdateComment}
                             placeholder={this.props.translate('common.optional')}
                             placeholderTextColor={themeColors.placeholderText}
+                            autoFocus
                         />
                     </View>
                 </ScrollView>
diff --git a/src/components/LocalePicker.js b/src/components/LocalePicker.js
new file mode 100644
index 000000000000..88a25971d7a3
--- /dev/null
+++ b/src/components/LocalePicker.js
@@ -0,0 +1,88 @@
+import React from 'react';
+import {withOnyx} from 'react-native-onyx';
+import PropTypes from 'prop-types';
+import styles from '../styles/styles';
+import Picker from './Picker';
+import Text from './Text';
+import compose from '../libs/compose';
+import {setLocale} from '../libs/actions/App';
+import withLocalize, {withLocalizePropTypes} from './withLocalize';
+import ONYXKEYS from '../ONYXKEYS';
+import CONST from '../CONST';
+import Permissions from '../libs/Permissions';
+import {translate} from '../libs/translate';
+
+const propTypes = {
+    /** Indicates which locale the user currently has selected */
+    preferredLocale: PropTypes.string,
+
+    /** Indicates size of a picker component and whether to render the label or not */
+    size: PropTypes.oneOf(['normal', 'small']),
+
+    /** Beta features list */
+    betas: PropTypes.arrayOf(PropTypes.string),
+
+    ...withLocalizePropTypes,
+};
+
+const defaultProps = {
+    preferredLocale: CONST.DEFAULT_LOCALE,
+    size: 'normal',
+    betas: [],
+};
+
+const localesToLanguages = {
+    default: {
+        value: 'en',
+        label: translate('en', 'preferencesPage.languages.english'),
+    },
+    es: {
+        value: 'es',
+        label: translate('es', 'preferencesPage.languages.spanish'),
+    },
+};
+
+const LocalePicker = ({
+    // eslint-disable-next-line no-shadow
+    preferredLocale, translate, betas, size,
+}) => {
+    if (!Permissions.canUseInternationalization(betas)) {
+        return null;
+    }
+
+    return (
+        <>
+            {size === 'normal' && (
+            <Text style={[styles.formLabel]} numberOfLines={1}>
+                {translate('preferencesPage.language')}
+            </Text>
+            )}
+            <Picker
+                onChange={(locale) => {
+                    if (locale !== preferredLocale) {
+                        setLocale(locale);
+                    }
+                }}
+                items={Object.values(localesToLanguages)}
+                size={size}
+                value={preferredLocale}
+            />
+        </>
+    );
+};
+
+LocalePicker.defaultProps = defaultProps;
+LocalePicker.propTypes = propTypes;
+LocalePicker.displayName = 'LocalePicker';
+
+export default compose(
+    withLocalize,
+    withOnyx({
+        preferredLocale: {
+            key: ONYXKEYS.PREFERRED_LOCALE,
+        },
+        betas: {
+            key: ONYXKEYS.BETAS,
+        },
+    }),
+)(LocalePicker);
diff --git a/src/components/OptionsList.js b/src/components/OptionsList.js
index dbb6e968da42..cfb25b7e5e19 100644
--- a/src/components/OptionsList.js
+++ b/src/components/OptionsList.js
@@ -78,6 +78,9 @@ const propTypes = {
 
     /** Whether to disable the interactivity of the list's option row(s) */
     disableRowInteractivity: PropTypes.bool,
+
+    /** Callback to execute when the SectionList lays out */
+    onLayout: PropTypes.func,
 };
 
 const defaultProps = {
@@ -99,6 +102,7 @@ const defaultProps = {
     showTitleTooltip: false,
     optionMode: undefined,
     disableRowInteractivity: false,
+    onLayout: undefined,
 };
 
 class OptionsList extends Component {
@@ -109,6 +113,8 @@ class OptionsList extends Component {
         this.renderSectionHeader = this.renderSectionHeader.bind(this);
         this.extractKey = this.extractKey.bind(this);
         this.onScrollToIndexFailed = this.onScrollToIndexFailed.bind(this);
+        this.viewabilityConfig = {viewAreaCoveragePercentThreshold: 95};
+        this.didLayout = false;
     }
 
     shouldComponentUpdate(nextProps) {
@@ -228,6 +234,18 @@ class OptionsList extends Component {
                     renderItem={this.renderItem}
                     renderSectionHeader={this.renderSectionHeader}
                     extraData={this.props.focusedIndex}
+                    initialNumToRender={5}
+                    maxToRenderPerBatch={5}
+                    windowSize={5}
+                    viewabilityConfig={this.viewabilityConfig}
+                    onViewableItemsChanged={() => {
+                        if (this.didLayout) {
+                            return;
+                        }
+
+                        this.didLayout = true;
+                        this.props.onLayout();
+                    }}
                 />
             </View>
         );
diff --git a/src/components/Picker/PickerPropTypes.js b/src/components/Picker/PickerPropTypes.js
index 633966a2bef4..3a6077b5886c 100644
--- a/src/components/Picker/PickerPropTypes.js
+++ b/src/components/Picker/PickerPropTypes.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import Icon from '../Icon';
+import styles from '../../styles/styles';
 import {DownArrow} from '../Icon/Expensicons';
 
 const propTypes = {
@@ -36,13 +37,32 @@ const propTypes = {
 
     /** An icon to display with the picker */
     icon: PropTypes.func,
+
+    /** Size of a picker component */
+    size: PropTypes.oneOf(['normal', 'small']),
 };
 const defaultProps = {
     useDisabledStyles: false,
     disabled: false,
     placeholder: {},
     value: null,
-    icon: () => <Icon src={DownArrow} />,
+    icon: size => (
+        <>
+            {size === 'small'
+                ? (
+                    <Icon
+                        width={styles.pickerSmall.icon.width}
+                        height={styles.pickerSmall.icon.height}
+                        src={DownArrow}
+                    />
+                )
+                : (
+                    <Icon
+                        src={DownArrow}
+                    />
+                )}
+        </>
+    ),
 };
 
 export {
diff --git a/src/components/Picker/index.js b/src/components/Picker/index.js
index 427d38184ef3..b963c81601b8 100644
--- a/src/components/Picker/index.js
+++ b/src/components/Picker/index.js
@@ -13,19 +13,29 @@ const Picker = ({
     value,
     icon,
     disabled,
-}) => (
-    <RNPickerSelect
-        onValueChange={onChange}
-        items={items}
-        style={useDisabledStyles ? pickerDisabledStyles : styles.picker}
-        useNativeAndroidPickerStyle={false}
-        placeholder={placeholder}
-        value={value}
-        Icon={icon}
-        disabled={disabled}
-        fixAndroidTouchableBug
-    />
-);
+    size,
+}) => {
+    let pickerStyles;
+    if (size === 'small') {
+        pickerStyles = styles.pickerSmall;
+    } else {
+        pickerStyles = useDisabledStyles ? pickerDisabledStyles : styles.picker;
+    }
+
+    return (
+        <RNPickerSelect
+            onValueChange={onChange}
+            items={items}
+            style={pickerStyles}
+            useNativeAndroidPickerStyle={false}
+            placeholder={placeholder}
+            value={value}
+            Icon={() => icon(size)}
+            disabled={disabled}
+            fixAndroidTouchableBug
+        />
+    );
+};
 
 Picker.propTypes = pickerPropTypes.propTypes;
 Picker.defaultProps = pickerPropTypes.defaultProps;
diff --git a/src/components/PressableWithSecondaryInteraction/index.js b/src/components/PressableWithSecondaryInteraction/index.js
index cc9645d98180..bf6c981f4d9a 100644
--- a/src/components/PressableWithSecondaryInteraction/index.js
+++ b/src/components/PressableWithSecondaryInteraction/index.js
@@ -30,7 +30,9 @@ class PressableWithSecondaryInteraction extends Component {
      */
     executeSecondaryInteractionOnContextMenu(e) {
         const selection = window.getSelection().toString();
-        e.preventDefault();
+        if (this.props.preventDefaultContentMenu) {
+            e.preventDefault();
+        }
         this.props.onSecondaryInteraction(e, selection);
     }
 
diff --git a/src/components/PressableWithSecondaryInteraction/pressableWithSecondaryInteractionPropTypes.js b/src/components/PressableWithSecondaryInteraction/pressableWithSecondaryInteractionPropTypes.js
index 372eabd424cd..beb257922b0e 100644
--- a/src/components/PressableWithSecondaryInteraction/pressableWithSecondaryInteractionPropTypes.js
+++ b/src/components/PressableWithSecondaryInteraction/pressableWithSecondaryInteractionPropTypes.js
@@ -15,12 +15,16 @@ const propTypes = {
 
     /** The ref to the search input (may be null on small screen widths) */
     forwardedRef: PropTypes.func,
+
+    /** Prevent the default ContextMenu on web/Desktop */
+    preventDefaultContentMenu: PropTypes.bool,
 };
 
 const defaultProps = {
     forwardedRef: () => {},
     onPressIn: () => {},
     onPressOut: () => {},
+    preventDefaultContentMenu: true,
 };
 
 export {propTypes, defaultProps};
diff --git a/src/components/ScreenWrapper.js b/src/components/ScreenWrapper.js
index 094b8b597fdd..f3ac8a258d06 100644
--- a/src/components/ScreenWrapper.js
+++ b/src/components/ScreenWrapper.js
@@ -8,6 +8,7 @@ import styles, {getSafeAreaPadding} from '../styles/styles';
 import HeaderGap from './HeaderGap';
 import KeyboardShortcut from '../libs/KeyboardShortcut';
 import onScreenTransitionEnd from '../libs/onScreenTransitionEnd';
+import Navigation from '../libs/Navigation/Navigation';
 
 const propTypes = {
     /** Array of additional styles to add */
@@ -32,9 +33,6 @@ const propTypes = {
     navigation: PropTypes.shape({
         // Method to attach listener to Navigation state.
         addListener: PropTypes.func.isRequired,
-
-        // Returns to the previous navigation state e.g. if this is inside a Modal we will dismiss it
-        goBack: PropTypes.func,
     }),
 };
 
@@ -45,7 +43,6 @@ const defaultProps = {
     onTransitionEnd: () => {},
     navigation: {
         addListener: () => {},
-        goBack: () => {},
     },
 };
 
@@ -59,7 +56,7 @@ class ScreenWrapper extends React.Component {
 
     componentDidMount() {
         this.unsubscribeEscapeKey = KeyboardShortcut.subscribe('Escape', () => {
-            this.props.navigation.goBack();
+            Navigation.dismissModal();
         }, [], true);
 
         this.unsubscribeTransitionEnd = onScreenTransitionEnd(this.props.navigation, () => {
diff --git a/src/components/TextInputAutoWidth.js b/src/components/TextInputAutoWidth.js
index 18a04bb9e335..9dbc83537cd6 100644
--- a/src/components/TextInputAutoWidth.js
+++ b/src/components/TextInputAutoWidth.js
@@ -42,15 +42,13 @@ class TextInputAutoWidth extends React.Component {
     render() {
         const propsWithoutStyles = _.omit(this.props, ['inputStyle', 'textStyle']);
         return (
-            <>
-                <View>
-                    <TextInputFocusable
-                        style={[this.props.inputStyle, getAutoGrowTextInputStyle(this.state.textInputWidth)]}
-                        ref={this.props.forwardedRef}
-                        /* eslint-disable-next-line react/jsx-props-no-spreading */
-                        {...propsWithoutStyles}
-                    />
-                </View>
+            <View>
+                <TextInputFocusable
+                    style={[this.props.inputStyle, getAutoGrowTextInputStyle(this.state.textInputWidth)]}
+                    ref={this.props.forwardedRef}
+                    /* eslint-disable-next-line react/jsx-props-no-spreading */
+                    {...propsWithoutStyles}
+                />
                 {/*
                 Text input component doesn't support auto grow by default.
                 We're using a hidden text input to achieve that.
@@ -63,7 +61,7 @@ class TextInputAutoWidth extends React.Component {
                 >
                     {this.props.value || this.props.placeholder}
                 </Text>
-            </>
+            </View>
         );
     }
 }
diff --git a/src/components/TextInputFocusable/index.js b/src/components/TextInputFocusable/index.js
index 5ace8e0e8d9a..44f386ef3d64 100755
--- a/src/components/TextInputFocusable/index.js
+++ b/src/components/TextInputFocusable/index.js
@@ -118,6 +118,7 @@ class TextInputFocusable extends React.Component {
         this.dragNDropListener = this.dragNDropListener.bind(this);
         this.handlePaste = this.handlePaste.bind(this);
         this.handlePastedHTML = this.handlePastedHTML.bind(this);
+        this.handleWheel = this.handleWheel.bind(this);
     }
 
     componentDidMount() {
@@ -141,6 +142,7 @@ class TextInputFocusable extends React.Component {
             document.addEventListener('dragleave', this.dragNDropListener);
             document.addEventListener('drop', this.dragNDropListener);
             this.textInput.addEventListener('paste', this.handlePaste);
+            this.textInput.addEventListener('wheel', this.handleWheel);
         }
     }
 
@@ -168,6 +170,7 @@ class TextInputFocusable extends React.Component {
             document.removeEventListener('dragleave', this.dragNDropListener);
             document.removeEventListener('drop', this.dragNDropListener);
             this.textInput.removeEventListener('paste', this.handlePaste);
+            this.textInput.removeEventListener('wheel', this.handleWheel);
         }
     }
 
@@ -304,6 +307,18 @@ class TextInputFocusable extends React.Component {
         }
     }
 
+    /**
+     * Manually scrolls the text input, then prevents the event from being passed up to the parent.
+     * @param {Object} event native Event
+     */
+    handleWheel(event) {
+        if (event.target === document.activeElement) {
+            this.textInput.scrollTop += event.deltaY;
+            event.preventDefault();
+            event.stopPropagation();
+        }
+    }
+
     /**
      * Check the current scrollHeight of the textarea (minus any padding) and
      * divide by line height to get the total number of rows for the textarea.
diff --git a/src/components/withLocalize.js b/src/components/withLocalize.js
index 78eca06f6077..435a2df71629 100755
--- a/src/components/withLocalize.js
+++ b/src/components/withLocalize.js
@@ -2,7 +2,6 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import {withOnyx} from 'react-native-onyx';
 import getComponentDisplayName from '../libs/getComponentDisplayName';
-import compose from '../libs/compose';
 import ONYXKEYS from '../ONYXKEYS';
 import {translate} from '../libs/translate';
 import DateUtils from '../libs/DateUtils';
@@ -30,59 +29,123 @@ const withLocalizePropTypes = {
     fromLocalPhone: PropTypes.func.isRequired,
 };
 
-function withLocalizeHOC(WrappedComponent) {
-    const WithLocalize = (props) => {
-        const translations = {
-            translate: (phrase, variables) => translate(props.preferredLocale, phrase, variables),
-            numberFormat: (number, options) => numberFormat(props.preferredLocale, number, options),
-            timestampToRelative: timestamp => DateUtils.timestampToRelative(props.preferredLocale, timestamp),
-            timestampToDateTime: (timestamp, includeTimezone) => DateUtils.timestampToDateTime(
-                props.preferredLocale,
-                timestamp,
-                includeTimezone,
-            ),
-            toLocalPhone: number => toLocalPhone(props.preferredLocale, number),
-            fromLocalPhone: number => fromLocalPhone(props.preferredLocale, number),
-        };
-        return (
-            <WrappedComponent
-                // eslint-disable-next-line react/jsx-props-no-spreading
-                {...props}
-                ref={props.forwardedRef}
-                translate={translations.translate}
-                numberFormat={translations.numberFormat}
-                timestampToRelative={translations.timestampToRelative}
-                timestampToDateTime={translations.timestampToDateTime}
-                toLocalPhone={translations.toLocalPhone}
-                fromLocalPhone={translations.fromLocalPhone}
-            />
-        );
-    };
-    WithLocalize.displayName = `WithLocalize(${getComponentDisplayName(WrappedComponent)})`;
-    WithLocalize.propTypes = {
+export default (WrappedComponent) => {
+    const propTypes = {
+        /** The user's preferred locale e.g. 'en', 'es-ES' */
         preferredLocale: PropTypes.string,
+
+        /** Passed ref from whatever component is wrapped in the HOC */
         forwardedRef: PropTypes.oneOfType([
             PropTypes.func,
             PropTypes.shape({current: PropTypes.instanceOf(React.Component)}),
         ]),
     };
-    WithLocalize.defaultProps = {
+
+    const defaultProps = {
         preferredLocale: CONST.DEFAULT_LOCALE,
         forwardedRef: undefined,
     };
-    return React.forwardRef((props, ref) => (
+
+    class WithLocalize extends React.Component {
+        constructor(props) {
+            super(props);
+
+            this.translate = this.translate.bind(this);
+            this.numberFormat = this.numberFormat.bind(this);
+            this.timestampToRelative = this.timestampToRelative.bind(this);
+            this.timestampToDateTime = this.timestampToDateTime.bind(this);
+            this.fromLocalPhone = this.fromLocalPhone.bind(this);
+            this.toLocalPhone = this.toLocalPhone.bind(this);
+        }
+
+        /**
+         * @param {String} phrase
+         * @param {Object} [variables]
+         * @returns {String}
+         */
+        translate(phrase, variables) {
+            return translate(this.props.preferredLocale, phrase, variables);
+        }
+
+        /**
+         * @param {Number} number
+         * @param {Intl.NumberFormatOptions} options
+         * @returns {String}
+         */
+        numberFormat(number, options) {
+            return numberFormat(this.props.preferredLocale, number, options);
+        }
+
+        /**
+         * @param {Number} timestamp
+         * @returns {String}
+         */
+        timestampToRelative(timestamp) {
+            return DateUtils.timestampToRelative(this.props.preferredLocale, timestamp);
+        }
+
+        /**
+         * @param {Number} timestamp
+         * @param {Boolean} [includeTimezone]
+         * @returns {String}
+         */
+        timestampToDateTime(timestamp, includeTimezone) {
+            return DateUtils.timestampToDateTime(
+                this.props.preferredLocale,
+                timestamp,
+                includeTimezone,
+            );
+        }
+
+        /**
+         * @param {Number} number
+         * @returns {String}
+         */
+        toLocalPhone(number) {
+            return toLocalPhone(this.props.preferredLocale, number);
+        }
+
+        /**
+         * @param {Number} number
+         * @returns {String}
+         */
+        fromLocalPhone(number) {
+            return fromLocalPhone(this.props.preferredLocale, number);
+        }
+
+        render() {
+            return (
+                <WrappedComponent
+                    // eslint-disable-next-line react/jsx-props-no-spreading
+                    {...this.props}
+                    ref={this.props.forwardedRef}
+                    translate={this.translate}
+                    numberFormat={this.numberFormat}
+                    timestampToRelative={this.timestampToRelative}
+                    timestampToDateTime={this.timestampToDateTime}
+                    toLocalPhone={this.toLocalPhone}
+                    fromLocalPhone={this.fromLocalPhone}
+                />
+            );
+        }
+    }
+
+    WithLocalize.propTypes = propTypes;
+    WithLocalize.defaultProps = defaultProps;
+
+    const withForwardedRef = React.forwardRef((props, ref) => (
         // eslint-disable-next-line react/jsx-props-no-spreading
         <WithLocalize {...props} forwardedRef={ref} />
     ));
-}
-export default compose(
-    withOnyx({
+
+    withForwardedRef.displayName = `withLocalize(${getComponentDisplayName(WrappedComponent)})`;
+
+    return withOnyx({
         preferredLocale: {
             key: ONYXKEYS.NVP_PREFERRED_LOCALE,
         },
-    }),
-    withLocalizeHOC,
-);
+    })(withForwardedRef);
+};
 
 export {
     withLocalizePropTypes,
diff --git a/src/libs/Firebase/index.js b/src/libs/Firebase/index.js
new file mode 100644
index 000000000000..a8c7a34f869f
--- /dev/null
+++ b/src/libs/Firebase/index.js
@@ -0,0 +1,6 @@
+/** Web does not use Firebase for performance tracing */
+
+export default {
+    startTrace() {},
+    stopTrace() {},
+};
diff --git a/src/libs/Firebase/index.native.js b/src/libs/Firebase/index.native.js
new file mode 100644
index 000000000000..af627091a0ae
--- /dev/null
+++ b/src/libs/Firebase/index.native.js
@@ -0,0 +1,56 @@
+/* eslint-disable no-unused-vars */
+import perf from '@react-native-firebase/perf';
+import {isDevelopment} from '../Environment/Environment';
+import Log from '../Log';
+
+const traceMap = {};
+
+/**
+ * @param {String} customEventName
+ */
+function startTrace(customEventName) {
+    const start = global.performance.now();
+    if (isDevelopment()) {
+        return;
+    }
+
+    if (traceMap[customEventName]) {
+        return;
+    }
+
+    perf().startTrace(customEventName)
+        .then((trace) => {
+            traceMap[customEventName] = {
+                trace,
+                start,
+            };
+        });
+}
+
+/**
+ * @param {String} customEventName
+ */
+function stopTrace(customEventName) {
+    const stop = global.performance.now();
+
+    if (isDevelopment()) {
+        return;
+    }
+
+    const {trace, start} = traceMap[customEventName];
+    if (!trace) {
+        return;
+    }
+
+    trace.stop();
+
+    // Uncomment to inspect logs on release builds
+    // Log.info(`sidebar_loaded: ${stop - start} ms`, true);
+
+    delete traceMap[customEventName];
+}
+
+export default {
+    startTrace,
+    stopTrace,
+};
diff --git a/src/libs/KeyboardShortcut/index.js b/src/libs/KeyboardShortcut/index.js
index 3cc302801e99..1f82b4cab687 100644
--- a/src/libs/KeyboardShortcut/index.js
+++ b/src/libs/KeyboardShortcut/index.js
@@ -5,6 +5,7 @@ const events = {};
 /**
  * Checks if an event for that key is configured and if so, runs it.
  * @param {Event} event
+ * @private
  */
 function bindHandlerToKeyupEvent(event) {
     if (events[event.keyCode] === undefined) {
@@ -12,9 +13,10 @@ function bindHandlerToKeyupEvent(event) {
     }
 
     const eventCallbacks = events[event.keyCode];
+    const reversedEventCallbacks = [...eventCallbacks].reverse();
 
     // Loop over all the callbacks
-    eventCallbacks.forEach((callback) => {
+    _.every(reversedEventCallbacks, (callback) => {
         const pressedModifiers = _.all(callback.modifiers, (modifier) => {
             if (modifier === 'shift' && !event.shiftKey) {
                 return false;
@@ -50,7 +52,7 @@ function bindHandlerToKeyupEvent(event) {
             return false;
         });
         if (!pressedModifiers || pressedExtraModifiers) {
-            return;
+            return true;
         }
 
         // If configured to do so, prevent input text control to trigger this event
@@ -59,13 +61,16 @@ function bindHandlerToKeyupEvent(event) {
             || event.target.nodeName === 'TEXTAREA'
             || event.target.contentEditable === 'true'
         )) {
-            return;
+            return true;
         }
 
         if (_.isFunction(callback.callback)) {
             callback.callback(event);
         }
         event.preventDefault();
+
+        // Short circuit the loop because the event is triggered
+        return false;
     });
 }
 
@@ -73,6 +78,52 @@ function bindHandlerToKeyupEvent(event) {
 document.removeEventListener('keydown', bindHandlerToKeyupEvent, {capture: true});
 document.addEventListener('keydown', bindHandlerToKeyupEvent, {capture: true});
 
+/**
+ * Returns keyCode for a given key
+ * @param {String} key The key to watch, i.e. 'K' or 'Escape'
+ * @returns {Number} The key's keyCode, i.e. 75 or 27
+ * @private
+ */
+function getKeyCode(key) {
+    // For keys that have longer names we must catch and return the correct key key.charCodeAt(0) would return the
+    // key code for 'E' (the letter at index 0 in the string) not 'Escape'
+    switch (key) {
+        case 'Enter':
+            return 13;
+        case 'Escape':
+            return 27;
+        default:
+            return key.charCodeAt(0);
+    }
+}
+
+/**
+ * Unsubscribes to a keyboard event.
+ * @param {Number} key The key to stop watching
+ * @private
+ */
+function unsubscribe(key) {
+    const keyCode = getKeyCode(key);
+    events[keyCode].pop();
+}
+
+/**
+ * Subscribes to a keyboard event.
+ * @param {String} key The key to watch, i.e. 'K' or 'Escape'
+ * @param {Function} callback The callback to call
+ * @param {String|Array} modifiers Can either be shift or control
+ * @param {Boolean} captureOnInputs Should we capture the event on inputs too?
+ * @returns {Function} clean up method
+ */
+function subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) {
+    const keyCode = getKeyCode(key);
+    if (events[keyCode] === undefined) {
+        events[keyCode] = [];
+    }
+    events[keyCode].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs});
+    return () => unsubscribe(key);
+}
+
 /**
  * Module storing the different keyboard shortcut
  *
@@ -85,49 +136,7 @@ document.addEventListener('keydown', bindHandlerToKeyupEvent, {capture: true});
  * The "subClass" is used by pages to bind /unbind with no worries
  */
 const KeyboardShortcut = {
-    /**
-     * Returns keyCode for a given key
-     * @param {String} key The key to watch, i.e. 'K' or 'Escape'
-     * @returns {Number} The key's keyCode, i.e. 75 or 27
-     */
-    getKeyCode(key) {
-        // For keys that have longer names we must catch and return the correct key key.charCodeAt(0) would return the
-        // key code for 'E' (the letter at index 0 in the string) not 'Escape'
-        switch (key) {
-            case 'Enter':
-                return 13;
-            case 'Escape':
-                return 27;
-            default:
-                return key.charCodeAt(0);
-        }
-    },
-
-    /**
-     * Subscribes to a keyboard event.
-     * @param {String} key The key to watch, i.e. 'K' or 'Escape'
-     * @param {Function} callback The callback to call
-     * @param {String|Array} modifiers Can either be shift or control
-     * @param {Boolean} captureOnInputs Should we capture the event on inputs too?
-     * @returns {Function} clean up method
-     */
-    subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) {
-        const keyCode = this.getKeyCode(key);
-        if (events[keyCode] === undefined) {
-            events[keyCode] = [];
-        }
-        events[keyCode].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs});
-        return () => this.unsubscribe(key);
-    },
-
-    /**
-     * Unsubscribes to a keyboard event.
-     * @param {Number} key The key to stop watching
-     */
-    unsubscribe(key) {
-        const keyCode = this.getKeyCode(key);
-        delete events[keyCode];
-    },
+    subscribe,
 };
 
 export default KeyboardShortcut;
diff --git a/src/libs/LocalePhoneNumber.js b/src/libs/LocalePhoneNumber.js
index 4d51e711d705..3d47e7c6a5a9 100644
--- a/src/libs/LocalePhoneNumber.js
+++ b/src/libs/LocalePhoneNumber.js
@@ -10,7 +10,7 @@ import translations from '../languages/translations';
  *
  * @param {String} locale eg 'en', 'es-ES'
  * @param {String} number
- * @returns {string}
+ * @returns {String}
  */
 function toLocalPhone(locale, number) {
     const numString = lodashTrim(number);
@@ -31,7 +31,7 @@ function toLocalPhone(locale, number) {
  *
  * @param {String} locale eg 'en', 'es-ES'
  * @param {String} number
- * @returns {string}
+ * @returns {String}
  */
 function fromLocalPhone(locale, number) {
     const numString = lodashTrim(number);
diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js
index 5ba802e792bf..028ff82ea443 100644
--- a/src/libs/Navigation/AppNavigator/AuthScreens.js
+++ b/src/libs/Navigation/AppNavigator/AuthScreens.js
@@ -178,24 +178,23 @@ class AuthScreens extends React.Component {
 
         Timing.end(CONST.TIMING.HOMEPAGE_INITIAL_RENDER);
 
+        let searchShortcutModifiers = ['control'];
+        let groupShortcutModifiers = ['control', 'shift'];
+
+        if (getOperatingSystem() === CONST.OS.MAC_OS) {
+            searchShortcutModifiers = ['meta'];
+            groupShortcutModifiers = ['meta', 'shift'];
+        }
+
         // Listen for the key K being pressed so that focus can be given to
         // the chat switcher, or new group chat
         // based on the key modifiers pressed and the operating system
-        if (getOperatingSystem() === CONST.OS.MAC_OS) {
-            KeyboardShortcut.subscribe('K', () => {
-                Navigation.navigate(ROUTES.SEARCH);
-            }, ['meta'], true);
-            KeyboardShortcut.subscribe('K', () => {
-                Navigation.navigate(ROUTES.NEW_GROUP);
-            }, ['meta', 'shift'], true);
-        } else {
-            KeyboardShortcut.subscribe('K', () => {
-                Navigation.navigate(ROUTES.SEARCH);
-            }, ['control'], true);
-            KeyboardShortcut.subscribe('K', () => {
-                Navigation.navigate(ROUTES.NEW_GROUP);
-            }, ['control', 'shift'], true);
-        }
+        this.unsubscribeSearchShortcut = KeyboardShortcut.subscribe('K', () => {
+            Navigation.navigate(ROUTES.SEARCH);
+        }, searchShortcutModifiers, true);
+        this.unsubscribeGroupShortcut = KeyboardShortcut.subscribe('K', () => {
+            Navigation.navigate(ROUTES.NEW_GROUP);
+        }, groupShortcutModifiers, true);
     }
 
     shouldComponentUpdate(nextProps) {
@@ -215,7 +214,12 @@ class AuthScreens extends React.Component {
     }
 
     componentWillUnmount() {
-        KeyboardShortcut.unsubscribe('K');
+        if (this.unsubscribeSearchShortcut) {
+            this.unsubscribeSearchShortcut();
+        }
+        if (this.unsubscribeGroupShortcut) {
+            this.unsubscribeGroupShortcut();
+        }
         NetworkConnection.stopListeningForReconnect();
         clearInterval(this.interval);
         this.interval = null;
diff --git a/src/libs/Permissions.js b/src/libs/Permissions.js
index 7063273b245c..1ca31ce88712 100644
--- a/src/libs/Permissions.js
+++ b/src/libs/Permissions.js
@@ -51,10 +51,19 @@ function canUseDefaultRooms(betas) {
     return _.contains(betas, CONST.BETAS.DEFAULT_ROOMS) || canUseAllBetas(betas);
 }
 
+/**
+ * @param {Array<String>} betas
+ * @returns {Boolean}
+ */
+function canUseInternationalization(betas) {
+    return _.contains(betas, CONST.BETAS.INTERNATIONALIZATION) || canUseAllBetas(betas);
+}
+
 export default {
     canUseChronos,
     canUseIOU,
     canUsePayWithExpensify,
     canUseFreePlan,
     canUseDefaultRooms,
+    canUseInternationalization,
 };
diff --git a/src/libs/UnreadIndicatorUpdater/updateUnread/index.website.js b/src/libs/UnreadIndicatorUpdater/updateUnread/index.website.js
index aca9134a16ab..75f6d3f31d08 100644
--- a/src/libs/UnreadIndicatorUpdater/updateUnread/index.website.js
+++ b/src/libs/UnreadIndicatorUpdater/updateUnread/index.website.js
@@ -10,7 +10,7 @@ import CONFIG from '../../../CONFIG';
  */
 function updateUnread(totalCount) {
     const hasUnread = totalCount !== 0;
-    document.title = hasUnread ? `(NEW!) ${CONFIG.SITE_TITLE}` : CONFIG.SITE_TITLE;
+    document.title = hasUnread ? `(${totalCount}) ${CONFIG.SITE_TITLE}` : CONFIG.SITE_TITLE;
     document.getElementById('favicon').href = hasUnread ? CONFIG.FAVICON.UNREAD : CONFIG.FAVICON.DEFAULT;
 }
 
diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js
index 9635948348cd..e3b339fdc7ab 100644
--- a/src/libs/actions/App.js
+++ b/src/libs/actions/App.js
@@ -1,6 +1,16 @@
 import Onyx from 'react-native-onyx';
 import ONYXKEYS from '../../ONYXKEYS';
 import * as API from '../API';
+import Firebase from '../Firebase';
+import CONST from '../../CONST';
+
+let isSidebarLoaded;
+
+Onyx.connect({
+    key: ONYXKEYS.IS_SIDEBAR_LOADED,
+    callback: val => isSidebarLoaded = val,
+    initWithStoredValues: false,
+});
 
 /**
  * @param {String} url
@@ -17,7 +27,17 @@ function setLocale(locale) {
     Onyx.merge(ONYXKEYS.NVP_PREFERRED_LOCALE, locale);
 }
 
+function setSidebarLoaded() {
+    if (isSidebarLoaded) {
+        return;
+    }
+
+    Onyx.set(ONYXKEYS.IS_SIDEBAR_LOADED, true);
+    Firebase.stopTrace(CONST.TIMING.SIDEBAR_LOADED);
+}
+
 export {
     setCurrentURL,
     setLocale,
+    setSidebarLoaded,
 };
diff --git a/src/libs/actions/PaymentMethods.js b/src/libs/actions/PaymentMethods.js
index f6474b581cd9..5f995433e465 100644
--- a/src/libs/actions/PaymentMethods.js
+++ b/src/libs/actions/PaymentMethods.js
@@ -13,6 +13,8 @@ function getPaymentMethods() {
     return API.Get({
         returnValueList: 'bankAccountList, cardList, userWallet, nameValuePairs',
         name: 'paypalMeAddress',
+        includeDeleted: false,
+        includeNotIssued: false,
     })
         .then((response) => {
             Onyx.multiSet({
diff --git a/src/libs/actions/Session.js b/src/libs/actions/Session.js
index 3540939041fd..94bf1ff064a1 100644
--- a/src/libs/actions/Session.js
+++ b/src/libs/actions/Session.js
@@ -299,6 +299,15 @@ function continueSessionFromECom(accountID, validateCode, twoFactorAuthCode) {
     });
 }
 
+/**
+ * Sets the redirectToWorkspaceNewAfterSignIn flag in the session variable
+ *
+ * @param {Boolean} shouldRedirect
+ */
+function setRedirectToWorkspaceNewAfterSignIn(shouldRedirect) {
+    Onyx.merge(ONYXKEYS.SESSION, {redirectToWorkspaceNewAfterSignIn: shouldRedirect});
+}
+
 export {
     continueSessionFromECom,
     fetchAccountDetails,
@@ -309,4 +318,5 @@ export {
     resendValidationLink,
     resetPassword,
     restartSignin,
+    setRedirectToWorkspaceNewAfterSignIn,
 };
diff --git a/src/libs/actions/SignInRedirect.js b/src/libs/actions/SignInRedirect.js
index 583753ec8d3e..a206b5f249ac 100644
--- a/src/libs/actions/SignInRedirect.js
+++ b/src/libs/actions/SignInRedirect.js
@@ -19,6 +19,12 @@ Onyx.connect({
     },
 });
 
+let currentPreferredLocale;
+Onyx.connect({
+    key: ONYXKEYS.PREFERRED_LOCALE,
+    callback: val => currentPreferredLocale = val,
+});
+
 /**
  * Clears the Onyx store and redirects to the sign in page.
  * Normally this method would live in Session.js, but that would cause a circular dependency with Network.js.
@@ -37,12 +43,16 @@ function redirectToSignIn(errorMessage) {
     }
 
     const activeClients = currentActiveClients;
+    const preferredLocale = currentPreferredLocale;
 
     // We must set the authToken to null so we can navigate to "signin" it's not possible to navigate to the route as
     // it only exists when the authToken is null.
     Onyx.set(ONYXKEYS.SESSION, {authToken: null})
         .then(() => {
             Onyx.clear().then(() => {
+                if (preferredLocale) {
+                    Onyx.set(ONYXKEYS.PREFERRED_LOCALE, preferredLocale);
+                }
                 if (errorMessage) {
                     Onyx.set(ONYXKEYS.SESSION, {error: errorMessage});
                 }
diff --git a/src/libs/actions/Timing.js b/src/libs/actions/Timing.js
index 4d1eae31a36f..a0cbae149360 100644
--- a/src/libs/actions/Timing.js
+++ b/src/libs/actions/Timing.js
@@ -1,5 +1,6 @@
 import getPlatform from '../getPlatform';
 import {Graphite_Timer} from '../API';
+import {isDevelopment} from '../Environment/Environment';
 
 let timestampData = {};
 
@@ -26,14 +27,19 @@ function end(eventName, secondaryName = '') {
             : `expensify.cash.${eventName}`;
 
         console.debug(`Timing:${grafanaEventName}`, eventTime);
+        delete timestampData[eventName];
+
+        // eslint-disable-next-line no-undef
+        if (isDevelopment()) {
+            // Don't create traces on dev as this will mess up the accuracy of data in release builds of the app
+            return;
+        }
 
         Graphite_Timer({
             name: grafanaEventName,
             value: eventTime,
             platform: `${getPlatform()}`,
         });
-
-        delete timestampData[eventName];
     }
 }
 
diff --git a/src/libs/numberFormat/index.android.js b/src/libs/numberFormat/index.native.js
similarity index 100%
rename from src/libs/numberFormat/index.android.js
rename to src/libs/numberFormat/index.native.js
diff --git a/src/pages/DetailsPage.js b/src/pages/DetailsPage.js
index c36129e5d319..ad99904118c9 100755
--- a/src/pages/DetailsPage.js
+++ b/src/pages/DetailsPage.js
@@ -92,24 +92,13 @@ const DetailsPage = ({
                                 imageStyles={[styles.avatarLarge]}
                                 source={details.avatar}
                             />
-                            {details.displayName && isSMSLogin
-                                ? (
-                                    <CommunicationsLink
-                                        style={[styles.mt1, styles.mb6]}
-                                        type={CONST.LOGIN_TYPE.PHONE}
-                                        value={getPhoneNumber(details)}
-                                    >
-                                        <Text style={[styles.displayName]} numberOfLines={1}>
-                                            {toLocalPhone(details.displayName)}
-                                        </Text>
-                                    </CommunicationsLink>
-                                ) : (
-                                    <Text style={[styles.displayName]} numberOfLines={1}>
-                                        {details.displayName || null}
-                                    </Text>
-                                )}
+                            {details.displayName && (
+                                <Text style={[styles.displayName, styles.mb6]} numberOfLines={1}>
+                                    {isSMSLogin ? toLocalPhone(details.displayName) : details.displayName}
+                                </Text>
+                            )}
                             {details.login ? (
-                                <View style={[styles.mb6, styles.detailsPageSectionContainer]}>
+                                <View style={[styles.mb6, styles.detailsPageSectionContainer, styles.w100]}>
                                     <Text style={[styles.formLabel, styles.mb2]} numberOfLines={1}>
                                         {translate(isSMSLogin
                                             ? 'common.phoneNumber'
diff --git a/src/pages/ReimbursementAccount/IdentityForm.js b/src/pages/ReimbursementAccount/IdentityForm.js
index ce0a0383f330..3122d5e6532b 100644
--- a/src/pages/ReimbursementAccount/IdentityForm.js
+++ b/src/pages/ReimbursementAccount/IdentityForm.js
@@ -96,7 +96,7 @@ const IdentityForm = ({
                 onChangeText={val => onFieldChange('ssnLast4', val)}
             />
             <TextInputWithLabel
-                label={translate('common.companyAddressNoPO')}
+                label={translate('common.addressNoPO')}
                 containerStyles={[styles.mt4]}
                 value={street}
                 onChangeText={val => onFieldChange('street', val)}
diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js
index 564e0181679c..7244c9460a34 100755
--- a/src/pages/SearchPage.js
+++ b/src/pages/SearchPage.js
@@ -128,7 +128,7 @@ class SearchPage extends Component {
         } = getSearchOptions(
             this.props.reports,
             this.props.personalDetails,
-            this.state.searchValue,
+            this.state.searchValue.trim(),
             this.props.betas,
         );
         this.setState({
diff --git a/src/pages/ValidateLogin2FANewWorkspacePage.js b/src/pages/ValidateLogin2FANewWorkspacePage.js
index bbe5b804a200..6e9c07d44b9b 100644
--- a/src/pages/ValidateLogin2FANewWorkspacePage.js
+++ b/src/pages/ValidateLogin2FANewWorkspacePage.js
@@ -3,9 +3,10 @@ import {TextInput, View} from 'react-native';
 import lodashGet from 'lodash/get';
 import PropTypes from 'prop-types';
 import {withOnyx} from 'react-native-onyx';
+import _ from 'underscore';
 import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
 import validateLinkPropTypes from './validateLinkPropTypes';
-import {continueSessionFromECom} from '../libs/actions/Session';
+import {continueSessionFromECom, setRedirectToWorkspaceNewAfterSignIn} from '../libs/actions/Session';
 import styles from '../styles/styles';
 import ExpensifyCashLogo from '../components/ExpensifyCashLogo';
 import variables from '../styles/variables';
@@ -30,6 +31,9 @@ const propTypes = {
     /** The accountID and validateCode are passed via the URL */
     route: validateLinkPropTypes,
 
+    /** List of betas */
+    betas: PropTypes.arrayOf(PropTypes.string),
+
     ...withLocalizePropTypes,
 };
 
@@ -38,6 +42,7 @@ const defaultProps = {
         params: {},
     },
     session: {},
+    betas: [],
 };
 class ValidateLogin2FANewWorkspacePage extends Component {
     constructor(props) {
@@ -62,7 +67,12 @@ class ValidateLogin2FANewWorkspacePage extends Component {
             // by calling dismissModal(), the /v/... route is removed from history so the user will get taken to `/`
             // if they cancel out of the new workspace modal.
             Navigation.dismissModal();
-            Navigation.navigate(ROUTES.WORKSPACE_NEW);
+
+            if (_.isEmpty(this.props.betas)) {
+                setRedirectToWorkspaceNewAfterSignIn(true);
+            } else {
+                Navigation.navigate(ROUTES.WORKSPACE_NEW);
+            }
         }
     }
 
@@ -144,5 +154,8 @@ export default compose(
         session: {
             key: ONYXKEYS.SESSION,
         },
+        betas: {
+            key: ONYXKEYS.BETAS,
+        },
     }),
 )(ValidateLogin2FANewWorkspacePage);
diff --git a/src/pages/ValidateLoginNewWorkspacePage.js b/src/pages/ValidateLoginNewWorkspacePage.js
index 5e672f1a4d9b..5a1b8ab1f1c8 100644
--- a/src/pages/ValidateLoginNewWorkspacePage.js
+++ b/src/pages/ValidateLoginNewWorkspacePage.js
@@ -2,12 +2,13 @@ import {Component} from 'react';
 import PropTypes from 'prop-types';
 import {withOnyx} from 'react-native-onyx';
 import lodashGet from 'lodash/get';
+import _ from 'underscore';
 import validateLinkPropTypes from './validateLinkPropTypes';
 import compose from '../libs/compose';
 import ONYXKEYS from '../ONYXKEYS';
 import Navigation from '../libs/Navigation/Navigation';
 import ROUTES from '../ROUTES';
-import {continueSessionFromECom} from '../libs/actions/Session';
+import {continueSessionFromECom, setRedirectToWorkspaceNewAfterSignIn} from '../libs/actions/Session';
 
 const propTypes = {
     /* Onyx Props */
@@ -20,6 +21,9 @@ const propTypes = {
 
     /** The accountID and validateCode are passed via the URL */
     route: validateLinkPropTypes,
+
+    /** List of betas */
+    betas: PropTypes.arrayOf(PropTypes.string),
 };
 
 const defaultProps = {
@@ -27,6 +31,7 @@ const defaultProps = {
         params: {},
     },
     session: {},
+    betas: [],
 };
 class ValidateLoginNewWorkspacePage extends Component {
     componentDidMount() {
@@ -39,7 +44,11 @@ class ValidateLoginNewWorkspacePage extends Component {
             // by calling dismissModal(), the /v/... route is removed from history so the user will get taken to `/`
             // if they cancel out of the new workspace modal.
             Navigation.dismissModal();
-            Navigation.navigate(ROUTES.WORKSPACE_NEW);
+            if (_.isEmpty(this.props.betas)) {
+                setRedirectToWorkspaceNewAfterSignIn(true);
+            } else {
+                Navigation.navigate(ROUTES.WORKSPACE_NEW);
+            }
             return;
         }
 
@@ -63,5 +72,8 @@ export default compose(
         session: {
             key: ONYXKEYS.SESSION,
         },
+        betas: {
+            key: ONYXKEYS.BETAS,
+        },
     }),
 )(ValidateLoginNewWorkspacePage);
diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js
index ae87bc4b6921..dfe7cea28c1b 100644
--- a/src/pages/home/ReportScreen.js
+++ b/src/pages/home/ReportScreen.js
@@ -1,4 +1,5 @@
 import React from 'react';
+import {withOnyx} from 'react-native-onyx';
 import PropTypes from 'prop-types';
 import styles from '../../styles/styles';
 import ReportView from './report/ReportView';
@@ -8,6 +9,7 @@ import Navigation from '../../libs/Navigation/Navigation';
 import ROUTES from '../../ROUTES';
 import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndicator';
 import {updateCurrentlyViewedReportID} from '../../libs/actions/Report';
+import ONYXKEYS from '../../ONYXKEYS';
 
 const propTypes = {
     /** Navigation route context info provided by react navigation */
@@ -18,6 +20,13 @@ const propTypes = {
             reportID: PropTypes.string,
         }).isRequired,
     }).isRequired,
+
+    /** Tells us if the sidebar has rendered */
+    isSidebarLoaded: PropTypes.bool,
+};
+
+const defaultProps = {
+    isSidebarLoaded: false,
 };
 
 class ReportScreen extends React.Component {
@@ -84,6 +93,10 @@ class ReportScreen extends React.Component {
     }
 
     render() {
+        if (!this.props.isSidebarLoaded) {
+            return null;
+        }
+
         return (
             <ScreenWrapper style={[styles.appContent, styles.flex1]}>
                 <HeaderView
@@ -100,4 +113,10 @@ class ReportScreen extends React.Component {
 }
 
 ReportScreen.propTypes = propTypes;
-export default ReportScreen;
+ReportScreen.defaultProps = defaultProps;
+
+export default withOnyx({
+    isSidebarLoaded: {
+        key: ONYXKEYS.IS_SIDEBAR_LOADED,
+    },
+})(ReportScreen);
diff --git a/src/pages/home/report/EmojiPickerMenu/index.js b/src/pages/home/report/EmojiPickerMenu/index.js
index 044abc87a2cc..51d0307a21f6 100755
--- a/src/pages/home/report/EmojiPickerMenu/index.js
+++ b/src/pages/home/report/EmojiPickerMenu/index.js
@@ -274,7 +274,7 @@ class EmojiPickerMenu extends Component {
      * @param {String} searchTerm
      */
     filterEmojis(searchTerm) {
-        const normalizedSearchTerm = searchTerm.toLowerCase();
+        const normalizedSearchTerm = searchTerm.toLowerCase().trim();
         if (normalizedSearchTerm === '') {
             // There are no headers when searching, so we need to re-make them sticky when there is no search term
             this.setState({
@@ -298,7 +298,9 @@ class EmojiPickerMenu extends Component {
     /**
      * Given an emoji item object, render a component based on its type.
      * Items with the code "SPACER" return nothing and are used to fill rows up to 8
-     * so that the sticky headers function properly
+     * so that the sticky headers function properly.
+     * We add '\uFE0F' to our unicode to force the correct emoji presentation (VS16)
+     * on emojis that also have a text style presentation (VS15).
      *
      * @param {Object} item
      * @param {Number} index
@@ -313,7 +315,7 @@ class EmojiPickerMenu extends Component {
         if (header) {
             return (
                 <Text style={styles.emojiHeaderStyle}>
-                    {code}
+                    {`${code}\uFE0F`}
                 </Text>
             );
         }
@@ -322,7 +324,7 @@ class EmojiPickerMenu extends Component {
             <EmojiPickerMenuItem
                 onPress={this.props.onEmojiSelected}
                 onHover={() => this.setState({highlightedIndex: index})}
-                emoji={code}
+                emoji={`${code}\uFE0F`}
                 isHighlighted={index === this.state.highlightedIndex}
                 emojiSize={this.emojiSize}
             />
diff --git a/src/pages/home/report/EmojiPickerMenu/index.native.js b/src/pages/home/report/EmojiPickerMenu/index.native.js
index b1a4d1302506..6708330dffca 100644
--- a/src/pages/home/report/EmojiPickerMenu/index.native.js
+++ b/src/pages/home/report/EmojiPickerMenu/index.native.js
@@ -58,7 +58,7 @@ class EmojiPickerMenu extends Component {
         if (item.header) {
             return (
                 <Text style={styles.emojiHeaderStyle}>
-                    {item.code}
+                    {`${item.code}\uFE0F`}
                 </Text>
             );
         }
@@ -66,7 +66,7 @@ class EmojiPickerMenu extends Component {
         return (
             <EmojiPickerMenuItem
                 onPress={this.props.onEmojiSelected}
-                emoji={item.code}
+                emoji={`${item.code}\uFE0F`}
                 emojiSize={this.emojiSize}
             />
         );
diff --git a/src/pages/home/report/ParticipantLocalTime.js b/src/pages/home/report/ParticipantLocalTime.js
index 595ccb40ae29..cfd902da46e4 100644
--- a/src/pages/home/report/ParticipantLocalTime.js
+++ b/src/pages/home/report/ParticipantLocalTime.js
@@ -42,9 +42,14 @@ class ParticipantLocalTime extends React.Component {
 
     getParticipantLocalTime() {
         const reportRecipientTimezone = lodashGet(this.props.participant, 'timezone', {});
-        return moment().tz(reportRecipientTimezone.selected).format('LT');
-    }
+        const reportRecipientDay = moment().tz(reportRecipientTimezone.selected).format('dddd');
+        const currentUserDay = moment().tz(this.props.currentUserTimezone.selected).format('dddd');
 
+        if (reportRecipientDay !== currentUserDay) {
+            return `${moment().tz(reportRecipientTimezone.selected).format('LT')} ${reportRecipientDay}`;
+        }
+        return `${moment().tz(reportRecipientTimezone.selected).format('LT')}`;
+    }
 
     render() {
         // Moment.format does not return AM or PM values immediately.
diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js
index d0bd5fef9e77..f67ea162dafd 100755
--- a/src/pages/home/report/ReportActionCompose.js
+++ b/src/pages/home/report/ReportActionCompose.js
@@ -452,7 +452,7 @@ class ReportActionCompose extends React.Component {
             ]}
             >
                 {shouldShowReportRecipientLocalTime
-                    && <ParticipantLocalTime participant={reportRecipient} />}
+                    && <ParticipantLocalTime participant={reportRecipient} currentUserTimezone={currentUserTimezone} />}
                 <View style={[
                     (this.state.isFocused || this.state.isDraggingOver)
                         ? styles.chatItemComposeBoxFocusedColor
diff --git a/src/pages/home/report/ReportActionContextMenu.js b/src/pages/home/report/ReportActionContextMenu.js
index ca8fcc35b04f..f7e0b7f63d71 100755
--- a/src/pages/home/report/ReportActionContextMenu.js
+++ b/src/pages/home/report/ReportActionContextMenu.js
@@ -14,7 +14,6 @@ import {
 import ContextMenuItem from '../../../components/ContextMenuItem';
 import ReportActionPropTypes from './ReportActionPropTypes';
 import Clipboard from '../../../libs/Clipboard';
-import compose from '../../../libs/compose';
 import {isReportMessageAttachment, canEditReportAction, canDeleteReportAction} from '../../../libs/reportUtils';
 import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
 import ReportActionComposeFocusManager from '../../../libs/ReportActionComposeFocusManager';
@@ -197,6 +196,4 @@ class ReportActionContextMenu extends React.Component {
 ReportActionContextMenu.propTypes = propTypes;
 ReportActionContextMenu.defaultProps = defaultProps;
 
-export default compose(
-    withLocalize,
-)(ReportActionContextMenu);
+export default withLocalize(ReportActionContextMenu);
diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js
index 2561f83b111c..64b3a9fa4929 100644
--- a/src/pages/home/report/ReportActionItem.js
+++ b/src/pages/home/report/ReportActionItem.js
@@ -273,6 +273,7 @@ class ReportActionItem extends Component {
                     onPressIn={() => this.props.isSmallScreenWidth && canUseTouchScreen() && ControlSelection.block()}
                     onPressOut={() => ControlSelection.unblock()}
                     onSecondaryInteraction={this.showPopover}
+                    preventDefaultContentMenu={!this.props.draftMessage}
                 >
                     <Hoverable resetsOnClickOutside={false}>
                         {hovered => (
diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js
index 1cf5bf99fce8..84befd28f4c8 100644
--- a/src/pages/home/report/ReportActionItemSingle.js
+++ b/src/pages/home/report/ReportActionItemSingle.js
@@ -95,6 +95,8 @@ const ReportActionItemSingle = ({
 
 ReportActionItemSingle.propTypes = propTypes;
 ReportActionItemSingle.defaultProps = defaultProps;
+ReportActionItemSingle.displayName = 'ReportActionItemSingle';
+
 export default compose(
     withLocalize,
     withOnyx({
diff --git a/src/pages/home/report/ReportView.js b/src/pages/home/report/ReportView.js
index 8481be201ed8..1eb4ea57589a 100644
--- a/src/pages/home/report/ReportView.js
+++ b/src/pages/home/report/ReportView.js
@@ -47,6 +47,7 @@ const ReportView = ({reportID, session}) => (
 
 ReportView.propTypes = propTypes;
 ReportView.defaultProps = defaultProps;
+ReportView.displayName = 'ReportView';
 
 export default withOnyx({
     session: {
diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js
index 48a9c30b842e..d846b67e9e29 100644
--- a/src/pages/home/sidebar/SidebarLinks.js
+++ b/src/pages/home/sidebar/SidebarLinks.js
@@ -20,7 +20,7 @@ import CONST from '../../../CONST';
 import {participantPropTypes} from './optionPropTypes';
 import themeColors from '../../../styles/themes/default';
 import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
-
+import * as App from '../../../libs/actions/App';
 
 const propTypes = {
     /** Toggles the navigation menu open and closed */
@@ -179,6 +179,7 @@ class SidebarLinks extends React.Component {
                     showTitleTooltip
                     disableFocusOptions={this.props.isSmallScreenWidth}
                     optionMode={this.props.priorityMode === CONST.PRIORITY_MODE.GSD ? 'compact' : 'default'}
+                    onLayout={App.setSidebarLoaded}
                 />
                 <KeyboardSpacer />
             </View>
diff --git a/src/pages/home/sidebar/SidebarScreen.js b/src/pages/home/sidebar/SidebarScreen.js
index fcfd60c59950..b4f9dabeb2ed 100755
--- a/src/pages/home/sidebar/SidebarScreen.js
+++ b/src/pages/home/sidebar/SidebarScreen.js
@@ -23,6 +23,7 @@ import {
 } from '../../../components/Icon/Expensicons';
 import Permissions from '../../../libs/Permissions';
 import ONYXKEYS from '../../../ONYXKEYS';
+import Firebase from '../../../libs/Firebase';
 
 const propTypes = {
     /** Beta features list */
@@ -47,6 +48,10 @@ class SidebarScreen extends Component {
         };
     }
 
+    componentDidMount() {
+        Firebase.startTrace(CONST.TIMING.SIDEBAR_LOADED);
+    }
+
     /**
      * Method called when a Create Menu item is selected.
      */
diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js
index 284148db3ea3..660ca27b0422 100755
--- a/src/pages/iou/IOUModal.js
+++ b/src/pages/iou/IOUModal.js
@@ -20,6 +20,7 @@ import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndica
 import ScreenWrapper from '../../components/ScreenWrapper';
 import CONST from '../../CONST';
 import KeyboardAvoidingView from '../../components/KeyboardAvoidingView';
+import * as PersonalDetails from '../../libs/actions/PersonalDetails';
 
 /**
  * IOU modal for requesting money and splitting bills.
@@ -129,6 +130,7 @@ class IOUModal extends Component {
     }
 
     componentDidMount() {
+        PersonalDetails.fetchLocalCurrency();
         setIOUSelectedCurrency(this.props.myPersonalDetails.localCurrencyCode);
     }
 
@@ -287,9 +289,9 @@ class IOUModal extends Component {
                         </View>
                         <View style={[styles.pRelative, styles.flex1]}>
                             <FullScreenLoadingIndicator
-                                visible={!didScreenTransitionEnd || this.props.iou.isRetrievingCurrency}
+                                visible={!didScreenTransitionEnd}
                             />
-                            {didScreenTransitionEnd && !this.props.iou.isRetrievingCurrency && (
+                            {didScreenTransitionEnd && (
                                 <>
                                     {currentStep === Steps.IOUAmount && (
                                         <IOUAmountPage
diff --git a/src/pages/settings/Payments/PaymentMethodList.js b/src/pages/settings/Payments/PaymentMethodList.js
index c76ac9024f4e..7e62429e1f38 100644
--- a/src/pages/settings/Payments/PaymentMethodList.js
+++ b/src/pages/settings/Payments/PaymentMethodList.js
@@ -83,12 +83,17 @@ class PaymentMethodList extends Component {
         _.each(this.props.bankAccountList, (bankAccount) => {
             // Add all bank accounts besides the wallet
             if (bankAccount.type !== CONST.BANK_ACCOUNT_TYPES.WALLET) {
+                const formattedBankAccountNumber = bankAccount.accountNumber
+                    ? `${this.props.translate('paymentMethodList.accountLastFour')} ${
+                        bankAccount.accountNumber.slice(-4)
+                    }`
+                    : null;
                 combinedPaymentMethods.push({
                     type: MENU_ITEM,
                     title: bankAccount.addressName,
 
                     // eslint-disable-next-line
-                    description: `${this.props.translate('paymentMethodList.accountLastFour')} ${bankAccount.accountNumber.slice(-4)}`,
+                    description: formattedBankAccountNumber,
                     icon: Bank,
                     onPress: e => this.props.onPress(e, bankAccount.bankAccountID),
                     key: `bankAccount-${bankAccount.bankAccountID}`,
@@ -99,12 +104,15 @@ class PaymentMethodList extends Component {
         _.each(this.props.cardList, (card) => {
             // Add all cards besides the "cash" card
             if (card.cardName !== CONST.CARD_TYPES.DEFAULT_CASH) {
+                const formattedCardNumber = card.cardNumber
+                    ? `${this.props.translate('paymentMethodList.cardLastFour')} ${card.cardNumber.slice(-4)}`
+                    : null;
                 combinedPaymentMethods.push({
                     type: MENU_ITEM,
                     title: card.cardName,
 
                     // eslint-disable-next-line
-                    description: `${this.props.translate('paymentMethodList.cardLastFour')} ${card.cardNumber.slice(-4)}`,
+                    description: formattedCardNumber,
                     icon: CreditCard,
                     onPress: e => this.props.onPress(e, card.cardID),
                     key: `card-${card.cardID}`,
diff --git a/src/pages/settings/PreferencesPage.js b/src/pages/settings/PreferencesPage.js
index 009150001840..03e8c23c017c 100755
--- a/src/pages/settings/PreferencesPage.js
+++ b/src/pages/settings/PreferencesPage.js
@@ -4,6 +4,7 @@ import {withOnyx} from 'react-native-onyx';
 import PropTypes from 'prop-types';
 
 import HeaderWithCloseButton from '../../components/HeaderWithCloseButton';
+import LocalePicker from '../../components/LocalePicker';
 import Navigation from '../../libs/Navigation/Navigation';
 import ROUTES from '../../ROUTES';
 import ONYXKEYS from '../../ONYXKEYS';
@@ -17,7 +18,6 @@ import Switch from '../../components/Switch';
 import Picker from '../../components/Picker';
 import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
 import compose from '../../libs/compose';
-import {setLocale} from '../../libs/actions/App';
 
 const propTypes = {
     /** The chat priority mode */
@@ -29,20 +29,16 @@ const propTypes = {
         expensifyNewsStatus: PropTypes.bool,
     }),
 
-    /** Indicates which locale the user currently has selected */
-    preferredLocale: PropTypes.string,
-
     ...withLocalizePropTypes,
 };
 
 const defaultProps = {
     priorityMode: CONST.PRIORITY_MODE.DEFAULT,
     user: {},
-    preferredLocale: CONST.DEFAULT_LOCALE,
 };
 
 const PreferencesPage = ({
-    priorityMode, user, translate, preferredLocale,
+    priorityMode, user, translate,
 }) => {
     const priorityModes = {
         default: {
@@ -57,17 +53,6 @@ const PreferencesPage = ({
         },
     };
 
-    const localesToLanguages = {
-        default: {
-            value: 'en',
-            label: translate('preferencesPage.languages.english'),
-        },
-        es: {
-            value: 'es',
-            label: translate('preferencesPage.languages.spanish'),
-        },
-    };
-
     return (
         <ScreenWrapper>
             <HeaderWithCloseButton
@@ -109,19 +94,8 @@ const PreferencesPage = ({
                     <Text style={[styles.textLabel, styles.colorMuted, styles.mb6]}>
                         {priorityModes[priorityMode].description}
                     </Text>
-                    <Text style={[styles.formLabel]} numberOfLines={1}>
-                        {translate('preferencesPage.language')}
-                    </Text>
                     <View style={[styles.mb2]}>
-                        <Picker
-                            onChange={(locale) => {
-                                if (locale !== preferredLocale) {
-                                    setLocale(locale);
-                                }
-                            }}
-                            items={Object.values(localesToLanguages)}
-                            value={preferredLocale}
-                        />
+                        <LocalePicker />
                     </View>
                 </View>
             </View>
@@ -142,8 +116,5 @@ export default compose(
         user: {
             key: ONYXKEYS.USER,
         },
-        preferredLocale: {
-            key: ONYXKEYS.NVP_PREFERRED_LOCALE,
-        },
     }),
 )(PreferencesPage);
diff --git a/src/pages/settings/Profile/ProfilePage.js b/src/pages/settings/Profile/ProfilePage.js
index df883255c03a..c8d7e5ba0b09 100755
--- a/src/pages/settings/Profile/ProfilePage.js
+++ b/src/pages/settings/Profile/ProfilePage.js
@@ -193,8 +193,8 @@ class ProfilePage extends Component {
                 && this.props.myPersonalDetails.pronouns === this.state.selfSelectedPronouns);
 
         // Disables button if none of the form values have changed
-        const isButtonDisabled = (this.props.myPersonalDetails.firstName === this.state.firstName)
-            && (this.props.myPersonalDetails.lastName === this.state.lastName)
+        const isButtonDisabled = (this.props.myPersonalDetails.firstName === this.state.firstName.trim())
+            && (this.props.myPersonalDetails.lastName === this.state.lastName.trim())
             && (this.props.myPersonalDetails.timezone.selected === this.state.selectedTimezone)
             && (this.props.myPersonalDetails.timezone.automatic === this.state.isAutomaticTimezone)
             && arePronounsUnchanged;
diff --git a/src/pages/signin/LoginForm.js b/src/pages/signin/LoginForm.js
index 547c43760fe9..d6f7d8463830 100755
--- a/src/pages/signin/LoginForm.js
+++ b/src/pages/signin/LoginForm.js
@@ -88,15 +88,6 @@ class LoginForm extends React.Component {
                         autoFocus={canFocusInputOnScreenFocus()}
                     />
                 </View>
-                <View style={[styles.mt5]}>
-                    <Button
-                        success
-                        text={this.props.translate('common.continue')}
-                        isLoading={this.props.account.loading}
-                        onPress={this.validateAndSubmitForm}
-                    />
-                </View>
-
                 {this.state.formError && (
                     <Text style={[styles.formError]}>
                         {this.state.formError}
@@ -113,6 +104,15 @@ class LoginForm extends React.Component {
                         {this.props.account.success}
                     </Text>
                 )}
+                <View style={[styles.mt5]}>
+                    <Button
+                        success
+                        text={this.props.translate('common.continue')}
+                        isLoading={this.props.account.loading}
+                        onPress={this.validateAndSubmitForm}
+                    />
+                </View>
+
             </>
         );
     }
diff --git a/src/pages/signin/PasswordForm.js b/src/pages/signin/PasswordForm.js
index 9fdc16c599f8..fc2cf2e804e6 100755
--- a/src/pages/signin/PasswordForm.js
+++ b/src/pages/signin/PasswordForm.js
@@ -4,6 +4,7 @@ import {
 } from 'react-native';
 import PropTypes from 'prop-types';
 import {withOnyx} from 'react-native-onyx';
+import _ from 'underscore';
 import styles from '../../styles/styles';
 import Button from '../../components/Button';
 import Text from '../../components/Text';
@@ -110,6 +111,18 @@ class PasswordForm extends React.Component {
                         />
                     </View>
                 )}
+
+                {this.props.account && !_.isEmpty(this.props.account.error) && (
+                    <Text style={[styles.formError]}>
+                        {this.props.account.error}
+                    </Text>
+                )}
+
+                {this.state.formError && (
+                    <Text style={[styles.formError]}>
+                        {this.state.formError}
+                    </Text>
+                )}
                 <View>
                     <Button
                         success
@@ -120,11 +133,6 @@ class PasswordForm extends React.Component {
                     />
                     <ChangeExpensifyLoginLink />
                 </View>
-                {this.state.formError && (
-                    <Text style={[styles.formError]}>
-                        {this.state.formError}
-                    </Text>
-                )}
             </>
         );
     }
diff --git a/src/pages/signin/ResendValidationForm.js b/src/pages/signin/ResendValidationForm.js
index f95d7cea43f8..cbae3f489a83 100755
--- a/src/pages/signin/ResendValidationForm.js
+++ b/src/pages/signin/ResendValidationForm.js
@@ -80,6 +80,11 @@ class ResendValidationForm extends React.Component {
                         {this.props.translate('resendValidationForm.weSentYouMagicSignInLink')}
                     </Text>
                 </View>
+                {!_.isEmpty(this.state.formSuccess) && (
+                    <Text style={[styles.formSuccess]}>
+                        {this.state.formSuccess}
+                    </Text>
+                )}
                 <View style={[styles.mt4]}>
                     <Button
                         success
@@ -90,12 +95,6 @@ class ResendValidationForm extends React.Component {
                     />
                     <ChangeExpensifyLoginLink />
                 </View>
-
-                {!_.isEmpty(this.state.formSuccess) && (
-                    <Text style={[styles.formSuccess]}>
-                        {this.state.formSuccess}
-                    </Text>
-                )}
             </>
         );
     }
diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js
index bab1ccdd3564..7af84f558677 100644
--- a/src/pages/signin/SignInPage.js
+++ b/src/pages/signin/SignInPage.js
@@ -1,11 +1,9 @@
 import React, {Component} from 'react';
 import {
-    SafeAreaView, View,
+    SafeAreaView,
 } from 'react-native';
 import PropTypes from 'prop-types';
 import {withOnyx} from 'react-native-onyx';
-import _ from 'underscore';
-import Text from '../../components/Text';
 import ONYXKEYS from '../../ONYXKEYS';
 import styles from '../../styles/styles';
 import updateUnread from '../../libs/UnreadIndicatorUpdater/updateUnread/index';
@@ -55,7 +53,8 @@ const defaultProps = {
 class SignInPage extends Component {
     componentDidMount() {
         // Always reset the unread counter to zero on this page
-        updateUnread(0);
+        // NOTE: We need to wait for the next tick to ensure that the unread indicator is updated
+        setTimeout(() => updateUnread(0), 0);
     }
 
     render() {
@@ -94,17 +93,6 @@ class SignInPage extends Component {
                         {showPasswordForm && <PasswordForm />}
 
                         {showResendValidationLinkForm && <ResendValidationForm />}
-
-                        {/* Because of the custom layout of the login form, session errors are displayed differently */}
-                        {!showLoginForm && (
-                            <View>
-                                {this.props.account && !_.isEmpty(this.props.account.error) && (
-                                    <Text style={[styles.formError]}>
-                                        {this.props.account.error}
-                                    </Text>
-                                )}
-                            </View>
-                        )}
                     </SignInPageLayout>
                 </SafeAreaView>
             </>
diff --git a/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js b/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js
index 23b169f713b9..475b0a30d613 100755
--- a/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js
+++ b/src/pages/signin/SignInPageLayout/SignInPageLayoutNarrow.js
@@ -1,5 +1,5 @@
 import React from 'react';
-import {ScrollView, View} from 'react-native';
+import {ScrollView, View, KeyboardAvoidingView} from 'react-native';
 import PropTypes from 'prop-types';
 import styles from '../../../styles/styles';
 import variables from '../../../styles/variables';
@@ -21,38 +21,40 @@ const propTypes = {
 const SignInPageLayoutNarrow = props => (
     <ScrollView
         keyboardShouldPersistTaps="handled"
-        contentContainerStyle={[
+        showsVerticalScrollIndicator={false}
+        style={[
             styles.flexGrow1,
-            styles.pb5,
             styles.mh5,
             styles.signInPageNarrowContentContainer,
             styles.alignSelfCenter,
         ]}
     >
-        <View style={[styles.flexGrow1]}>
-            <View
-                style={[
-                    styles.signInPageInnerNative,
-                    styles.flex1,
-                    styles.dFlex,
-                    styles.flexColumn,
-                    props.windowHeight > props.windowWidth ? styles.mt40Percentage : null,
-                ]}
-            >
-                <View style={[styles.signInPageLogoNative, styles.mb2]}>
-                    <ExpensifyCashLogo
-                        width={variables.componentSizeLarge}
-                        height={variables.componentSizeLarge}
-                    />
+        <KeyboardAvoidingView behavior="position">
+            <View style={[styles.flexGrow1]}>
+                <View
+                    style={[
+                        styles.signInPageInnerNative,
+                        styles.flex1,
+                        styles.dFlex,
+                        styles.flexColumn,
+                        props.windowHeight > props.windowWidth ? styles.mt40Percentage : null,
+                    ]}
+                >
+                    <View style={[styles.signInPageLogoNative, styles.mb2]}>
+                        <ExpensifyCashLogo
+                            width={variables.componentSizeLarge}
+                            height={variables.componentSizeLarge}
+                        />
+                    </View>
+                    <Text style={[styles.mv5, styles.textLabel, styles.h3]}>
+                        {props.translate('welcomeText.phrase1')}
+                    </Text>
+                    {props.children}
                 </View>
-                <Text style={[styles.mv5, styles.textLabel, styles.h3]}>
-                    {props.translate('welcomeText.phrase1')}
-                </Text>
-                {props.children}
-            </View>
-            <View style={[styles.mt3]}>
-                <TermsAndLicenses />
             </View>
+        </KeyboardAvoidingView>
+        <View style={[styles.mt3, styles.mb5, styles.alignSelfCenter]}>
+            <TermsAndLicenses />
         </View>
     </ScrollView>
 );
diff --git a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js
index fa0d4cbed3c6..4ef064130e71 100644
--- a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js
+++ b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.android.js
@@ -7,12 +7,10 @@ import withLocalize, {
     withLocalizePropTypes,
 } from '../../../../components/withLocalize';
 import LogoWordmark from '../../../../../assets/images/expensify-wordmark.svg';
+import LocalePicker from '../../../../components/LocalePicker';
 
 const TermsWithLicenses = ({translate}) => (
     <View>
-        <View style={[styles.mt1, styles.alignItemsCenter, styles.mb3]}>
-            <LogoWordmark height={30} width={80} />
-        </View>
         <View
             style={[
                 styles.dFlex,
@@ -20,7 +18,6 @@ const TermsWithLicenses = ({translate}) => (
                 styles.flexWrap,
                 styles.textAlignCenter,
                 styles.alignItemsCenter,
-                styles.justifyContentCenter,
             ]}
         >
             <Text style={[styles.textAlignCenter, styles.loginTermsText]}>
@@ -61,6 +58,12 @@ const TermsWithLicenses = ({translate}) => (
             </TextLink>
             <Text style={[styles.textAlignCenter, styles.loginTermsText]}>.</Text>
         </View>
+        <View style={[
+            styles.mt4, styles.alignItemsCenter, styles.mb2, styles.flexRow, styles.justifyContentBetween]}
+        >
+            <LogoWordmark height={30} width={80} />
+            <LocalePicker size="small" />
+        </View>
     </View>
 );
 
diff --git a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js
index 720c89434bf3..f884c94d7d8e 100644
--- a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js
+++ b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.ios.js
@@ -7,19 +7,16 @@ import withLocalize, {
     withLocalizePropTypes,
 } from '../../../../components/withLocalize';
 import LogoWordmark from '../../../../../assets/images/expensify-wordmark.svg';
+import LocalePicker from '../../../../components/LocalePicker';
 
 const TermsWithLicenses = ({translate}) => (
     <View>
-        <View style={[styles.mt1, styles.alignItemsCenter, styles.mb3]}>
-            <LogoWordmark height={30} width={80} />
-        </View>
         <View
             style={[
                 styles.dFlex,
                 styles.flexColumn,
                 styles.flexWrap,
                 styles.textAlignCenter,
-                styles.alignItemsCenter,
                 styles.justifyContentCenter,
             ]}
         >
@@ -67,6 +64,12 @@ const TermsWithLicenses = ({translate}) => (
                 <Text style={[styles.textAlignCenter, styles.loginTermsText]}>.</Text>
             </View>
         </View>
+        <View style={[
+            styles.mt4, styles.alignItemsCenter, styles.mb2, styles.flexRow, styles.justifyContentBetween]}
+        >
+            <LogoWordmark height={30} width={80} />
+            <LocalePicker size="small" />
+        </View>
     </View>
 );
 
diff --git a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js
index 175bda985afc..a022e771f31b 100755
--- a/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js
+++ b/src/pages/signin/TermsAndLicenses/TermsWithLicenses/index.js
@@ -7,13 +7,11 @@ import withLocalize, {
     withLocalizePropTypes,
 } from '../../../../components/withLocalize';
 import LogoWordmark from '../../../../../assets/images/expensify-wordmark.svg';
+import LocalePicker from '../../../../components/LocalePicker';
 
 const TermsWithLicenses = ({translate}) => (
     <View>
-        <View style={[styles.mt1, styles.alignItemsCenter, styles.mb3]}>
-            <LogoWordmark height={30} width={80} />
-        </View>
-        <Text style={[styles.textAlignCenter, styles.loginTermsText]}>
+        <Text style={[styles.loginTermsText]}>
             {translate('termsOfUse.phrase1')}
             {' '}
             <TextLink
@@ -45,6 +43,10 @@ const TermsWithLicenses = ({translate}) => (
             </TextLink>
             .
         </Text>
+        <View style={[styles.mt4, styles.alignItemsCenter, styles.mb2, styles.flexRow, styles.justifyContentBetween]}>
+            <LogoWordmark height={30} width={80} />
+            <LocalePicker size="small" />
+        </View>
     </View>
 );
 
diff --git a/src/pages/workspace/PublicWorkspaceNewView.js b/src/pages/workspace/PublicWorkspaceNewView.js
index fa0ac88b4420..3d4a62f581a7 100644
--- a/src/pages/workspace/PublicWorkspaceNewView.js
+++ b/src/pages/workspace/PublicWorkspaceNewView.js
@@ -1,8 +1,7 @@
 import React from 'react';
-import Onyx from 'react-native-onyx';
 import PropTypes from 'prop-types';
-import ONYXKEYS from '../../ONYXKEYS';
 import SCREENS from '../../SCREENS';
+import {setRedirectToWorkspaceNewAfterSignIn} from '../../libs/actions/Session';
 
 const propTypes = {
     /** react-navigation navigation object available to screen components */
@@ -14,7 +13,7 @@ const propTypes = {
 
 class PublicWorkspaceNewView extends React.PureComponent {
     componentDidMount() {
-        Onyx.merge(ONYXKEYS.SESSION, {redirectToWorkspaceNewAfterSignIn: true});
+        setRedirectToWorkspaceNewAfterSignIn(true);
         this.props.navigation.replace(SCREENS.HOME);
     }
 
diff --git a/src/pages/workspace/WorkspaceCardPage.js b/src/pages/workspace/WorkspaceCardPage.js
index 98f18de11873..b77f05efce9f 100644
--- a/src/pages/workspace/WorkspaceCardPage.js
+++ b/src/pages/workspace/WorkspaceCardPage.js
@@ -20,12 +20,16 @@ import themeDefault from '../../styles/themes/default';
 import ROUTES from '../../ROUTES';
 import CONFIG from '../../CONFIG';
 import CONST from '../../CONST';
+import Permissions from '../../libs/Permissions';
 import HeroCardWebImage from '../../../assets/images/cascading-cards-web.svg';
 import HeroCardMobileImage from '../../../assets/images/cascading-cards-mobile.svg';
 
 const propTypes = {
     /* Onyx Props */
 
+    /** Beta features list */
+    betas: PropTypes.arrayOf(PropTypes.string).isRequired,
+
     /** The details about the user that is signed in */
     user: PropTypes.shape({
         /** Whether or not the user has public domain */
@@ -65,6 +69,7 @@ const publicLink = CONFIG.EXPENSIFY.URL_EXPENSIFY_COM + CONST.ADD_SECONDARY_LOGI
 const manageCardLink = CONFIG.EXPENSIFY.URL_EXPENSIFY_COM + CONST.MANAGE_CARDS_URL;
 
 const WorkspaceCardPage = ({
+    betas,
     user,
     translate,
     isSmallScreenWidth,
@@ -92,6 +97,11 @@ const WorkspaceCardPage = ({
         }
     };
 
+    if (!Permissions.canUseFreePlan(betas)) {
+        console.debug('Not showing workspace card page because user is not on free plan beta');
+        return <Navigation.DismissModal />;
+    }
+
     return (
         <ScreenWrapper style={[styles.defaultModalContainer]}>
             <HeaderWithCloseButton
@@ -193,5 +203,8 @@ export default compose(
         reimbursementAccount: {
             key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
         },
+        betas: {
+            key: ONYXKEYS.BETAS,
+        },
     }),
 )(WorkspaceCardPage);
diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js
index 577df15669c9..cd107c43c84a 100644
--- a/src/pages/workspace/WorkspaceInvitePage.js
+++ b/src/pages/workspace/WorkspaceInvitePage.js
@@ -15,7 +15,6 @@ import compose from '../../libs/compose';
 import ONYXKEYS from '../../ONYXKEYS';
 import {invite} from '../../libs/actions/Policy';
 import TextLink from '../../components/TextLink';
-import getEmailKeyboardType from '../../libs/getEmailKeyboardType';
 import themeColors from '../../styles/themes/default';
 import Growl from '../../libs/Growl';
 import FixedFooter from '../../components/FixedFooter';
@@ -107,7 +106,6 @@ class WorkspaceInvitePage extends React.Component {
                                 autoCapitalize="none"
                                 style={[styles.textInput]}
                                 value={this.state.userLogins}
-                                keyboardType={getEmailKeyboardType()}
                                 onChangeText={text => this.setState({userLogins: text})}
                             />
                         </View>
diff --git a/src/pages/workspace/WorkspacePeoplePage.js b/src/pages/workspace/WorkspacePeoplePage.js
index abbcd2c81d35..a396454083fe 100644
--- a/src/pages/workspace/WorkspacePeoplePage.js
+++ b/src/pages/workspace/WorkspacePeoplePage.js
@@ -21,6 +21,7 @@ import Text from '../../components/Text';
 import ROUTES from '../../ROUTES';
 import ConfirmModal from '../../components/ConfirmModal';
 import personalDetailsPropType from '../personalDetailsPropType';
+import Permissions from '../../libs/Permissions';
 import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions';
 import OptionRow from '../home/sidebar/OptionRow';
 
@@ -29,6 +30,9 @@ const propTypes = {
 
     ...windowDimensionsPropTypes,
 
+    /** List of betas */
+    betas: PropTypes.arrayOf(PropTypes.string).isRequired,
+
     /** The personal details of the person who is logged in */
     personalDetails: personalDetailsPropType.isRequired,
 
@@ -204,6 +208,10 @@ class WorkspacePeoplePage extends React.Component {
     }
 
     render() {
+        if (!Permissions.canUseFreePlan(this.props.betas)) {
+            console.debug('Not showing workspace people page because user is not on free plan beta');
+            return <Navigation.DismissModal />;
+        }
         const policyEmployeeList = lodashGet(this.props, 'policy.employeeList', []);
         const data = _.chain(policyEmployeeList)
             .map(email => this.props.personalDetails[email])
@@ -285,5 +293,8 @@ export default compose(
         session: {
             key: ONYXKEYS.SESSION,
         },
+        betas: {
+            key: ONYXKEYS.BETAS,
+        },
     }),
 )(WorkspacePeoplePage);
diff --git a/src/styles/styles.js b/src/styles/styles.js
index 22555cd975ab..7311fe1818e7 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -340,6 +340,64 @@ const styles = {
         },
     },
 
+    pickerSmall: {
+        inputIOS: {
+            fontFamily: fontFamily.GTA,
+            fontSize: variables.fontSizeSmall,
+            paddingLeft: 9,
+            paddingRight: 25,
+            paddingTop: 6,
+            paddingBottom: 6,
+            borderRadius: variables.componentBorderRadius,
+            borderWidth: 1,
+            borderColor: themeColors.border,
+            color: themeColors.text,
+            height: variables.componentSizeSmall,
+            opacity: 1,
+            backgroundColor: 'transparent',
+        },
+        inputWeb: {
+            fontFamily: fontFamily.GTA,
+            fontSize: variables.fontSizeSmall,
+            paddingLeft: 9,
+            paddingRight: 25,
+            paddingTop: 6,
+            paddingBottom: 6,
+            borderWidth: 1,
+            borderRadius: variables.componentBorderRadius,
+            borderColor: themeColors.border,
+            color: themeColors.text,
+            appearance: 'none',
+            height: variables.componentSizeSmall,
+            opacity: 1,
+            cursor: 'pointer',
+            backgroundColor: 'transparent',
+        },
+        inputAndroid: {
+            fontFamily: fontFamily.GTA,
+            fontSize: variables.fontSizeSmall,
+            paddingLeft: 9,
+            paddingRight: 25,
+            paddingTop: 6,
+            paddingBottom: 6,
+            borderWidth: 1,
+            borderRadius: variables.componentBorderRadius,
+            borderColor: themeColors.border,
+            color: themeColors.text,
+            height: variables.componentSizeSmall,
+            opacity: 1,
+        },
+        iconContainer: {
+            top: 7,
+            right: 9,
+            pointerEvents: 'none',
+        },
+        icon: {
+            width: variables.iconSizeExtraSmall,
+            height: variables.iconSizeExtraSmall,
+        },
+    },
+
     badge: {
         backgroundColor: themeColors.badgeDefaultBG,
         borderRadius: 14,
@@ -1646,10 +1704,11 @@ const styles = {
     },
 
     hiddenElementOutsideOfWindow: {
-        position: 'absolute',
+        position: 'fixed',
         top: 0,
         left: 0,
         opacity: 0,
+        transform: 'translateX(-100%)',
     },
 
     growlNotificationWrapper: {
@@ -1797,10 +1856,8 @@ const styles = {
         ...whiteSpace.noWrap,
     },
 
-    communicationsLinkIcon: {
-        right: -36,
-        top: 0,
-        bottom: 0,
+    communicationsLinkHeight: {
+        height: 20,
     },
 };
 
