From 055eab10143a8d6d70bb36cab0bfd03b6a140b38 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Tue, 27 Apr 2021 16:57:33 -0700 Subject: [PATCH 01/17] Update urban airship to 11.0.0 --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9b23fbef5be2..c96be8d2a56f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37025,9 +37025,9 @@ } }, "urbanairship-react-native": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urbanairship-react-native/-/urbanairship-react-native-10.0.0.tgz", - "integrity": "sha512-0vJ6K+KnGeB5vJujFzfWXc7x+nFkdELj4TSOBkfW0VfxrQpojIXmOdXt0GHWOUOVTzFj2iA25qkfcSAaImQeGw==" + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/urbanairship-react-native/-/urbanairship-react-native-11.0.0.tgz", + "integrity": "sha512-hYAgzIZPnTzXRV3fh44MtoIaCm2M5ycc50yTxbrtwM+S9EOgLV3SnFD4L/8l+mVZXDU+sjRPY8DWipbCUmG3tA==" }, "uri-js": { "version": "4.4.0", diff --git a/package.json b/package.json index ae815de8d14d..91f1fe304033 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "rn-fetch-blob": "^0.12.0", "save": "^2.4.0", "underscore": "^1.10.2", - "urbanairship-react-native": "^10.0.0" + "urbanairship-react-native": "^11.0.0" }, "devDependencies": { "@actions/core": "^1.2.6", From e57688b85f9723ecb3d2c8837eeec5e725f49283 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 20 May 2021 00:12:43 -0700 Subject: [PATCH 02/17] Setup draft local push notification implementation --- ios/ExpensifyCash.xcodeproj/project.pbxproj | 260 +++++++++--------- ios/ExpensifyCash/AppDelegate.m | 43 +++ ios/Podfile.lock | 32 ++- package-lock.json | 13 + package.json | 2 + .../LocalNotification/BrowserNotifications.js | 13 +- .../NotificationGenerator.js | 24 ++ .../LocalNotification/index.native.js | 95 ++++++- 8 files changed, 328 insertions(+), 154 deletions(-) create mode 100644 src/libs/Notification/LocalNotification/NotificationGenerator.js diff --git a/ios/ExpensifyCash.xcodeproj/project.pbxproj b/ios/ExpensifyCash.xcodeproj/project.pbxproj index 088ecf088fc2..b2a326dfb8f3 100644 --- a/ios/ExpensifyCash.xcodeproj/project.pbxproj +++ b/ios/ExpensifyCash.xcodeproj/project.pbxproj @@ -24,11 +24,11 @@ 70CF6E82262E297300711ADC /* BootSplash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 70CF6E81262E297300711ADC /* BootSplash.storyboard */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 8821A238A081483FA947BC4E /* GTAmericaExp-RgIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 918D7FEFF96242E6B5F5E14D /* GTAmericaExp-RgIt.otf */; }; - 8C86654500DCC843A74147B5 /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2AB27DDDFCCE3CD100EA0C /* libPods-ExpensifyCash-ExpensifyCashTests.a */; }; - BB6CECBDA023256B6B955321 /* libPods-ExpensifyCash.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F2C8BDCC1FF0B64AE2DFC9B /* libPods-ExpensifyCash.a */; }; DB77016704074197AB6633BB /* GTAmericaExpMono-RgIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5150E5D0D7F74DBA8D7C1914 /* GTAmericaExpMono-RgIt.otf */; }; + E27E544276A2B4A39CEF499B /* libPods-ExpensifyCash.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FCA1D898923C5F88D253A7D5 /* libPods-ExpensifyCash.a */; }; E9DF872D2525201700607FDC /* AirshipConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = E9DF872C2525201700607FDC /* AirshipConfig.plist */; }; ED814D34526B415CAFA0451E /* GTAmericaExpMono-BdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3981452A2C7340EBBA2B9BD1 /* GTAmericaExpMono-BdIt.otf */; }; + FD7481720644FF1DF848EF34 /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69EC64EBD43DD980A28442D9 /* libPods-ExpensifyCash-ExpensifyCashTests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -46,6 +46,7 @@ 00E356EE1AD99517003FC87E /* ExpensifyCashTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExpensifyCashTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* ExpensifyCashTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExpensifyCashTests.m; sourceTree = ""; }; + 05409C3757E1292EF1EB9940 /* Pods-ExpensifyCash.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.release.xcconfig"; sourceTree = ""; }; 0DE5D096095C41EE96746C9E /* GTAmericaExpMono-Bd.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-Bd.otf"; path = "../assets/fonts/GTAmericaExpMono-Bd.otf"; sourceTree = ""; }; 0F5BE0CD252686320097D869 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* Expensify.cash.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Expensify.cash.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -54,28 +55,27 @@ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ExpensifyCash/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ExpensifyCash/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ExpensifyCash/main.m; sourceTree = ""; }; + 1E0B23B9EFFD3DF878D874A7 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; sourceTree = ""; }; 3981452A2C7340EBBA2B9BD1 /* GTAmericaExpMono-BdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-BdIt.otf"; path = "../assets/fonts/GTAmericaExpMono-BdIt.otf"; sourceTree = ""; }; 5150E5D0D7F74DBA8D7C1914 /* GTAmericaExpMono-RgIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-RgIt.otf"; path = "../assets/fonts/GTAmericaExpMono-RgIt.otf"; sourceTree = ""; }; 67D5C3A6A7FA417C8A853FC1 /* GTAmericaExp-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Light.otf"; path = "../assets/fonts/GTAmericaExp-Light.otf"; sourceTree = ""; }; - 6F2C8BDCC1FF0B64AE2DFC9B /* libPods-ExpensifyCash.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 69EC64EBD43DD980A28442D9 /* libPods-ExpensifyCash-ExpensifyCashTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash-ExpensifyCashTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 70CF6E81262E297300711ADC /* BootSplash.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = BootSplash.storyboard; path = ExpensifyCash/BootSplash.storyboard; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = ExpensifyCash/LaunchScreen.storyboard; sourceTree = ""; }; 8437A5A38F2047E0BCCD7C2F /* GTAmericaExpMono-Rg.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-Rg.otf"; path = "../assets/fonts/GTAmericaExpMono-Rg.otf"; sourceTree = ""; }; 8C7003903C1E4957824899BB /* GTAmericaExp-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Regular.otf"; path = "../assets/fonts/GTAmericaExp-Regular.otf"; sourceTree = ""; }; 918D7FEFF96242E6B5F5E14D /* GTAmericaExp-RgIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-RgIt.otf"; path = "../assets/fonts/GTAmericaExp-RgIt.otf"; sourceTree = ""; }; - A13EE2CFAF952F935D201D2F /* Pods-ExpensifyCash.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.release.xcconfig"; sourceTree = ""; }; + 9235FD3550ECA389C6306012 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; sourceTree = ""; }; A292718541C841859D97DF2F /* GTAmericaExp-Thin.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Thin.otf"; path = "../assets/fonts/GTAmericaExp-Thin.otf"; sourceTree = ""; }; A5AAD008CBD84A6CAEB9AC97 /* GTAmericaExp-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Bold.otf"; path = "../assets/fonts/GTAmericaExp-Bold.otf"; sourceTree = ""; }; A8D6F2F722FD4E66A38EBBB6 /* GTAmericaExp-BdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-BdIt.otf"; path = "../assets/fonts/GTAmericaExp-BdIt.otf"; sourceTree = ""; }; AE65058949E14DA5A2D5435D /* GTAmericaExp-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Medium.otf"; path = "../assets/fonts/GTAmericaExp-Medium.otf"; sourceTree = ""; }; - AF728B3FCBC8C2731C4DA7B4 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; sourceTree = ""; }; DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-MdIt.otf"; path = "../assets/fonts/GTAmericaExp-MdIt.otf"; sourceTree = ""; }; - E7967C67752432EA2031954F /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; sourceTree = ""; }; E9DF872C2525201700607FDC /* AirshipConfig.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AirshipConfig.plist; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; - ED2AB27DDDFCCE3CD100EA0C /* libPods-ExpensifyCash-ExpensifyCashTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash-ExpensifyCashTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - F4BC0E78FF1E9BD8B2D38C66 /* Pods-ExpensifyCash.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.debug.xcconfig"; sourceTree = ""; }; + FCA1D898923C5F88D253A7D5 /* libPods-ExpensifyCash.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + FE2F222A24641331CF55435F /* Pods-ExpensifyCash.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -83,7 +83,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8C86654500DCC843A74147B5 /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */, + FD7481720644FF1DF848EF34 /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -91,7 +91,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - BB6CECBDA023256B6B955321 /* libPods-ExpensifyCash.a in Frameworks */, + E27E544276A2B4A39CEF499B /* libPods-ExpensifyCash.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -137,8 +137,8 @@ children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED2971642150620600B7C4FE /* JavaScriptCore.framework */, - 6F2C8BDCC1FF0B64AE2DFC9B /* libPods-ExpensifyCash.a */, - ED2AB27DDDFCCE3CD100EA0C /* libPods-ExpensifyCash-ExpensifyCashTests.a */, + FCA1D898923C5F88D253A7D5 /* libPods-ExpensifyCash.a */, + 69EC64EBD43DD980A28442D9 /* libPods-ExpensifyCash-ExpensifyCashTests.a */, ); name = Frameworks; sourceTree = ""; @@ -197,10 +197,10 @@ EC29677F0A49C2946A495A33 /* Pods */ = { isa = PBXGroup; children = ( - F4BC0E78FF1E9BD8B2D38C66 /* Pods-ExpensifyCash.debug.xcconfig */, - A13EE2CFAF952F935D201D2F /* Pods-ExpensifyCash.release.xcconfig */, - AF728B3FCBC8C2731C4DA7B4 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */, - E7967C67752432EA2031954F /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */, + FE2F222A24641331CF55435F /* Pods-ExpensifyCash.debug.xcconfig */, + 05409C3757E1292EF1EB9940 /* Pods-ExpensifyCash.release.xcconfig */, + 1E0B23B9EFFD3DF878D874A7 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */, + 9235FD3550ECA389C6306012 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -212,12 +212,12 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ExpensifyCashTests" */; buildPhases = ( - AEFD4743761AD0E2373D0494 /* [CP] Check Pods Manifest.lock */, + CC9B40A4B06F1C3249593697 /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - F2B8013B9E9ECAB2B509E702 /* [CP] Copy Pods Resources */, - 97ED3CCB9FD5A5A2AB20CC03 /* [CP] Embed Pods Frameworks */, + A4EA632E96952340E0E4D405 /* [CP] Embed Pods Frameworks */, + 721407845DD1DAB922607458 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -233,16 +233,16 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ExpensifyCash" */; buildPhases = ( - 6A9F4436BADC311F14A4349F /* [CP] Check Pods Manifest.lock */, + BCBE7AF862BE1E3610376CC0 /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - C9071365B664DE0D85DC5195 /* [CP] Copy Pods Resources */, - CF6259710B5A341870372EA2 /* [CP-User] [RNFB] Core Configuration */, - ED5B8E90A3384FC6A128FB95 /* [CP-User] [RNFB] Crashlytics Configuration */, - DBBB399CCB345652E314C5BC /* [CP] Embed Pods Frameworks */, + 86BC79682CD81C4569299B32 /* [CP] Embed Pods Frameworks */, + 002D8DA867E61436951CF83F /* [CP] Copy Pods Resources */, + 69E81293CFEA3638C919AAFC /* [CP-User] [RNFB] Core Configuration */, + D2487DCEE7DEDD4183EBAC81 /* [CP-User] [RNFB] Crashlytics Configuration */, ); buildRules = ( ); @@ -327,85 +327,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Bundle React Native code and images"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; - }; - 6A9F4436BADC311F14A4349F /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ExpensifyCash-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 97ED3CCB9FD5A5A2AB20CC03 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh", - "${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}/OpenSSL.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LinkKit.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - AEFD4743761AD0E2373D0494 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ExpensifyCash-ExpensifyCashTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - C9071365B664DE0D85DC5195 /* [CP] Copy Pods Resources */ = { + 002D8DA867E61436951CF83F /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -533,47 +455,31 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-resources.sh\"\n"; showEnvVarsInLog = 0; }; - CF6259710B5A341870372EA2 /* [CP-User] [RNFB] Core Configuration */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - name = "[CP-User] [RNFB] Core Configuration"; - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\n_MAX_LOOKUPS=2;\n_SEARCH_RESULT=''\n_RN_ROOT_EXISTS=''\n_CURRENT_LOOKUPS=1\n_JSON_ROOT=\"'react-native'\"\n_JSON_FILE_NAME='firebase.json'\n_JSON_OUTPUT_BASE64='e30=' # { }\n_CURRENT_SEARCH_DIR=${PROJECT_DIR}\n_PLIST_BUDDY=/usr/libexec/PlistBuddy\n_TARGET_PLIST=\"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\"\n_DSYM_PLIST=\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"\n\n# plist arrays\n_PLIST_ENTRY_KEYS=()\n_PLIST_ENTRY_TYPES=()\n_PLIST_ENTRY_VALUES=()\n\nfunction setPlistValue {\n echo \"info: setting plist entry '$1' of type '$2' in file '$4'\"\n ${_PLIST_BUDDY} -c \"Add :$1 $2 '$3'\" $4 || echo \"info: '$1' already exists\"\n}\n\nfunction getFirebaseJsonKeyValue () {\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$1'); puts output[$_JSON_ROOT]['$2']\"\n else\n echo \"\"\n fi;\n}\n\nfunction jsonBoolToYesNo () {\n if [[ $1 == \"false\" ]]; then\n echo \"NO\"\n elif [[ $1 == \"true\" ]]; then\n echo \"YES\"\n else echo \"NO\"\n fi\n}\n\necho \"info: -> RNFB build script started\"\necho \"info: 1) Locating ${_JSON_FILE_NAME} file:\"\n\nif [[ -z ${_CURRENT_SEARCH_DIR} ]]; then\n _CURRENT_SEARCH_DIR=$(pwd)\nfi;\n\nwhile true; do\n _CURRENT_SEARCH_DIR=$(dirname \"$_CURRENT_SEARCH_DIR\")\n if [[ \"$_CURRENT_SEARCH_DIR\" == \"/\" ]] || [[ ${_CURRENT_LOOKUPS} -gt ${_MAX_LOOKUPS} ]]; then break; fi;\n echo \"info: ($_CURRENT_LOOKUPS of $_MAX_LOOKUPS) Searching in '$_CURRENT_SEARCH_DIR' for a ${_JSON_FILE_NAME} file.\"\n _SEARCH_RESULT=$(find \"$_CURRENT_SEARCH_DIR\" -maxdepth 2 -name ${_JSON_FILE_NAME} -print | head -n 1)\n if [[ ${_SEARCH_RESULT} ]]; then\n echo \"info: ${_JSON_FILE_NAME} found at $_SEARCH_RESULT\"\n break;\n fi;\n _CURRENT_LOOKUPS=$((_CURRENT_LOOKUPS+1))\ndone\n\nif [[ ${_SEARCH_RESULT} ]]; then\n _JSON_OUTPUT_RAW=$(cat \"${_SEARCH_RESULT}\")\n _RN_ROOT_EXISTS=$(ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$_JSON_OUTPUT_RAW'); puts output[$_JSON_ROOT]\" || echo '')\n\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n _JSON_OUTPUT_BASE64=$(python -c 'import json,sys,base64;print(base64.b64encode(json.dumps(json.loads(open('\"'${_SEARCH_RESULT}'\"').read())['${_JSON_ROOT}'])))' || echo \"e30=\")\n fi\n\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n\n # config.messaging_auto_init_enabled\n _MESSAGING_AUTO_INIT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"messaging_auto_init_enabled\")\n if [[ $_MESSAGING_AUTO_INIT ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseMessagingAutoInitEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_MESSAGING_AUTO_INIT\")\")\n fi\n\n # config.crashlytics_disable_auto_disabler - undocumented for now - mainly for debugging, document if becomes useful\n _CRASHLYTICS_AUTO_DISABLE_ENABLED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"crashlytics_disable_auto_disabler\")\n if [[ $_CRASHLYTICS_AUTO_DISABLE_ENABLED == \"true\" ]]; then\n echo \"Disabled Crashlytics auto disabler.\" # do nothing\n else\n _PLIST_ENTRY_KEYS+=(\"FirebaseCrashlyticsCollectionEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"NO\")\n fi\n\n # config.admob_delay_app_measurement_init\n _ADMOB_DELAY_APP_MEASUREMENT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_delay_app_measurement_init\")\n if [[ $_ADMOB_DELAY_APP_MEASUREMENT == \"true\" ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADDelayAppMeasurementInit\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"YES\")\n fi\n\n # config.admob_ios_app_id\n _ADMOB_IOS_APP_ID=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_ios_app_id\")\n if [[ $_ADMOB_IOS_APP_ID ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADApplicationIdentifier\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_ADMOB_IOS_APP_ID\")\n fi\nelse\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n echo \"warning: A firebase.json file was not found, whilst this file is optional it is recommended to include it to configure firebase services in React Native Firebase.\"\nfi;\n\necho \"info: 2) Injecting Info.plist entries: \"\n\n# Log out the keys we're adding\nfor i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n echo \" -> $i) ${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\"\ndone\n\nfor plist in \"${_TARGET_PLIST}\" \"${_DSYM_PLIST}\" ; do\n if [[ -f \"${plist}\" ]]; then\n\n # paths with spaces break the call to setPlistValue. temporarily modify\n # the shell internal field separator variable (IFS), which normally\n # includes spaces, to consist only of line breaks\n oldifs=$IFS\n IFS=\"\n\"\n\n for i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n setPlistValue \"${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\" \"${plist}\"\n done\n\n # restore the original internal field separator value\n IFS=$oldifs\n else\n echo \"warning: A Info.plist build output file was not found (${plist})\"\n fi\ndone\n\necho \"info: <- RNFB build script finished\"\n"; - }; - DBBB399CCB345652E314C5BC /* [CP] Embed Pods Frameworks */ = { + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/LinkKit/LinkKit.framework/LinkKit", ); - name = "[CP] Embed Pods Frameworks"; + name = "Bundle React Native code and images"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LinkKit.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; }; - ED5B8E90A3384FC6A128FB95 /* [CP-User] [RNFB] Crashlytics Configuration */ = { + 69E81293CFEA3638C919AAFC /* [CP-User] [RNFB] Core Configuration */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - name = "[CP-User] [RNFB] Crashlytics Configuration"; + name = "[CP-User] [RNFB] Core Configuration"; runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\nif [[ ${PODS_ROOT} ]]; then\n echo \"info: Exec FirebaseCrashlytics Run from Pods\"\n \"${PODS_ROOT}/FirebaseCrashlytics/run\"\nelse\n echo \"info: Exec FirebaseCrashlytics Run from framework\"\n \"${PROJECT_DIR}/FirebaseCrashlytics.framework/run\"\nfi\n"; + shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\n_MAX_LOOKUPS=2;\n_SEARCH_RESULT=''\n_RN_ROOT_EXISTS=''\n_CURRENT_LOOKUPS=1\n_JSON_ROOT=\"'react-native'\"\n_JSON_FILE_NAME='firebase.json'\n_JSON_OUTPUT_BASE64='e30=' # { }\n_CURRENT_SEARCH_DIR=${PROJECT_DIR}\n_PLIST_BUDDY=/usr/libexec/PlistBuddy\n_TARGET_PLIST=\"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\"\n_DSYM_PLIST=\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"\n\n# plist arrays\n_PLIST_ENTRY_KEYS=()\n_PLIST_ENTRY_TYPES=()\n_PLIST_ENTRY_VALUES=()\n\nfunction setPlistValue {\n echo \"info: setting plist entry '$1' of type '$2' in file '$4'\"\n ${_PLIST_BUDDY} -c \"Add :$1 $2 '$3'\" $4 || echo \"info: '$1' already exists\"\n}\n\nfunction getFirebaseJsonKeyValue () {\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$1'); puts output[$_JSON_ROOT]['$2']\"\n else\n echo \"\"\n fi;\n}\n\nfunction jsonBoolToYesNo () {\n if [[ $1 == \"false\" ]]; then\n echo \"NO\"\n elif [[ $1 == \"true\" ]]; then\n echo \"YES\"\n else echo \"NO\"\n fi\n}\n\necho \"info: -> RNFB build script started\"\necho \"info: 1) Locating ${_JSON_FILE_NAME} file:\"\n\nif [[ -z ${_CURRENT_SEARCH_DIR} ]]; then\n _CURRENT_SEARCH_DIR=$(pwd)\nfi;\n\nwhile true; do\n _CURRENT_SEARCH_DIR=$(dirname \"$_CURRENT_SEARCH_DIR\")\n if [[ \"$_CURRENT_SEARCH_DIR\" == \"/\" ]] || [[ ${_CURRENT_LOOKUPS} -gt ${_MAX_LOOKUPS} ]]; then break; fi;\n echo \"info: ($_CURRENT_LOOKUPS of $_MAX_LOOKUPS) Searching in '$_CURRENT_SEARCH_DIR' for a ${_JSON_FILE_NAME} file.\"\n _SEARCH_RESULT=$(find \"$_CURRENT_SEARCH_DIR\" -maxdepth 2 -name ${_JSON_FILE_NAME} -print | head -n 1)\n if [[ ${_SEARCH_RESULT} ]]; then\n echo \"info: ${_JSON_FILE_NAME} found at $_SEARCH_RESULT\"\n break;\n fi;\n _CURRENT_LOOKUPS=$((_CURRENT_LOOKUPS+1))\ndone\n\nif [[ ${_SEARCH_RESULT} ]]; then\n _JSON_OUTPUT_RAW=$(cat \"${_SEARCH_RESULT}\")\n _RN_ROOT_EXISTS=$(ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$_JSON_OUTPUT_RAW'); puts output[$_JSON_ROOT]\" || echo '')\n\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n _JSON_OUTPUT_BASE64=$(python -c 'import json,sys,base64;print(base64.b64encode(json.dumps(json.loads(open('\"'${_SEARCH_RESULT}'\"').read())['${_JSON_ROOT}'])))' || echo \"e30=\")\n fi\n\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n\n # config.messaging_auto_init_enabled\n _MESSAGING_AUTO_INIT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"messaging_auto_init_enabled\")\n if [[ $_MESSAGING_AUTO_INIT ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseMessagingAutoInitEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_MESSAGING_AUTO_INIT\")\")\n fi\n\n # config.crashlytics_disable_auto_disabler - undocumented for now - mainly for debugging, document if becomes useful\n _CRASHLYTICS_AUTO_DISABLE_ENABLED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"crashlytics_disable_auto_disabler\")\n if [[ $_CRASHLYTICS_AUTO_DISABLE_ENABLED == \"true\" ]]; then\n echo \"Disabled Crashlytics auto disabler.\" # do nothing\n else\n _PLIST_ENTRY_KEYS+=(\"FirebaseCrashlyticsCollectionEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"NO\")\n fi\n\n # config.admob_delay_app_measurement_init\n _ADMOB_DELAY_APP_MEASUREMENT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_delay_app_measurement_init\")\n if [[ $_ADMOB_DELAY_APP_MEASUREMENT == \"true\" ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADDelayAppMeasurementInit\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"YES\")\n fi\n\n # config.admob_ios_app_id\n _ADMOB_IOS_APP_ID=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_ios_app_id\")\n if [[ $_ADMOB_IOS_APP_ID ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADApplicationIdentifier\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_ADMOB_IOS_APP_ID\")\n fi\nelse\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n echo \"warning: A firebase.json file was not found, whilst this file is optional it is recommended to include it to configure firebase services in React Native Firebase.\"\nfi;\n\necho \"info: 2) Injecting Info.plist entries: \"\n\n# Log out the keys we're adding\nfor i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n echo \" -> $i) ${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\"\ndone\n\nfor plist in \"${_TARGET_PLIST}\" \"${_DSYM_PLIST}\" ; do\n if [[ -f \"${plist}\" ]]; then\n\n # paths with spaces break the call to setPlistValue. temporarily modify\n # the shell internal field separator variable (IFS), which normally\n # includes spaces, to consist only of line breaks\n oldifs=$IFS\n IFS=\"\n\"\n\n for i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n setPlistValue \"${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\" \"${plist}\"\n done\n\n # restore the original internal field separator value\n IFS=$oldifs\n else\n echo \"warning: A Info.plist build output file was not found (${plist})\"\n fi\ndone\n\necho \"info: <- RNFB build script finished\"\n"; }; - F2B8013B9E9ECAB2B509E702 /* [CP] Copy Pods Resources */ = { + 721407845DD1DAB922607458 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -701,6 +607,100 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 86BC79682CD81C4569299B32 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh", + "${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}/OpenSSL.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LinkKit.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A4EA632E96952340E0E4D405 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh", + "${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}/OpenSSL.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LinkKit.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + BCBE7AF862BE1E3610376CC0 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ExpensifyCash-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + CC9B40A4B06F1C3249593697 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ExpensifyCash-ExpensifyCashTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + D2487DCEE7DEDD4183EBAC81 /* [CP-User] [RNFB] Crashlytics Configuration */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + name = "[CP-User] [RNFB] Crashlytics Configuration"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\nif [[ ${PODS_ROOT} ]]; then\n echo \"info: Exec FirebaseCrashlytics Run from Pods\"\n \"${PODS_ROOT}/FirebaseCrashlytics/run\"\nelse\n echo \"info: Exec FirebaseCrashlytics Run from framework\"\n \"${PROJECT_DIR}/FirebaseCrashlytics.framework/run\"\nfi\n"; + }; FD10A7F022414F080027D42C /* Start Packager */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -753,7 +753,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AF728B3FCBC8C2731C4DA7B4 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */; + baseConfigurationReference = 1E0B23B9EFFD3DF878D874A7 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -777,7 +777,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E7967C67752432EA2031954F /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */; + baseConfigurationReference = 9235FD3550ECA389C6306012 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -799,7 +799,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4BC0E78FF1E9BD8B2D38C66 /* Pods-ExpensifyCash.debug.xcconfig */; + baseConfigurationReference = FE2F222A24641331CF55435F /* Pods-ExpensifyCash.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -831,7 +831,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A13EE2CFAF952F935D201D2F /* Pods-ExpensifyCash.release.xcconfig */; + baseConfigurationReference = 05409C3757E1292EF1EB9940 /* Pods-ExpensifyCash.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; diff --git a/ios/ExpensifyCash/AppDelegate.m b/ios/ExpensifyCash/AppDelegate.m index 0138f2b3cc4c..32cc01376947 100644 --- a/ios/ExpensifyCash/AppDelegate.m +++ b/ios/ExpensifyCash/AppDelegate.m @@ -9,6 +9,33 @@ #import "RNBootSplash.h" #import +#import + +/*=== START react-native-push-notification-ios configs ===*/ +// Required for the register event. +- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken +{ + [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; +} +// Required for the notification event. You must call the completion handler after handling the remote notification. +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo +fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler +{ + [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; +} +// Required for the registrationError event. +- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error +{ + [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error]; +} +// Required for localNotification event +- (void)userNotificationCenter:(UNUserNotificationCenter *)center +didReceiveNotificationResponse:(UNNotificationResponse *)response + withCompletionHandler:(void (^)(void))completionHandler +{ + [RNCPushNotificationIOS didReceiveNotificationResponse:response]; +} +/*=== END react-native-push-notification-ios configs ===*/ #ifdef FB_SONARKIT_ENABLED #import @@ -86,4 +113,20 @@ - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull N restorationHandler:restorationHandler]; } +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + ... + // Define UNUserNotificationCenter + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + center.delegate = self; + + return YES; +} + +//Called when a notification is delivered to a foreground app. +-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler +{ + completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge); +} + @end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6b4061284d47..9b4c2b8d3486 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,15 +1,15 @@ PODS: - - Airship (14.2.0): - - Airship/Automation (= 14.2.0) - - Airship/Core (= 14.2.0) - - Airship/ExtendedActions (= 14.2.0) - - Airship/MessageCenter (= 14.2.0) - - Airship/Automation (14.2.0): + - Airship (14.3.0): + - Airship/Automation (= 14.3.0) + - Airship/Core (= 14.3.0) + - Airship/ExtendedActions (= 14.3.0) + - Airship/MessageCenter (= 14.3.0) + - Airship/Automation (14.3.0): - Airship/Core - - Airship/Core (14.2.0) - - Airship/ExtendedActions (14.2.0): + - Airship/Core (14.3.0) + - Airship/ExtendedActions (14.3.0): - Airship/Core - - Airship/MessageCenter (14.2.0): + - Airship/MessageCenter (14.3.0): - Airship/Core - boost-for-react-native (1.63.0) - CocoaAsyncSocket (7.6.5) @@ -412,6 +412,8 @@ PODS: - React - RNCPicker (1.9.11): - React-Core + - RNCPushNotificationIOS (1.8.0): + - React-Core - RNFBAnalytics (7.6.8): - Firebase/Analytics (~> 6.34.0) - React-Core @@ -431,8 +433,8 @@ PODS: - React-Core - RNSVG (12.1.0): - React - - urbanairship-react-native (10.0.0): - - Airship (= 14.2.0) + - urbanairship-react-native (11.0.0): + - Airship (= 14.3.0) - React-Core - Yoga (1.14.0) - YogaKit (1.18.1): @@ -501,6 +503,7 @@ DEPENDENCIES: - "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" - "RNCPicker (from `../node_modules/@react-native-picker/picker`)" + - "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)" - "RNFBAnalytics (from `../node_modules/@react-native-firebase/analytics`)" - "RNFBApp (from `../node_modules/@react-native-firebase/app`)" - "RNFBCrashlytics (from `../node_modules/@react-native-firebase/crashlytics`)" @@ -620,6 +623,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/masked-view" RNCPicker: :path: "../node_modules/@react-native-picker/picker" + RNCPushNotificationIOS: + :path: "../node_modules/@react-native-community/push-notification-ios" RNFBAnalytics: :path: "../node_modules/@react-native-firebase/analytics" RNFBApp: @@ -640,7 +645,7 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - Airship: 02ad73780f9eed21870e36b0aaab327acda6a102 + Airship: 7609d263d3a207f112d6db066af5852b80af6819 boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: cde416483dac037923206447da6e1454df403714 @@ -704,6 +709,7 @@ SPEC CHECKSUMS: RNCClipboard: 5e299c6df8e0c98f3d7416b86ae563d3a9f768a3 RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459 RNCPicker: 6780c753e9e674065db90d9c965920516402579d + RNCPushNotificationIOS: 5b1cf9ad2aaa107ecb92d5d2d7005ba521b2b97a RNFBAnalytics: 2dc4dd9e2445faffca041b10447a23a71dcdabf8 RNFBApp: 7eacc7da7ab19f96c05e434017d44a9f09410da8 RNFBCrashlytics: 4870c14cf8833053b6b5648911abefe1923854d2 @@ -711,7 +717,7 @@ SPEC CHECKSUMS: RNReanimated: e03f7425cb7a38dcf1b644d680d1bfc91c3337ad RNScreens: b6c9607e6fe47c1b6e2f1910d2acd46dd7ecea3a RNSVG: ce9d996113475209013317e48b05c21ee988d42e - urbanairship-react-native: dfb6dc22b2f41ccaadd636b73d51b448cd1b2bbc + urbanairship-react-native: 041199e7f52d81fc0a5426176998f84d039c98dd Yoga: 7d13633d129fd179e01b8953d38d47be90db185a YogaKit: f782866e155069a2cca2517aafea43200b01fd5a diff --git a/package-lock.json b/package-lock.json index c96be8d2a56f..acc37a98c654 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5744,6 +5744,14 @@ "resolved": "https://registry.npmjs.org/@react-native-community/progress-view/-/progress-view-1.2.3.tgz", "integrity": "sha512-CW7eOhxduIxA723aZlKMOnBEz1o5Cjo5ibMNsf81TcjNqtsamRHm8jFS98za7t5P7XdhM0MhzkbaS90cwOlN+Q==" }, + "@react-native-community/push-notification-ios": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@react-native-community/push-notification-ios/-/push-notification-ios-1.8.0.tgz", + "integrity": "sha512-vxvkeampafjmtDoQBN8Q4azP21l6cMX93+OQZemyIWZmG++OjCVDQVitobf/kWLm5zyGwdylejbpMGo75qo7rA==", + "requires": { + "invariant": "^2.2.4" + } + }, "@react-native-firebase/analytics": { "version": "7.6.8", "resolved": "https://registry.npmjs.org/@react-native-firebase/analytics/-/analytics-7.6.8.tgz", @@ -32777,6 +32785,11 @@ "tsc": "^1.20150623.0" } }, + "react-native-push-notification": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/react-native-push-notification/-/react-native-push-notification-7.3.1.tgz", + "integrity": "sha512-5kSKPvDU23uZRmzgKTsGhbwGNvB2tidu1VnInBHP53ZD0VEPSBl5fbpuTfHH98ED+Gp1SCcT2/e6bJWkIspKvg==" + }, "react-native-reanimated": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-1.13.2.tgz", diff --git a/package.json b/package.json index 91f1fe304033..2de6fc800105 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@react-native-community/netinfo": "^5.9.10", "@react-native-community/progress-bar-android": "^1.0.4", "@react-native-community/progress-view": "^1.2.3", + "@react-native-community/push-notification-ios": "^1.8.0", "@react-native-firebase/analytics": "^7.6.7", "@react-native-firebase/app": "^8.4.5", "@react-native-firebase/crashlytics": "^8.4.9", @@ -83,6 +84,7 @@ "react-native-pdf": "^6.2.2", "react-native-picker-select": "8.0.4", "react-native-plaid-link-sdk": "^7.0.5", + "react-native-push-notification": "^7.3.1", "react-native-reanimated": "1.13.2", "react-native-render-html": "^6.0.0-alpha.10", "react-native-safe-area-context": "^3.1.4", diff --git a/src/libs/Notification/LocalNotification/BrowserNotifications.js b/src/libs/Notification/LocalNotification/BrowserNotifications.js index f5e128d3eec1..5f75ca90a8ed 100644 --- a/src/libs/Notification/LocalNotification/BrowserNotifications.js +++ b/src/libs/Notification/LocalNotification/BrowserNotifications.js @@ -1,7 +1,7 @@ // Web and desktop implementation only. Do not import for direct use. Use LocalNotification. -import Str from 'expensify-common/lib/str'; import Onyx from 'react-native-onyx'; import focusApp from './focusApp'; +import NotificationGenerator from './NotificationGenerator'; import EXPENSIFY_ICON_URL from '../../../../assets/images/expensify-logo-round-clearspace.png'; import ONYXKEYS from '../../../ONYXKEYS'; @@ -106,15 +106,10 @@ export default { * @param {Function} params.onClick */ pushReportCommentNotification({reportAction, onClick}) { - const {person, message} = reportAction; - const plainTextPerson = Str.htmlDecode(person.map(f => f.text).join()); - - // Specifically target the comment part of the message - const plainTextMessage = Str.htmlDecode((message.find(f => f.type === 'COMMENT') || {}).text); - + const {title, message} = NotificationGenerator.getReportActionNotificationPayload(reportAction); push({ - title: `New message from ${plainTextPerson}`, - body: plainTextMessage, + title, + body: message, delay: 0, onClick, }); diff --git a/src/libs/Notification/LocalNotification/NotificationGenerator.js b/src/libs/Notification/LocalNotification/NotificationGenerator.js new file mode 100644 index 000000000000..4d3a5cc98f4c --- /dev/null +++ b/src/libs/Notification/LocalNotification/NotificationGenerator.js @@ -0,0 +1,24 @@ +import Str from 'expensify-common/lib/str'; + +/** + * Process a reportAction to get a notification payload. + * + * @param {Object} reportAction + * @returns {Object} + */ +function getReportActionNotificationPayload(reportAction) { + const {person, message} = reportAction; + const plainTextPerson = Str.htmlDecode(person.map(f => f.text).join()); + + // Specifically target the comment part of the message + const plainTextMessage = Str.htmlDecode((message.find(f => f.type === 'COMMENT') || {}).text); + + return { + title: `New message from ${plainTextPerson}`, + message: plainTextMessage, + }; +} + +export default { + getReportActionNotificationPayload, +}; diff --git a/src/libs/Notification/LocalNotification/index.native.js b/src/libs/Notification/LocalNotification/index.native.js index bbc4f48744b6..eb5a794a53a9 100644 --- a/src/libs/Notification/LocalNotification/index.native.js +++ b/src/libs/Notification/LocalNotification/index.native.js @@ -1,5 +1,96 @@ -// Local Notifications are not currently supported on mobile so we'll just noop here. +import PushNotification from 'react-native-push-notification'; +import NotificationGenerator from './NotificationGenerator'; + +const notificationQueue = []; +let currentlyProcessingNotification = null; +let onNotification = () => {}; +let channelInitialized = false; + +PushNotification.configure({onNotification}); + +/** + * Get the local notification channel (required for Android) + * + * @returns {String} – The channel ID + * @throws {Error} – If the channel could not be initialized. + */ +function getChannel() { + const CHANNEL_ID = 'local_push_notification'; + if (channelInitialized) { + return CHANNEL_ID; + } + + PushNotification.createChannel( + { + channelId: CHANNEL_ID, + channelName: CHANNEL_ID, + }, + (created) => { + if (created) { + channelInitialized = true; + console.debug(`[LOCAL_NOTIFICATION] Local notification channel ${CHANNEL_ID} initialized`); + return CHANNEL_ID; + } + + // Channel not initialized + throw new Error('Local notification channel not initialized'); + }, + ); +} + +/** + * Process the notification queue. + */ +function processQueue() { + currentlyProcessingNotification = notificationQueue.shift(); + if (currentlyProcessingNotification) { + const {notification, handler} = this.current; + + // Bind notification event handler, if it exists + onNotification = handler || (() => {}); + + // Trigger local push notification + PushNotification.localNotification({ + channelId: getChannel(), + ...notification, + }); + + // Continue to process notification queue + processQueue(); + } +} + +/** + * Add a new notification to the queue and start processing the queue if necessary. + * + * @param {Object} notification + * @param {Function} handler + */ +function queueNotification(notification, handler) { + // Add notification to the queue + notificationQueue.push({notification, handler}); + + // Begin processing the queue if it is not already processing + if (!currentlyProcessingNotification) { + processQueue(); + } +} + +/** + * Create a report comment notification + * + * @param {Object} params + * @param {Object} params.reportAction + * @param {Function} params.onClick + */ +// TODO: maybe rename this from onClick to something more generic, maybe just onPress? +function showCommentNotification({reportAction, onClick}) { + queueNotification(NotificationGenerator.getReportActionNotificationPayload(reportAction), onClick); +} + export default { - showCommentNotification: () => {}, + showCommentNotification, + + // This notification is unused on iOS/Android showUpdateAvailableNotification: () => {}, }; From e5a366c8344b6ffc96059ace8650f4aa760cd049 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 20 May 2021 00:15:52 -0700 Subject: [PATCH 03/17] Rename getReportActionNotificationPayload --- .../Notification/LocalNotification/BrowserNotifications.js | 2 +- .../Notification/LocalNotification/NotificationGenerator.js | 4 ++-- src/libs/Notification/LocalNotification/index.native.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/Notification/LocalNotification/BrowserNotifications.js b/src/libs/Notification/LocalNotification/BrowserNotifications.js index 5f75ca90a8ed..471b35155a40 100644 --- a/src/libs/Notification/LocalNotification/BrowserNotifications.js +++ b/src/libs/Notification/LocalNotification/BrowserNotifications.js @@ -106,7 +106,7 @@ export default { * @param {Function} params.onClick */ pushReportCommentNotification({reportAction, onClick}) { - const {title, message} = NotificationGenerator.getReportActionNotificationPayload(reportAction); + const {title, message} = NotificationGenerator.getReportCommentNotificationPayload(reportAction); push({ title, body: message, diff --git a/src/libs/Notification/LocalNotification/NotificationGenerator.js b/src/libs/Notification/LocalNotification/NotificationGenerator.js index 4d3a5cc98f4c..e3e1d5affdd0 100644 --- a/src/libs/Notification/LocalNotification/NotificationGenerator.js +++ b/src/libs/Notification/LocalNotification/NotificationGenerator.js @@ -6,7 +6,7 @@ import Str from 'expensify-common/lib/str'; * @param {Object} reportAction * @returns {Object} */ -function getReportActionNotificationPayload(reportAction) { +function getReportCommentNotificationPayload(reportAction) { const {person, message} = reportAction; const plainTextPerson = Str.htmlDecode(person.map(f => f.text).join()); @@ -20,5 +20,5 @@ function getReportActionNotificationPayload(reportAction) { } export default { - getReportActionNotificationPayload, + getReportCommentNotificationPayload, }; diff --git a/src/libs/Notification/LocalNotification/index.native.js b/src/libs/Notification/LocalNotification/index.native.js index eb5a794a53a9..f5f3ab7a0ccf 100644 --- a/src/libs/Notification/LocalNotification/index.native.js +++ b/src/libs/Notification/LocalNotification/index.native.js @@ -85,7 +85,7 @@ function queueNotification(notification, handler) { */ // TODO: maybe rename this from onClick to something more generic, maybe just onPress? function showCommentNotification({reportAction, onClick}) { - queueNotification(NotificationGenerator.getReportActionNotificationPayload(reportAction), onClick); + queueNotification(NotificationGenerator.getReportCommentNotificationPayload(reportAction), onClick); } export default { From 2128f870dcc0e27e1593026d999ba3ae0c66f712 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 20 May 2021 00:18:25 -0700 Subject: [PATCH 04/17] Update processQueue JSDoc --- src/libs/Notification/LocalNotification/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Notification/LocalNotification/index.native.js b/src/libs/Notification/LocalNotification/index.native.js index f5f3ab7a0ccf..f06241e873ae 100644 --- a/src/libs/Notification/LocalNotification/index.native.js +++ b/src/libs/Notification/LocalNotification/index.native.js @@ -39,7 +39,7 @@ function getChannel() { } /** - * Process the notification queue. + * Process the notification queue recursively. */ function processQueue() { currentlyProcessingNotification = notificationQueue.shift(); From 4ecd1e6508570af98bb83ab965617f043c996166 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 20 May 2021 00:33:29 -0700 Subject: [PATCH 05/17] Add a comment explaining why a queue is needed --- .../LocalNotification/index.native.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libs/Notification/LocalNotification/index.native.js b/src/libs/Notification/LocalNotification/index.native.js index f06241e873ae..5f3e5882b162 100644 --- a/src/libs/Notification/LocalNotification/index.native.js +++ b/src/libs/Notification/LocalNotification/index.native.js @@ -1,6 +1,25 @@ import PushNotification from 'react-native-push-notification'; import NotificationGenerator from './NotificationGenerator'; +/* + * Note: react-native-push-notification uses a single global event handler for `onNotification`. + * So in order to provide an API similar to that of BrowserNotifications, + * where we can simply pass a payload and an `onPress` callback, we need to process each notification by: + * + * 1. Setting the global `onNotification` event handler to be the `onPress` callback for the given notification. + * 2. Triggering the local push notification. + * 3. Resetting the global `onNotification` event handler. + * + * That's why we need to process notifications in a queue – otherwise we could produce the following race condition: + * + * 1. A notification + callback is dispatched (call it X) + * 2. We set the global `onNotification` event handler to be X.onPress + * 3. Another notification + callback is dispatched (call it Y) + * 4. We set the global `onNotification` event handler to be Y.onPress + * 5. X.notification is displayed. + * 6. The user taps X.notification, and Y.onPress is executed. 😵 + */ + const notificationQueue = []; let currentlyProcessingNotification = null; let onNotification = () => {}; From 156d31ffaae8049eba1be4bff6eda96faf5de1e4 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 20 May 2021 00:38:06 -0700 Subject: [PATCH 06/17] Add throws to JSDocs --- src/libs/Notification/LocalNotification/index.native.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/Notification/LocalNotification/index.native.js b/src/libs/Notification/LocalNotification/index.native.js index 5f3e5882b162..2b7ea46821f8 100644 --- a/src/libs/Notification/LocalNotification/index.native.js +++ b/src/libs/Notification/LocalNotification/index.native.js @@ -59,6 +59,8 @@ function getChannel() { /** * Process the notification queue recursively. + * + * @throws {Error} */ function processQueue() { currentlyProcessingNotification = notificationQueue.shift(); @@ -84,6 +86,7 @@ function processQueue() { * * @param {Object} notification * @param {Function} handler + * @throws {Error} */ function queueNotification(notification, handler) { // Add notification to the queue @@ -101,6 +104,7 @@ function queueNotification(notification, handler) { * @param {Object} params * @param {Object} params.reportAction * @param {Function} params.onClick + * @throws {Error} */ // TODO: maybe rename this from onClick to something more generic, maybe just onPress? function showCommentNotification({reportAction, onClick}) { From f7138443f33a9684666f805ce5543abf612ff887 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 20 May 2021 11:15:01 -0700 Subject: [PATCH 07/17] Create cross-platform LocalNotificationService lib --- .../LocalNotification/BrowserNotifications.js | 131 ------------------ .../LocalNotification/LocalNotification.js | 26 ++++ .../LocalNotificationService/index.js | 72 ++++++++++ .../LocalNotificationService/index.native.js | 101 ++++++++++++++ .../NotificationGenerator.js | 30 +++- .../Notification/LocalNotification/index.js | 21 ++- .../LocalNotification/index.native.js | 107 +------------- 7 files changed, 245 insertions(+), 243 deletions(-) delete mode 100644 src/libs/Notification/LocalNotification/BrowserNotifications.js create mode 100644 src/libs/Notification/LocalNotification/LocalNotification.js create mode 100644 src/libs/Notification/LocalNotification/LocalNotificationService/index.js create mode 100644 src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js diff --git a/src/libs/Notification/LocalNotification/BrowserNotifications.js b/src/libs/Notification/LocalNotification/BrowserNotifications.js deleted file mode 100644 index 471b35155a40..000000000000 --- a/src/libs/Notification/LocalNotification/BrowserNotifications.js +++ /dev/null @@ -1,131 +0,0 @@ -// Web and desktop implementation only. Do not import for direct use. Use LocalNotification. -import Onyx from 'react-native-onyx'; -import focusApp from './focusApp'; -import NotificationGenerator from './NotificationGenerator'; -import EXPENSIFY_ICON_URL from '../../../../assets/images/expensify-logo-round-clearspace.png'; -import ONYXKEYS from '../../../ONYXKEYS'; - -const DEFAULT_DELAY = 4000; - -/** - * Checks if the user has granted permission to show browser notifications - * - * @return {Promise} - */ -function canUseBrowserNotifications() { - return new Promise((resolve) => { - // They have no browser notifications so we can't use this feature - if (!window.Notification) { - return resolve(false); - } - - // Check if they previously granted or denied us access to send a notification - const permissionGranted = Notification.permission === 'granted'; - - if (permissionGranted || Notification.permission === 'denied') { - return resolve(permissionGranted); - } - - // Check their global preferences for browser notifications and ask permission if they have none - Notification.requestPermission() - .then((status) => { - resolve(status === 'granted'); - }); - }); -} - -/** - * Light abstraction around browser push notifications. - * Checks for permission before determining whether to send. - * - * @param {Object} params - * @param {String} params.title - * @param {String} params.body - * @param {String} [params.icon] Default to Expensify logo - * @param {Number} [params.delay] - * @param {Function} [params.onClick] - * @param {String} [params.tag] - * - * @return {Promise} - resolves with Notification object or undefined - */ -function push({ - title, - body, - delay = DEFAULT_DELAY, - onClick = () => {}, - tag = '', - icon = EXPENSIFY_ICON_URL, -}) { - return new Promise((resolve) => { - if (!title || !body) { - throw new Error('BrowserNotification must include title and body parameter.'); - } - - canUseBrowserNotifications().then((canUseNotifications) => { - if (!canUseNotifications) { - resolve(); - return; - } - - const notification = new Notification(title, { - body, - icon, - tag, - }); - - // If we pass in a delay param greater than 0 the notification - // will auto-close after the specified time. - if (delay > 0) { - setTimeout(notification.close.bind(notification), delay); - } - - notification.onclick = (event) => { - event.preventDefault(); - onClick(); - window.parent.focus(); - window.focus(); - focusApp(); - notification.close(); - }; - - resolve(notification); - }); - }); -} - -/** - * BrowserNotification - * @namespace - */ -export default { - /** - * Create a report comment notification - * - * @param {Object} params - * @param {Object} params.reportAction - * @param {Function} params.onClick - */ - pushReportCommentNotification({reportAction, onClick}) { - const {title, message} = NotificationGenerator.getReportCommentNotificationPayload(reportAction); - push({ - title, - body: message, - delay: 0, - onClick, - }); - }, - - /** - * Create a notification to indicate that an update is available. - */ - pushUpdateAvailableNotification() { - push({ - title: 'Update available', - body: 'A new version of Expensify.cash is available!', - delay: 0, - onClick: () => { - Onyx.merge(ONYXKEYS.UPDATE_AVAILABLE, true); - }, - }); - }, -}; diff --git a/src/libs/Notification/LocalNotification/LocalNotification.js b/src/libs/Notification/LocalNotification/LocalNotification.js new file mode 100644 index 000000000000..793a9def4c6a --- /dev/null +++ b/src/libs/Notification/LocalNotification/LocalNotification.js @@ -0,0 +1,26 @@ +import EXPENSIFY_ICON_URL from '../../../../assets/images/expensify-logo-round-clearspace.png'; + +export default class LocalNotification { + /** + * Create a Notification object. + * + * @param {String} title + * @param {String} message + * @param {Function} [onPress] + * @param {String} [icon] + * @param {Number} [hideAfter] + * @param {String} [tag] + */ + constructor(title, message, onPress = () => {}, icon = EXPENSIFY_ICON_URL, hideAfter = 0, tag = '') { + if (!title || !message) { + throw new Error('LocalNotification must include title and message parameter.'); + } + + this.title = title; + this.message = message; + this.onPress = onPress; + this.icon = icon; + this.hideAfter = hideAfter; + this.tag = tag; + } +} diff --git a/src/libs/Notification/LocalNotification/LocalNotificationService/index.js b/src/libs/Notification/LocalNotification/LocalNotificationService/index.js new file mode 100644 index 000000000000..913bcc498977 --- /dev/null +++ b/src/libs/Notification/LocalNotification/LocalNotificationService/index.js @@ -0,0 +1,72 @@ +import LocalNotification from '../LocalNotification'; +import focusApp from '../focusApp'; + +/** + * Checks if the user has granted permission to show browser notifications + * + * @return {Promise} + */ +function canUseBrowserNotifications() { + return new Promise((resolve) => { + // They have no browser notifications so we can't use this feature + if (!window.Notification) { + return resolve(false); + } + + // Check if they previously granted or denied us access to send a notification + const permissionGranted = Notification.permission === 'granted'; + + if (permissionGranted || Notification.permission === 'denied') { + return resolve(permissionGranted); + } + + // Check their global preferences for browser notifications and ask permission if they have none + Notification.requestPermission() + .then((status) => { + resolve(status === 'granted'); + }); + }); +} + +/** + * Light abstraction around browser push notifications. + * Checks for permission before determining whether to send. + * + * @param {LocalNotification} notification + */ +function queueNotification(notification) { + if (!(notification instanceof LocalNotification)) { + throw new Error('Attempting to queue invalid LocalNotification'); + } + + canUseBrowserNotifications().then((canUseNotifications) => { + if (!canUseNotifications) { + return; + } + + const browserNotification = new Notification(notification.title, { + body: notification.message, + icon: notification.icon, + tag: notification.tag, + }); + + // If we pass in a delay param greater than 0 the notification + // will auto-close after the specified time. + if (notification.hideAfter > 0) { + setTimeout(browserNotification.close.bind(browserNotification), notification.hideAfter); + } + + browserNotification.onclick = (event) => { + event.preventDefault(); + notification.onPress(); + window.parent.focus(); + window.focus(); + focusApp(); + browserNotification.close(); + }; + }); +} + +export default { + queueNotification, +}; diff --git a/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js b/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js new file mode 100644 index 000000000000..64e3beef3067 --- /dev/null +++ b/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js @@ -0,0 +1,101 @@ +import PushNotification from 'react-native-push-notification'; +import LocalNotification from '../LocalNotification'; + +/* + * Note: react-native-push-notification uses a single global event handler for `onNotification`. + * So in order to provide an API similar to that of BrowserNotifications, + * where we can simply pass a payload and an `onPress` callback, we need to process each notification by: + * + * 1. Setting the global `onNotification` event handler to be the `onPress` callback for the given notification. + * 2. Triggering the local push notification. + * 3. Resetting the global `onNotification` event handler. + * + * That's why we need to process notifications in a queue – otherwise we could produce the following race condition: + * + * 1. A notification + callback is dispatched (call it X) + * 2. We set the global `onNotification` event handler to be X.onPress + * 3. Another notification + callback is dispatched (call it Y) + * 4. We set the global `onNotification` event handler to be Y.onPress + * 5. X.notification is displayed. + * 6. The user taps X.notification, and Y.onPress is executed. 😵 + */ + +const notificationQueue = []; +let currentlyProcessingNotification = null; +let onNotification = () => {}; +let channelInitialized = false; + +PushNotification.configure({onNotification}); + +/** + * Get the local notification channel (required for Android) + * + * @returns {String} – The channel ID + * @throws {Error} – If the channel could not be initialized. + */ +function getChannel() { + const CHANNEL_ID = 'local_push_notification'; + if (channelInitialized) { + return CHANNEL_ID; + } + + PushNotification.createChannel( + { + channelId: CHANNEL_ID, + channelName: CHANNEL_ID, + }, + (created) => { + if (created) { + channelInitialized = true; + console.debug(`[LOCAL_NOTIFICATION] Local notification channel ${CHANNEL_ID} initialized`); + return CHANNEL_ID; + } + + // Channel not initialized + throw new Error('Local notification channel not initialized'); + }, + ); +} + +/** + * Process the notification queue recursively. + * + * @throws {Error} + */ +function processQueue() { + currentlyProcessingNotification = notificationQueue.shift(); + if (currentlyProcessingNotification) { + // Bind notification event handler + onNotification = currentlyProcessingNotification.onPress; + + // Trigger local push notification + PushNotification.localNotification({ + channelId: getChannel(), + title: currentlyProcessingNotification.title, + message: currentlyProcessingNotification.message, + }); + + // Continue to process notification queue + processQueue(); + } +} + +/** + * Add a new notification to the queue and start processing the queue if necessary. + * + * @param {LocalNotification} notification + * @throws {Error} + */ +export default function queueNotification(notification) { + if (!(notification instanceof LocalNotification)) { + throw new Error('Attempting to queue invalid LocalNotification'); + } + + // Add notification to the queue + notificationQueue.push(notification); + + // Begin processing the queue if it is not already processing + if (!currentlyProcessingNotification) { + processQueue(); + } +} diff --git a/src/libs/Notification/LocalNotification/NotificationGenerator.js b/src/libs/Notification/LocalNotification/NotificationGenerator.js index e3e1d5affdd0..2302f5380fd0 100644 --- a/src/libs/Notification/LocalNotification/NotificationGenerator.js +++ b/src/libs/Notification/LocalNotification/NotificationGenerator.js @@ -1,24 +1,42 @@ +import Onyx from 'react-native-onyx'; import Str from 'expensify-common/lib/str'; +import LocalNotification from './LocalNotification'; +import ONYXKEYS from '../../../ONYXKEYS'; /** * Process a reportAction to get a notification payload. * * @param {Object} reportAction - * @returns {Object} + * @param {Function} onPress + * @returns {LocalNotification} */ -function getReportCommentNotificationPayload(reportAction) { +function getReportCommentNotificationPayload(reportAction, onPress) { const {person, message} = reportAction; const plainTextPerson = Str.htmlDecode(person.map(f => f.text).join()); // Specifically target the comment part of the message const plainTextMessage = Str.htmlDecode((message.find(f => f.type === 'COMMENT') || {}).text); - return { - title: `New message from ${plainTextPerson}`, - message: plainTextMessage, - }; + return new LocalNotification(`New message from ${plainTextPerson}`, plainTextMessage, onPress); +} + +/** + * Generate the update available notification. + * + * @returns {LocalNotification} + */ +function getUpdateAvailableNotification() { + return new LocalNotification( + 'Update available', + 'A new version of Expensify.cash is available!', + 0, + () => { + Onyx.merge(ONYXKEYS.UPDATE_AVAILABLE, true); + }, + ); } export default { getReportCommentNotificationPayload, + getUpdateAvailableNotification, }; diff --git a/src/libs/Notification/LocalNotification/index.js b/src/libs/Notification/LocalNotification/index.js index 9564b0ef7f26..6015c735a897 100644 --- a/src/libs/Notification/LocalNotification/index.js +++ b/src/libs/Notification/LocalNotification/index.js @@ -1,11 +1,24 @@ -import BrowserNotifications from './BrowserNotifications'; +import LocalNotificationService from './LocalNotificationService'; +import NotificationGenerator from './NotificationGenerator'; -function showCommentNotification({reportAction, onClick}) { - BrowserNotifications.pushReportCommentNotification({reportAction, onClick}); +/** + * Send a report comment notification. + * + * @param {Object} params + * @param {Object} params.reportAction + * @param {Function} params.onPress + */ +function showCommentNotification({reportAction, onPress}) { + const commentNotification = NotificationGenerator.getReportCommentNotificationPayload(reportAction, onPress); + LocalNotificationService.queueNotification(commentNotification); } +/** + * Send an update available notification. + */ function showUpdateAvailableNotification() { - BrowserNotifications.pushUpdateAvailableNotification(); + const updateAvailableNotification = NotificationGenerator.getUpdateAvailableNotification(); + LocalNotificationService.queueNotification(updateAvailableNotification); } export default { diff --git a/src/libs/Notification/LocalNotification/index.native.js b/src/libs/Notification/LocalNotification/index.native.js index 2b7ea46821f8..bce07e393576 100644 --- a/src/libs/Notification/LocalNotification/index.native.js +++ b/src/libs/Notification/LocalNotification/index.native.js @@ -1,114 +1,17 @@ -import PushNotification from 'react-native-push-notification'; +import LocalNotificationService from './LocalNotificationService'; import NotificationGenerator from './NotificationGenerator'; -/* - * Note: react-native-push-notification uses a single global event handler for `onNotification`. - * So in order to provide an API similar to that of BrowserNotifications, - * where we can simply pass a payload and an `onPress` callback, we need to process each notification by: - * - * 1. Setting the global `onNotification` event handler to be the `onPress` callback for the given notification. - * 2. Triggering the local push notification. - * 3. Resetting the global `onNotification` event handler. - * - * That's why we need to process notifications in a queue – otherwise we could produce the following race condition: - * - * 1. A notification + callback is dispatched (call it X) - * 2. We set the global `onNotification` event handler to be X.onPress - * 3. Another notification + callback is dispatched (call it Y) - * 4. We set the global `onNotification` event handler to be Y.onPress - * 5. X.notification is displayed. - * 6. The user taps X.notification, and Y.onPress is executed. 😵 - */ - -const notificationQueue = []; -let currentlyProcessingNotification = null; -let onNotification = () => {}; -let channelInitialized = false; - -PushNotification.configure({onNotification}); - -/** - * Get the local notification channel (required for Android) - * - * @returns {String} – The channel ID - * @throws {Error} – If the channel could not be initialized. - */ -function getChannel() { - const CHANNEL_ID = 'local_push_notification'; - if (channelInitialized) { - return CHANNEL_ID; - } - - PushNotification.createChannel( - { - channelId: CHANNEL_ID, - channelName: CHANNEL_ID, - }, - (created) => { - if (created) { - channelInitialized = true; - console.debug(`[LOCAL_NOTIFICATION] Local notification channel ${CHANNEL_ID} initialized`); - return CHANNEL_ID; - } - - // Channel not initialized - throw new Error('Local notification channel not initialized'); - }, - ); -} - -/** - * Process the notification queue recursively. - * - * @throws {Error} - */ -function processQueue() { - currentlyProcessingNotification = notificationQueue.shift(); - if (currentlyProcessingNotification) { - const {notification, handler} = this.current; - - // Bind notification event handler, if it exists - onNotification = handler || (() => {}); - - // Trigger local push notification - PushNotification.localNotification({ - channelId: getChannel(), - ...notification, - }); - - // Continue to process notification queue - processQueue(); - } -} - -/** - * Add a new notification to the queue and start processing the queue if necessary. - * - * @param {Object} notification - * @param {Function} handler - * @throws {Error} - */ -function queueNotification(notification, handler) { - // Add notification to the queue - notificationQueue.push({notification, handler}); - - // Begin processing the queue if it is not already processing - if (!currentlyProcessingNotification) { - processQueue(); - } -} - /** * Create a report comment notification * * @param {Object} params * @param {Object} params.reportAction - * @param {Function} params.onClick + * @param {Function} params.onPress * @throws {Error} */ -// TODO: maybe rename this from onClick to something more generic, maybe just onPress? -function showCommentNotification({reportAction, onClick}) { - queueNotification(NotificationGenerator.getReportCommentNotificationPayload(reportAction), onClick); +function showCommentNotification({reportAction, onPress}) { + const commentNotification = NotificationGenerator.getReportCommentNotificationPayload(reportAction, onPress); + LocalNotificationService.queueNotification(commentNotification); } export default { From 88fb0132d6571f157f6b04bfe97479137e90bea1 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 20 May 2021 11:19:27 -0700 Subject: [PATCH 08/17] DRY up common notifications between platforms --- .../Notification/LocalNotification/common.js | 19 +++++++++++++++++++ .../Notification/LocalNotification/index.js | 15 ++------------- .../LocalNotification/index.native.js | 18 ++---------------- 3 files changed, 23 insertions(+), 29 deletions(-) create mode 100644 src/libs/Notification/LocalNotification/common.js diff --git a/src/libs/Notification/LocalNotification/common.js b/src/libs/Notification/LocalNotification/common.js new file mode 100644 index 000000000000..344c831eddc7 --- /dev/null +++ b/src/libs/Notification/LocalNotification/common.js @@ -0,0 +1,19 @@ +import LocalNotificationService from './LocalNotificationService'; +import NotificationGenerator from './NotificationGenerator'; + +/** + * Create a report comment notification + * + * @param {Object} params + * @param {Object} params.reportAction + * @param {Function} params.onPress + * @throws {Error} + */ +function showCommentNotification({reportAction, onPress}) { + const commentNotification = NotificationGenerator.getReportCommentNotificationPayload(reportAction, onPress); + LocalNotificationService.queueNotification(commentNotification); +} + +export default { + showCommentNotification, +}; diff --git a/src/libs/Notification/LocalNotification/index.js b/src/libs/Notification/LocalNotification/index.js index 6015c735a897..eb602bd5be84 100644 --- a/src/libs/Notification/LocalNotification/index.js +++ b/src/libs/Notification/LocalNotification/index.js @@ -1,17 +1,6 @@ import LocalNotificationService from './LocalNotificationService'; import NotificationGenerator from './NotificationGenerator'; - -/** - * Send a report comment notification. - * - * @param {Object} params - * @param {Object} params.reportAction - * @param {Function} params.onPress - */ -function showCommentNotification({reportAction, onPress}) { - const commentNotification = NotificationGenerator.getReportCommentNotificationPayload(reportAction, onPress); - LocalNotificationService.queueNotification(commentNotification); -} +import commonNotifications from './common'; /** * Send an update available notification. @@ -22,6 +11,6 @@ function showUpdateAvailableNotification() { } export default { - showCommentNotification, + ...commonNotifications, showUpdateAvailableNotification, }; diff --git a/src/libs/Notification/LocalNotification/index.native.js b/src/libs/Notification/LocalNotification/index.native.js index bce07e393576..76fc702351ea 100644 --- a/src/libs/Notification/LocalNotification/index.native.js +++ b/src/libs/Notification/LocalNotification/index.native.js @@ -1,21 +1,7 @@ -import LocalNotificationService from './LocalNotificationService'; -import NotificationGenerator from './NotificationGenerator'; - -/** - * Create a report comment notification - * - * @param {Object} params - * @param {Object} params.reportAction - * @param {Function} params.onPress - * @throws {Error} - */ -function showCommentNotification({reportAction, onPress}) { - const commentNotification = NotificationGenerator.getReportCommentNotificationPayload(reportAction, onPress); - LocalNotificationService.queueNotification(commentNotification); -} +import commonNotifications from './common'; export default { - showCommentNotification, + ...commonNotifications, // This notification is unused on iOS/Android showUpdateAvailableNotification: () => {}, From df0bfac21aeef11666114cc7aa20a122a1ee503d Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Tue, 1 Jun 2021 15:04:30 -0700 Subject: [PATCH 09/17] Reinstall node modules and pods after bad merge --- ios/ExpensifyCash.xcodeproj/project.pbxproj | 148 ++++++++++---------- package-lock.json | 5 +- 2 files changed, 78 insertions(+), 75 deletions(-) diff --git a/ios/ExpensifyCash.xcodeproj/project.pbxproj b/ios/ExpensifyCash.xcodeproj/project.pbxproj index bcb683c206ba..fbff60bbd6b7 100644 --- a/ios/ExpensifyCash.xcodeproj/project.pbxproj +++ b/ios/ExpensifyCash.xcodeproj/project.pbxproj @@ -21,14 +21,14 @@ 1E76D5232522316A005A268F /* GTAmericaExp-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = AE65058949E14DA5A2D5435D /* GTAmericaExp-Medium.otf */; }; 1E76D5242522316A005A268F /* GTAmericaExp-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8C7003903C1E4957824899BB /* GTAmericaExp-Regular.otf */; }; 1E76D5252522316A005A268F /* GTAmericaExp-Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = A292718541C841859D97DF2F /* GTAmericaExp-Thin.otf */; }; - 3807535CE8E56AD76DEF8703 /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EC5C9C2B205FECC0A67CA878 /* libPods-ExpensifyCash-ExpensifyCashTests.a */; }; 425866037F4C482AAB46CB8B /* GTAmericaExp-BdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = A8D6F2F722FD4E66A38EBBB6 /* GTAmericaExp-BdIt.otf */; }; 52477A09739546F4814EA25F /* GTAmericaExpMono-Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0DE5D096095C41EE96746C9E /* GTAmericaExpMono-Bd.otf */; }; 6856B78873B64C44A92E51DB /* GTAmericaExp-MdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */; }; 70CF6E82262E297300711ADC /* BootSplash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 70CF6E81262E297300711ADC /* BootSplash.storyboard */; }; + 7ED278182D8D0A2D2EE1F68E /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F3B0744CFF0430F33EF5377 /* libPods-ExpensifyCash-ExpensifyCashTests.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 8821A238A081483FA947BC4E /* GTAmericaExp-RgIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 918D7FEFF96242E6B5F5E14D /* GTAmericaExp-RgIt.otf */; }; - B4A2C73581BDC3D66F94A3AC /* libPods-ExpensifyCash.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B41FE47F80F455FB6E019B5E /* libPods-ExpensifyCash.a */; }; + 99F435D125FEF7A6B65AB800 /* libPods-ExpensifyCash.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6725D14A585207233601176E /* libPods-ExpensifyCash.a */; }; DB77016704074197AB6633BB /* GTAmericaExpMono-RgIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5150E5D0D7F74DBA8D7C1914 /* GTAmericaExpMono-RgIt.otf */; }; E9DF872D2525201700607FDC /* AirshipConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = E9DF872C2525201700607FDC /* AirshipConfig.plist */; }; ED814D34526B415CAFA0451E /* GTAmericaExpMono-BdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3981452A2C7340EBBA2B9BD1 /* GTAmericaExpMono-BdIt.otf */; }; @@ -60,12 +60,15 @@ 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ExpensifyCash/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ExpensifyCash/main.m; sourceTree = ""; }; 18D050DF262400AF000D658B /* BridgingFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BridgingFile.swift; sourceTree = ""; }; - 1C3425E20B41643777DE7722 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; sourceTree = ""; }; 3981452A2C7340EBBA2B9BD1 /* GTAmericaExpMono-BdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-BdIt.otf"; path = "../assets/fonts/GTAmericaExpMono-BdIt.otf"; sourceTree = ""; }; - 46BF67CDAA47420D541264C2 /* Pods-ExpensifyCash.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.release.xcconfig"; sourceTree = ""; }; + 39F97C08A506D924360431AC /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; sourceTree = ""; }; 5150E5D0D7F74DBA8D7C1914 /* GTAmericaExpMono-RgIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-RgIt.otf"; path = "../assets/fonts/GTAmericaExpMono-RgIt.otf"; sourceTree = ""; }; + 53ADB1B00B8DB25FFF4A451E /* Pods-ExpensifyCash.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.debug.xcconfig"; sourceTree = ""; }; + 6725D14A585207233601176E /* libPods-ExpensifyCash.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 67D5C3A6A7FA417C8A853FC1 /* GTAmericaExp-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Light.otf"; path = "../assets/fonts/GTAmericaExp-Light.otf"; sourceTree = ""; }; 70CF6E81262E297300711ADC /* BootSplash.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = BootSplash.storyboard; path = ExpensifyCash/BootSplash.storyboard; sourceTree = ""; }; + 7F3B0744CFF0430F33EF5377 /* libPods-ExpensifyCash-ExpensifyCashTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash-ExpensifyCashTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 8050C35474CA1229CB67554C /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = ExpensifyCash/LaunchScreen.storyboard; sourceTree = ""; }; 8437A5A38F2047E0BCCD7C2F /* GTAmericaExpMono-Rg.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-Rg.otf"; path = "../assets/fonts/GTAmericaExpMono-Rg.otf"; sourceTree = ""; }; 8C7003903C1E4957824899BB /* GTAmericaExp-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Regular.otf"; path = "../assets/fonts/GTAmericaExp-Regular.otf"; sourceTree = ""; }; @@ -74,12 +77,9 @@ A5AAD008CBD84A6CAEB9AC97 /* GTAmericaExp-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Bold.otf"; path = "../assets/fonts/GTAmericaExp-Bold.otf"; sourceTree = ""; }; A8D6F2F722FD4E66A38EBBB6 /* GTAmericaExp-BdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-BdIt.otf"; path = "../assets/fonts/GTAmericaExp-BdIt.otf"; sourceTree = ""; }; AE65058949E14DA5A2D5435D /* GTAmericaExp-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Medium.otf"; path = "../assets/fonts/GTAmericaExp-Medium.otf"; sourceTree = ""; }; - B41FE47F80F455FB6E019B5E /* libPods-ExpensifyCash.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - CF8C66EE73F9B503DE3E0D58 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; sourceTree = ""; }; DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-MdIt.otf"; path = "../assets/fonts/GTAmericaExp-MdIt.otf"; sourceTree = ""; }; - DDF4204498D793D7FB483440 /* Pods-ExpensifyCash.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.debug.xcconfig"; sourceTree = ""; }; + E5909F0BF549E15008ED6B55 /* Pods-ExpensifyCash.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.release.xcconfig"; sourceTree = ""; }; E9DF872C2525201700607FDC /* AirshipConfig.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AirshipConfig.plist; sourceTree = ""; }; - EC5C9C2B205FECC0A67CA878 /* libPods-ExpensifyCash-ExpensifyCashTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash-ExpensifyCashTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; /* End PBXFileReference section */ @@ -89,7 +89,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3807535CE8E56AD76DEF8703 /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */, + 7ED278182D8D0A2D2EE1F68E /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -97,7 +97,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - B4A2C73581BDC3D66F94A3AC /* libPods-ExpensifyCash.a in Frameworks */, + 99F435D125FEF7A6B65AB800 /* libPods-ExpensifyCash.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -145,8 +145,8 @@ children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED2971642150620600B7C4FE /* JavaScriptCore.framework */, - B41FE47F80F455FB6E019B5E /* libPods-ExpensifyCash.a */, - EC5C9C2B205FECC0A67CA878 /* libPods-ExpensifyCash-ExpensifyCashTests.a */, + 6725D14A585207233601176E /* libPods-ExpensifyCash.a */, + 7F3B0744CFF0430F33EF5377 /* libPods-ExpensifyCash-ExpensifyCashTests.a */, ); name = Frameworks; sourceTree = ""; @@ -206,10 +206,10 @@ EC29677F0A49C2946A495A33 /* Pods */ = { isa = PBXGroup; children = ( - 46BF67CDAA47420D541264C2 /* Pods-ExpensifyCash.release.xcconfig */, - CF8C66EE73F9B503DE3E0D58 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */, - 1C3425E20B41643777DE7722 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */, - DDF4204498D793D7FB483440 /* Pods-ExpensifyCash.debug.xcconfig */, + 53ADB1B00B8DB25FFF4A451E /* Pods-ExpensifyCash.debug.xcconfig */, + E5909F0BF549E15008ED6B55 /* Pods-ExpensifyCash.release.xcconfig */, + 8050C35474CA1229CB67554C /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */, + 39F97C08A506D924360431AC /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -221,12 +221,12 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ExpensifyCashTests" */; buildPhases = ( - 39ECFD0897ADA7A0E34E0C36 /* [CP] Check Pods Manifest.lock */, + 7241C8853C69513E313A7FDA /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - 97ED3CCB9FD5A5A2AB20CC03 /* [CP] Embed Pods Frameworks */, - E3E26870421B0A221D65F7A4 /* [CP] Copy Pods Resources */, + A4C96F28ED55A84C38700A94 /* [CP] Embed Pods Frameworks */, + 51833BCAB48C1B2101B878CC /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -242,16 +242,16 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ExpensifyCash" */; buildPhases = ( - ED5B8E90A3384FC6A128FB95 /* [CP] Check Pods Manifest.lock */, + D83A42087E765A7E30468999 /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - 7466D6D5FFFCE8DCCD1EB333 /* [CP] Copy Pods Resources */, - F928D8F3D996EB54A782A79C /* [CP-User] [RNFB] Core Configuration */, - DA4F8CF5B777BDB8DD1EB45D /* [CP-User] [RNFB] Crashlytics Configuration */, - DBBB399CCB345652E314C5BC /* [CP] Embed Pods Frameworks */, + FDEC6A9E72906AA72F933F6C /* [CP] Embed Pods Frameworks */, + AEAF32E6D064C67701C876D8 /* [CP] Copy Pods Resources */, + 40B8C8914523981F0B7B9B98 /* [CP-User] [RNFB] Core Configuration */, + D93A555AED43E5C954D5D60F /* [CP-User] [RNFB] Crashlytics Configuration */, ); buildRules = ( ); @@ -350,35 +350,23 @@ shellPath = /bin/sh; shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; }; - 39ECFD0897ADA7A0E34E0C36 /* [CP] Check Pods Manifest.lock */ = { + 40B8C8914523981F0B7B9B98 /* [CP-User] [RNFB] Core Configuration */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ExpensifyCash-ExpensifyCashTests-checkManifestLockResult.txt", - ); + name = "[CP-User] [RNFB] Core Configuration"; runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\n_MAX_LOOKUPS=2;\n_SEARCH_RESULT=''\n_RN_ROOT_EXISTS=''\n_CURRENT_LOOKUPS=1\n_JSON_ROOT=\"'react-native'\"\n_JSON_FILE_NAME='firebase.json'\n_JSON_OUTPUT_BASE64='e30=' # { }\n_CURRENT_SEARCH_DIR=${PROJECT_DIR}\n_PLIST_BUDDY=/usr/libexec/PlistBuddy\n_TARGET_PLIST=\"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\"\n_DSYM_PLIST=\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"\n\n# plist arrays\n_PLIST_ENTRY_KEYS=()\n_PLIST_ENTRY_TYPES=()\n_PLIST_ENTRY_VALUES=()\n\nfunction setPlistValue {\n echo \"info: setting plist entry '$1' of type '$2' in file '$4'\"\n ${_PLIST_BUDDY} -c \"Add :$1 $2 '$3'\" $4 || echo \"info: '$1' already exists\"\n}\n\nfunction getFirebaseJsonKeyValue () {\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$1'); puts output[$_JSON_ROOT]['$2']\"\n else\n echo \"\"\n fi;\n}\n\nfunction jsonBoolToYesNo () {\n if [[ $1 == \"false\" ]]; then\n echo \"NO\"\n elif [[ $1 == \"true\" ]]; then\n echo \"YES\"\n else echo \"NO\"\n fi\n}\n\necho \"info: -> RNFB build script started\"\necho \"info: 1) Locating ${_JSON_FILE_NAME} file:\"\n\nif [[ -z ${_CURRENT_SEARCH_DIR} ]]; then\n _CURRENT_SEARCH_DIR=$(pwd)\nfi;\n\nwhile true; do\n _CURRENT_SEARCH_DIR=$(dirname \"$_CURRENT_SEARCH_DIR\")\n if [[ \"$_CURRENT_SEARCH_DIR\" == \"/\" ]] || [[ ${_CURRENT_LOOKUPS} -gt ${_MAX_LOOKUPS} ]]; then break; fi;\n echo \"info: ($_CURRENT_LOOKUPS of $_MAX_LOOKUPS) Searching in '$_CURRENT_SEARCH_DIR' for a ${_JSON_FILE_NAME} file.\"\n _SEARCH_RESULT=$(find \"$_CURRENT_SEARCH_DIR\" -maxdepth 2 -name ${_JSON_FILE_NAME} -print | head -n 1)\n if [[ ${_SEARCH_RESULT} ]]; then\n echo \"info: ${_JSON_FILE_NAME} found at $_SEARCH_RESULT\"\n break;\n fi;\n _CURRENT_LOOKUPS=$((_CURRENT_LOOKUPS+1))\ndone\n\nif [[ ${_SEARCH_RESULT} ]]; then\n _JSON_OUTPUT_RAW=$(cat \"${_SEARCH_RESULT}\")\n _RN_ROOT_EXISTS=$(ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$_JSON_OUTPUT_RAW'); puts output[$_JSON_ROOT]\" || echo '')\n\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n _JSON_OUTPUT_BASE64=$(python -c 'import json,sys,base64;print(base64.b64encode(json.dumps(json.loads(open('\"'${_SEARCH_RESULT}'\"').read())['${_JSON_ROOT}'])))' || echo \"e30=\")\n fi\n\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n\n # config.messaging_auto_init_enabled\n _MESSAGING_AUTO_INIT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"messaging_auto_init_enabled\")\n if [[ $_MESSAGING_AUTO_INIT ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseMessagingAutoInitEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_MESSAGING_AUTO_INIT\")\")\n fi\n\n # config.crashlytics_disable_auto_disabler - undocumented for now - mainly for debugging, document if becomes useful\n _CRASHLYTICS_AUTO_DISABLE_ENABLED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"crashlytics_disable_auto_disabler\")\n if [[ $_CRASHLYTICS_AUTO_DISABLE_ENABLED == \"true\" ]]; then\n echo \"Disabled Crashlytics auto disabler.\" # do nothing\n else\n _PLIST_ENTRY_KEYS+=(\"FirebaseCrashlyticsCollectionEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"NO\")\n fi\n\n # config.admob_delay_app_measurement_init\n _ADMOB_DELAY_APP_MEASUREMENT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_delay_app_measurement_init\")\n if [[ $_ADMOB_DELAY_APP_MEASUREMENT == \"true\" ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADDelayAppMeasurementInit\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"YES\")\n fi\n\n # config.admob_ios_app_id\n _ADMOB_IOS_APP_ID=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_ios_app_id\")\n if [[ $_ADMOB_IOS_APP_ID ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADApplicationIdentifier\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_ADMOB_IOS_APP_ID\")\n fi\nelse\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n echo \"warning: A firebase.json file was not found, whilst this file is optional it is recommended to include it to configure firebase services in React Native Firebase.\"\nfi;\n\necho \"info: 2) Injecting Info.plist entries: \"\n\n# Log out the keys we're adding\nfor i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n echo \" -> $i) ${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\"\ndone\n\nfor plist in \"${_TARGET_PLIST}\" \"${_DSYM_PLIST}\" ; do\n if [[ -f \"${plist}\" ]]; then\n\n # paths with spaces break the call to setPlistValue. temporarily modify\n # the shell internal field separator variable (IFS), which normally\n # includes spaces, to consist only of line breaks\n oldifs=$IFS\n IFS=\"\n\"\n\n for i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n setPlistValue \"${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\" \"${plist}\"\n done\n\n # restore the original internal field separator value\n IFS=$oldifs\n else\n echo \"warning: A Info.plist build output file was not found (${plist})\"\n fi\ndone\n\necho \"info: <- RNFB build script finished\"\n"; }; - 7466D6D5FFFCE8DCCD1EB333 /* [CP] Copy Pods Resources */ = { + 51833BCAB48C1B2101B878CC /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAAutomationActions.plist", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageBannerContentView.xib", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageBannerView.xib", @@ -497,46 +485,38 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 97ED3CCB9FD5A5A2AB20CC03 /* [CP] Embed Pods Frameworks */ = { + 7241C8853C69513E313A7FDA /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/LinkKit/LinkKit.framework/LinkKit", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LinkKit.framework", + "$(DERIVED_FILE_DIR)/Pods-ExpensifyCash-ExpensifyCashTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - DA4F8CF5B777BDB8DD1EB45D /* [CP-User] [RNFB] Crashlytics Configuration */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - name = "[CP-User] [RNFB] Crashlytics Configuration"; - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\nif [[ ${PODS_ROOT} ]]; then\n echo \"info: Exec FirebaseCrashlytics Run from Pods\"\n \"${PODS_ROOT}/FirebaseCrashlytics/run\"\nelse\n echo \"info: Exec FirebaseCrashlytics Run from framework\"\n \"${PROJECT_DIR}/FirebaseCrashlytics.framework/run\"\nfi\n"; - }; - DBBB399CCB345652E314C5BC /* [CP] Embed Pods Frameworks */ = { + A4C96F28ED55A84C38700A94 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh", "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", "${PODS_XCFRAMEWORKS_BUILD_DIR}/LinkKit/LinkKit.framework/LinkKit", ); @@ -547,16 +527,16 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - E3E26870421B0A221D65F7A4 /* [CP] Copy Pods Resources */ = { + AEAF32E6D064C67701C876D8 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-resources.sh", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAAutomationActions.plist", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageBannerContentView.xib", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageBannerView.xib", @@ -675,10 +655,10 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-resources.sh\"\n"; showEnvVarsInLog = 0; }; - ED5B8E90A3384FC6A128FB95 /* [CP] Check Pods Manifest.lock */ = { + D83A42087E765A7E30468999 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -700,15 +680,15 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - F928D8F3D996EB54A782A79C /* [CP-User] [RNFB] Core Configuration */ = { + D93A555AED43E5C954D5D60F /* [CP-User] [RNFB] Crashlytics Configuration */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - name = "[CP-User] [RNFB] Core Configuration"; + name = "[CP-User] [RNFB] Crashlytics Configuration"; runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\n_MAX_LOOKUPS=2;\n_SEARCH_RESULT=''\n_RN_ROOT_EXISTS=''\n_CURRENT_LOOKUPS=1\n_JSON_ROOT=\"'react-native'\"\n_JSON_FILE_NAME='firebase.json'\n_JSON_OUTPUT_BASE64='e30=' # { }\n_CURRENT_SEARCH_DIR=${PROJECT_DIR}\n_PLIST_BUDDY=/usr/libexec/PlistBuddy\n_TARGET_PLIST=\"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\"\n_DSYM_PLIST=\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"\n\n# plist arrays\n_PLIST_ENTRY_KEYS=()\n_PLIST_ENTRY_TYPES=()\n_PLIST_ENTRY_VALUES=()\n\nfunction setPlistValue {\n echo \"info: setting plist entry '$1' of type '$2' in file '$4'\"\n ${_PLIST_BUDDY} -c \"Add :$1 $2 '$3'\" $4 || echo \"info: '$1' already exists\"\n}\n\nfunction getFirebaseJsonKeyValue () {\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$1'); puts output[$_JSON_ROOT]['$2']\"\n else\n echo \"\"\n fi;\n}\n\nfunction jsonBoolToYesNo () {\n if [[ $1 == \"false\" ]]; then\n echo \"NO\"\n elif [[ $1 == \"true\" ]]; then\n echo \"YES\"\n else echo \"NO\"\n fi\n}\n\necho \"info: -> RNFB build script started\"\necho \"info: 1) Locating ${_JSON_FILE_NAME} file:\"\n\nif [[ -z ${_CURRENT_SEARCH_DIR} ]]; then\n _CURRENT_SEARCH_DIR=$(pwd)\nfi;\n\nwhile true; do\n _CURRENT_SEARCH_DIR=$(dirname \"$_CURRENT_SEARCH_DIR\")\n if [[ \"$_CURRENT_SEARCH_DIR\" == \"/\" ]] || [[ ${_CURRENT_LOOKUPS} -gt ${_MAX_LOOKUPS} ]]; then break; fi;\n echo \"info: ($_CURRENT_LOOKUPS of $_MAX_LOOKUPS) Searching in '$_CURRENT_SEARCH_DIR' for a ${_JSON_FILE_NAME} file.\"\n _SEARCH_RESULT=$(find \"$_CURRENT_SEARCH_DIR\" -maxdepth 2 -name ${_JSON_FILE_NAME} -print | head -n 1)\n if [[ ${_SEARCH_RESULT} ]]; then\n echo \"info: ${_JSON_FILE_NAME} found at $_SEARCH_RESULT\"\n break;\n fi;\n _CURRENT_LOOKUPS=$((_CURRENT_LOOKUPS+1))\ndone\n\nif [[ ${_SEARCH_RESULT} ]]; then\n _JSON_OUTPUT_RAW=$(cat \"${_SEARCH_RESULT}\")\n _RN_ROOT_EXISTS=$(ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$_JSON_OUTPUT_RAW'); puts output[$_JSON_ROOT]\" || echo '')\n\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n _JSON_OUTPUT_BASE64=$(python -c 'import json,sys,base64;print(base64.b64encode(json.dumps(json.loads(open('\"'${_SEARCH_RESULT}'\"').read())['${_JSON_ROOT}'])))' || echo \"e30=\")\n fi\n\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n\n # config.messaging_auto_init_enabled\n _MESSAGING_AUTO_INIT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"messaging_auto_init_enabled\")\n if [[ $_MESSAGING_AUTO_INIT ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseMessagingAutoInitEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_MESSAGING_AUTO_INIT\")\")\n fi\n\n # config.crashlytics_disable_auto_disabler - undocumented for now - mainly for debugging, document if becomes useful\n _CRASHLYTICS_AUTO_DISABLE_ENABLED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"crashlytics_disable_auto_disabler\")\n if [[ $_CRASHLYTICS_AUTO_DISABLE_ENABLED == \"true\" ]]; then\n echo \"Disabled Crashlytics auto disabler.\" # do nothing\n else\n _PLIST_ENTRY_KEYS+=(\"FirebaseCrashlyticsCollectionEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"NO\")\n fi\n\n # config.admob_delay_app_measurement_init\n _ADMOB_DELAY_APP_MEASUREMENT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_delay_app_measurement_init\")\n if [[ $_ADMOB_DELAY_APP_MEASUREMENT == \"true\" ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADDelayAppMeasurementInit\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"YES\")\n fi\n\n # config.admob_ios_app_id\n _ADMOB_IOS_APP_ID=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_ios_app_id\")\n if [[ $_ADMOB_IOS_APP_ID ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADApplicationIdentifier\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_ADMOB_IOS_APP_ID\")\n fi\nelse\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n echo \"warning: A firebase.json file was not found, whilst this file is optional it is recommended to include it to configure firebase services in React Native Firebase.\"\nfi;\n\necho \"info: 2) Injecting Info.plist entries: \"\n\n# Log out the keys we're adding\nfor i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n echo \" -> $i) ${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\"\ndone\n\nfor plist in \"${_TARGET_PLIST}\" \"${_DSYM_PLIST}\" ; do\n if [[ -f \"${plist}\" ]]; then\n\n # paths with spaces break the call to setPlistValue. temporarily modify\n # the shell internal field separator variable (IFS), which normally\n # includes spaces, to consist only of line breaks\n oldifs=$IFS\n IFS=\"\n\"\n\n for i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n setPlistValue \"${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\" \"${plist}\"\n done\n\n # restore the original internal field separator value\n IFS=$oldifs\n else\n echo \"warning: A Info.plist build output file was not found (${plist})\"\n fi\ndone\n\necho \"info: <- RNFB build script finished\"\n"; + shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\nif [[ ${PODS_ROOT} ]]; then\n echo \"info: Exec FirebaseCrashlytics Run from Pods\"\n \"${PODS_ROOT}/FirebaseCrashlytics/run\"\nelse\n echo \"info: Exec FirebaseCrashlytics Run from framework\"\n \"${PROJECT_DIR}/FirebaseCrashlytics.framework/run\"\nfi\n"; }; FD10A7F022414F080027D42C /* Start Packager */ = { isa = PBXShellScriptBuildPhase; @@ -729,6 +709,26 @@ shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; showEnvVarsInLog = 0; }; + FDEC6A9E72906AA72F933F6C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh", + "${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}/OpenSSL.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LinkKit.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -765,7 +765,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CF8C66EE73F9B503DE3E0D58 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */; + baseConfigurationReference = 8050C35474CA1229CB67554C /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -790,7 +790,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1C3425E20B41643777DE7722 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */; + baseConfigurationReference = 39F97C08A506D924360431AC /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -813,7 +813,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DDF4204498D793D7FB483440 /* Pods-ExpensifyCash.debug.xcconfig */; + baseConfigurationReference = 53ADB1B00B8DB25FFF4A451E /* Pods-ExpensifyCash.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -846,7 +846,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 46BF67CDAA47420D541264C2 /* Pods-ExpensifyCash.release.xcconfig */; + baseConfigurationReference = E5909F0BF549E15008ED6B55 /* Pods-ExpensifyCash.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; diff --git a/package-lock.json b/package-lock.json index b948df53fe14..f74bcf8fcdba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29648,6 +29648,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, "requires": { "yallist": "^4.0.0" }, @@ -29655,7 +29656,8 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -35198,6 +35200,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, "requires": { "minipass": "^3.1.1" } From 1453ce899e4464e9c3833c909b562b6bf7aefc93 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Tue, 1 Jun 2021 15:41:03 -0700 Subject: [PATCH 10/17] Fix AppDelegate --- ios/ExpensifyCash/AppDelegate.m | 62 ++++++++++++++------------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/ios/ExpensifyCash/AppDelegate.m b/ios/ExpensifyCash/AppDelegate.m index 32cc01376947..0a2a05ceda12 100644 --- a/ios/ExpensifyCash/AppDelegate.m +++ b/ios/ExpensifyCash/AppDelegate.m @@ -11,32 +11,6 @@ #import #import -/*=== START react-native-push-notification-ios configs ===*/ -// Required for the register event. -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken -{ - [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; -} -// Required for the notification event. You must call the completion handler after handling the remote notification. -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo -fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler -{ - [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; -} -// Required for the registrationError event. -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error -{ - [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error]; -} -// Required for localNotification event -- (void)userNotificationCenter:(UNUserNotificationCenter *)center -didReceiveNotificationResponse:(UNNotificationResponse *)response - withCompletionHandler:(void (^)(void))completionHandler -{ - [RNCPushNotificationIOS didReceiveNotificationResponse:response]; -} -/*=== END react-native-push-notification-ios configs ===*/ - #ifdef FB_SONARKIT_ENABLED #import #import @@ -113,20 +87,36 @@ - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull N restorationHandler:restorationHandler]; } -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - ... - // Define UNUserNotificationCenter - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - center.delegate = self; - - return YES; -} - //Called when a notification is delivered to a foreground app. -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge); } +/*=== START react-native-push-notification-ios configs ===*/ +// Required for the register event. +- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken +{ + [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; +} +// Required for the notification event. You must call the completion handler after handling the remote notification. +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo +fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler +{ + [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; +} +// Required for the registrationError event. +- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error +{ + [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error]; +} +// Required for localNotification event +- (void)userNotificationCenter:(UNUserNotificationCenter *)center +didReceiveNotificationResponse:(UNNotificationResponse *)response + withCompletionHandler:(void (^)(void))completionHandler +{ + [RNCPushNotificationIOS didReceiveNotificationResponse:response]; +} +/*=== END react-native-push-notification-ios configs ===*/ + @end From 1556181b200cf8f4b81c8c5ab13bcf016e0e1d91 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Tue, 1 Jun 2021 17:29:10 -0700 Subject: [PATCH 11/17] Fix export and implement isVisible on mobile --- .../LocalNotificationService/index.native.js | 6 +++++- src/libs/Visibility/index.native.js | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js b/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js index 64e3beef3067..522924dcdcd5 100644 --- a/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js +++ b/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js @@ -86,7 +86,7 @@ function processQueue() { * @param {LocalNotification} notification * @throws {Error} */ -export default function queueNotification(notification) { +function queueNotification(notification) { if (!(notification instanceof LocalNotification)) { throw new Error('Attempting to queue invalid LocalNotification'); } @@ -99,3 +99,7 @@ export default function queueNotification(notification) { processQueue(); } } + +export default { + queueNotification, +}; diff --git a/src/libs/Visibility/index.native.js b/src/libs/Visibility/index.native.js index ba878d4ef7d0..08eaa375cdce 100644 --- a/src/libs/Visibility/index.native.js +++ b/src/libs/Visibility/index.native.js @@ -1,10 +1,11 @@ -// Mobile apps do not require this check for visibility as -// they do not use the Notification lib. +import {AppState} from 'react-native'; /** * @return {Boolean} */ -const isVisible = () => true; +function isVisible() { + return AppState.currentState === 'active'; +} export default { isVisible, From f0d55254603bd565f7b80dc3d8ee3204bdaa9316 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Fri, 18 Jun 2021 11:19:21 -0700 Subject: [PATCH 12/17] Reinstall everything after merge --- ios/ExpensifyCash.xcodeproj/project.pbxproj | 242 ++++++++++---------- ios/Podfile.lock | 6 + package-lock.json | 13 ++ 3 files changed, 140 insertions(+), 121 deletions(-) diff --git a/ios/ExpensifyCash.xcodeproj/project.pbxproj b/ios/ExpensifyCash.xcodeproj/project.pbxproj index 3f740ca957f2..19419898d1d7 100644 --- a/ios/ExpensifyCash.xcodeproj/project.pbxproj +++ b/ios/ExpensifyCash.xcodeproj/project.pbxproj @@ -25,13 +25,13 @@ 52477A09739546F4814EA25F /* GTAmericaExpMono-Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0DE5D096095C41EE96746C9E /* GTAmericaExpMono-Bd.otf */; }; 6856B78873B64C44A92E51DB /* GTAmericaExp-MdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */; }; 70CF6E82262E297300711ADC /* BootSplash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 70CF6E81262E297300711ADC /* BootSplash.storyboard */; }; + 76619227EA8BB9DF4BF36236 /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C75B9D1040A9A06FB09B46EE /* libPods-ExpensifyCash-ExpensifyCashTests.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 8821A238A081483FA947BC4E /* GTAmericaExp-RgIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 918D7FEFF96242E6B5F5E14D /* GTAmericaExp-RgIt.otf */; }; - A3436007AC25B52D4421EDFE /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D9772847002A7309594CFB3C /* libPods-ExpensifyCash-ExpensifyCashTests.a */; }; - DA1351CF1BC4929C869D7874 /* libPods-ExpensifyCash.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19505195D8D4A1D33ACBECCF /* libPods-ExpensifyCash.a */; }; DB77016704074197AB6633BB /* GTAmericaExpMono-RgIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5150E5D0D7F74DBA8D7C1914 /* GTAmericaExpMono-RgIt.otf */; }; E9DF872D2525201700607FDC /* AirshipConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = E9DF872C2525201700607FDC /* AirshipConfig.plist */; }; ED814D34526B415CAFA0451E /* GTAmericaExpMono-BdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3981452A2C7340EBBA2B9BD1 /* GTAmericaExpMono-BdIt.otf */; }; + F6BDE056DEB0C6A30855CD7E /* libPods-ExpensifyCash.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C91F3560D48B5F2692B55D /* libPods-ExpensifyCash.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,24 +60,24 @@ 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ExpensifyCash/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ExpensifyCash/main.m; sourceTree = ""; }; 18D050DF262400AF000D658B /* BridgingFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BridgingFile.swift; sourceTree = ""; }; - 19505195D8D4A1D33ACBECCF /* libPods-ExpensifyCash.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 3981452A2C7340EBBA2B9BD1 /* GTAmericaExpMono-BdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-BdIt.otf"; path = "../assets/fonts/GTAmericaExpMono-BdIt.otf"; sourceTree = ""; }; - 40EE174FE0E5010DA25F3180 /* Pods-ExpensifyCash.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.debug.xcconfig"; sourceTree = ""; }; + 42C91F3560D48B5F2692B55D /* libPods-ExpensifyCash.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 51191C9E80935A80099F67B4 /* Pods-ExpensifyCash.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.release.xcconfig"; sourceTree = ""; }; 5150E5D0D7F74DBA8D7C1914 /* GTAmericaExpMono-RgIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-RgIt.otf"; path = "../assets/fonts/GTAmericaExpMono-RgIt.otf"; sourceTree = ""; }; - 5E0275D64694B453A3EE297D /* Pods-ExpensifyCash.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.release.xcconfig"; sourceTree = ""; }; 67D5C3A6A7FA417C8A853FC1 /* GTAmericaExp-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Light.otf"; path = "../assets/fonts/GTAmericaExp-Light.otf"; sourceTree = ""; }; + 6F9F2F6F4E0F0090A238B760 /* Pods-ExpensifyCash.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash.debug.xcconfig"; sourceTree = ""; }; 70CF6E81262E297300711ADC /* BootSplash.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = BootSplash.storyboard; path = ExpensifyCash/BootSplash.storyboard; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = ExpensifyCash/LaunchScreen.storyboard; sourceTree = ""; }; 8437A5A38F2047E0BCCD7C2F /* GTAmericaExpMono-Rg.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExpMono-Rg.otf"; path = "../assets/fonts/GTAmericaExpMono-Rg.otf"; sourceTree = ""; }; + 8505C557B697659B3983EF08 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; sourceTree = ""; }; 8C7003903C1E4957824899BB /* GTAmericaExp-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Regular.otf"; path = "../assets/fonts/GTAmericaExp-Regular.otf"; sourceTree = ""; }; 918D7FEFF96242E6B5F5E14D /* GTAmericaExp-RgIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-RgIt.otf"; path = "../assets/fonts/GTAmericaExp-RgIt.otf"; sourceTree = ""; }; A292718541C841859D97DF2F /* GTAmericaExp-Thin.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Thin.otf"; path = "../assets/fonts/GTAmericaExp-Thin.otf"; sourceTree = ""; }; A5AAD008CBD84A6CAEB9AC97 /* GTAmericaExp-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Bold.otf"; path = "../assets/fonts/GTAmericaExp-Bold.otf"; sourceTree = ""; }; A8D6F2F722FD4E66A38EBBB6 /* GTAmericaExp-BdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-BdIt.otf"; path = "../assets/fonts/GTAmericaExp-BdIt.otf"; sourceTree = ""; }; + A9454D0E01D17128C0732883 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; sourceTree = ""; }; AE65058949E14DA5A2D5435D /* GTAmericaExp-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-Medium.otf"; path = "../assets/fonts/GTAmericaExp-Medium.otf"; sourceTree = ""; }; - B82386231652D749850CFC70 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig"; sourceTree = ""; }; - D111222CBD2088E51A5BB624 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; path = "Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig"; sourceTree = ""; }; - D9772847002A7309594CFB3C /* libPods-ExpensifyCash-ExpensifyCashTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash-ExpensifyCashTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + C75B9D1040A9A06FB09B46EE /* libPods-ExpensifyCash-ExpensifyCashTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExpensifyCash-ExpensifyCashTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-MdIt.otf"; path = "../assets/fonts/GTAmericaExp-MdIt.otf"; sourceTree = ""; }; E9DF872C2525201700607FDC /* AirshipConfig.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AirshipConfig.plist; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; @@ -89,7 +89,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A3436007AC25B52D4421EDFE /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */, + 76619227EA8BB9DF4BF36236 /* libPods-ExpensifyCash-ExpensifyCashTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -97,7 +97,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DA1351CF1BC4929C869D7874 /* libPods-ExpensifyCash.a in Frameworks */, + F6BDE056DEB0C6A30855CD7E /* libPods-ExpensifyCash.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -145,8 +145,8 @@ children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED2971642150620600B7C4FE /* JavaScriptCore.framework */, - 19505195D8D4A1D33ACBECCF /* libPods-ExpensifyCash.a */, - D9772847002A7309594CFB3C /* libPods-ExpensifyCash-ExpensifyCashTests.a */, + 42C91F3560D48B5F2692B55D /* libPods-ExpensifyCash.a */, + C75B9D1040A9A06FB09B46EE /* libPods-ExpensifyCash-ExpensifyCashTests.a */, ); name = Frameworks; sourceTree = ""; @@ -206,10 +206,10 @@ EC29677F0A49C2946A495A33 /* Pods */ = { isa = PBXGroup; children = ( - 40EE174FE0E5010DA25F3180 /* Pods-ExpensifyCash.debug.xcconfig */, - 5E0275D64694B453A3EE297D /* Pods-ExpensifyCash.release.xcconfig */, - B82386231652D749850CFC70 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */, - D111222CBD2088E51A5BB624 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */, + 6F9F2F6F4E0F0090A238B760 /* Pods-ExpensifyCash.debug.xcconfig */, + 51191C9E80935A80099F67B4 /* Pods-ExpensifyCash.release.xcconfig */, + 8505C557B697659B3983EF08 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */, + A9454D0E01D17128C0732883 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -221,12 +221,12 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ExpensifyCashTests" */; buildPhases = ( - 538F0530BD355DE69016FC8D /* [CP] Check Pods Manifest.lock */, + 8DFA5A00696B687F79C95016 /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - DC5669E1DEB80DD839FDB293 /* [CP] Embed Pods Frameworks */, - D91BC49ED9E5B6C37CAABCC6 /* [CP] Copy Pods Resources */, + 508FBBA985FA02D6C17543EF /* [CP] Embed Pods Frameworks */, + 2B952465AAB48F24B1242706 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -242,16 +242,16 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ExpensifyCash" */; buildPhases = ( - BD50DAA2FC45BE14BFB945D0 /* [CP] Check Pods Manifest.lock */, + 9ADAD62C841619370715F04D /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - 8575AEF2E98CE400DE51E589 /* [CP] Embed Pods Frameworks */, - 1FE23122F2FCC35F85E0E2F7 /* [CP] Copy Pods Resources */, - CF6C6C97851DBF01CDAE664E /* [CP-User] [RNFB] Core Configuration */, - 5717025076C7AEA43883A0AC /* [CP-User] [RNFB] Crashlytics Configuration */, + 2B16A01E32805491D3D0C2C7 /* [CP] Embed Pods Frameworks */, + 2FF33D22F22E13C0294AF784 /* [CP] Copy Pods Resources */, + 98C853189A534B46B0295A00 /* [CP-User] [RNFB] Core Configuration */, + E0A3A156B5B4C0811DDF7822 /* [CP-User] [RNFB] Crashlytics Configuration */, ); buildRules = ( ); @@ -350,13 +350,35 @@ shellPath = /bin/sh; shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; }; - 1FE23122F2FCC35F85E0E2F7 /* [CP] Copy Pods Resources */ = { + 2B16A01E32805491D3D0C2C7 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh", + "${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}/Onfido.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LinkKit.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 2B952465AAB48F24B1242706 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAAutomationActions.plist", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageBannerContentView.xib", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageBannerView.xib", @@ -475,102 +497,16 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 538F0530BD355DE69016FC8D /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ExpensifyCash-ExpensifyCashTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 5717025076C7AEA43883A0AC /* [CP-User] [RNFB] Crashlytics Configuration */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - name = "[CP-User] [RNFB] Crashlytics Configuration"; - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\nif [[ ${PODS_ROOT} ]]; then\n echo \"info: Exec FirebaseCrashlytics Run from Pods\"\n \"${PODS_ROOT}/FirebaseCrashlytics/run\"\nelse\n echo \"info: Exec FirebaseCrashlytics Run from framework\"\n \"${PROJECT_DIR}/FirebaseCrashlytics.framework/run\"\nfi\n"; - }; - 8575AEF2E98CE400DE51E589 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh", - "${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}/Onfido.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LinkKit.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - BD50DAA2FC45BE14BFB945D0 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ExpensifyCash-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - CF6C6C97851DBF01CDAE664E /* [CP-User] [RNFB] Core Configuration */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - name = "[CP-User] [RNFB] Core Configuration"; - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\n_MAX_LOOKUPS=2;\n_SEARCH_RESULT=''\n_RN_ROOT_EXISTS=''\n_CURRENT_LOOKUPS=1\n_JSON_ROOT=\"'react-native'\"\n_JSON_FILE_NAME='firebase.json'\n_JSON_OUTPUT_BASE64='e30=' # { }\n_CURRENT_SEARCH_DIR=${PROJECT_DIR}\n_PLIST_BUDDY=/usr/libexec/PlistBuddy\n_TARGET_PLIST=\"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\"\n_DSYM_PLIST=\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"\n\n# plist arrays\n_PLIST_ENTRY_KEYS=()\n_PLIST_ENTRY_TYPES=()\n_PLIST_ENTRY_VALUES=()\n\nfunction setPlistValue {\n echo \"info: setting plist entry '$1' of type '$2' in file '$4'\"\n ${_PLIST_BUDDY} -c \"Add :$1 $2 '$3'\" $4 || echo \"info: '$1' already exists\"\n}\n\nfunction getFirebaseJsonKeyValue () {\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$1'); puts output[$_JSON_ROOT]['$2']\"\n else\n echo \"\"\n fi;\n}\n\nfunction jsonBoolToYesNo () {\n if [[ $1 == \"false\" ]]; then\n echo \"NO\"\n elif [[ $1 == \"true\" ]]; then\n echo \"YES\"\n else echo \"NO\"\n fi\n}\n\necho \"info: -> RNFB build script started\"\necho \"info: 1) Locating ${_JSON_FILE_NAME} file:\"\n\nif [[ -z ${_CURRENT_SEARCH_DIR} ]]; then\n _CURRENT_SEARCH_DIR=$(pwd)\nfi;\n\nwhile true; do\n _CURRENT_SEARCH_DIR=$(dirname \"$_CURRENT_SEARCH_DIR\")\n if [[ \"$_CURRENT_SEARCH_DIR\" == \"/\" ]] || [[ ${_CURRENT_LOOKUPS} -gt ${_MAX_LOOKUPS} ]]; then break; fi;\n echo \"info: ($_CURRENT_LOOKUPS of $_MAX_LOOKUPS) Searching in '$_CURRENT_SEARCH_DIR' for a ${_JSON_FILE_NAME} file.\"\n _SEARCH_RESULT=$(find \"$_CURRENT_SEARCH_DIR\" -maxdepth 2 -name ${_JSON_FILE_NAME} -print | head -n 1)\n if [[ ${_SEARCH_RESULT} ]]; then\n echo \"info: ${_JSON_FILE_NAME} found at $_SEARCH_RESULT\"\n break;\n fi;\n _CURRENT_LOOKUPS=$((_CURRENT_LOOKUPS+1))\ndone\n\nif [[ ${_SEARCH_RESULT} ]]; then\n _JSON_OUTPUT_RAW=$(cat \"${_SEARCH_RESULT}\")\n _RN_ROOT_EXISTS=$(ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$_JSON_OUTPUT_RAW'); puts output[$_JSON_ROOT]\" || echo '')\n\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n _JSON_OUTPUT_BASE64=$(python -c 'import json,sys,base64;print(base64.b64encode(json.dumps(json.loads(open('\"'${_SEARCH_RESULT}'\"').read())['${_JSON_ROOT}'])))' || echo \"e30=\")\n fi\n\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n\n # config.messaging_auto_init_enabled\n _MESSAGING_AUTO_INIT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"messaging_auto_init_enabled\")\n if [[ $_MESSAGING_AUTO_INIT ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseMessagingAutoInitEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_MESSAGING_AUTO_INIT\")\")\n fi\n\n # config.crashlytics_disable_auto_disabler - undocumented for now - mainly for debugging, document if becomes useful\n _CRASHLYTICS_AUTO_DISABLE_ENABLED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"crashlytics_disable_auto_disabler\")\n if [[ $_CRASHLYTICS_AUTO_DISABLE_ENABLED == \"true\" ]]; then\n echo \"Disabled Crashlytics auto disabler.\" # do nothing\n else\n _PLIST_ENTRY_KEYS+=(\"FirebaseCrashlyticsCollectionEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"NO\")\n fi\n\n # config.admob_delay_app_measurement_init\n _ADMOB_DELAY_APP_MEASUREMENT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_delay_app_measurement_init\")\n if [[ $_ADMOB_DELAY_APP_MEASUREMENT == \"true\" ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADDelayAppMeasurementInit\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"YES\")\n fi\n\n # config.admob_ios_app_id\n _ADMOB_IOS_APP_ID=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_ios_app_id\")\n if [[ $_ADMOB_IOS_APP_ID ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADApplicationIdentifier\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_ADMOB_IOS_APP_ID\")\n fi\nelse\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n echo \"warning: A firebase.json file was not found, whilst this file is optional it is recommended to include it to configure firebase services in React Native Firebase.\"\nfi;\n\necho \"info: 2) Injecting Info.plist entries: \"\n\n# Log out the keys we're adding\nfor i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n echo \" -> $i) ${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\"\ndone\n\nfor plist in \"${_TARGET_PLIST}\" \"${_DSYM_PLIST}\" ; do\n if [[ -f \"${plist}\" ]]; then\n\n # paths with spaces break the call to setPlistValue. temporarily modify\n # the shell internal field separator variable (IFS), which normally\n # includes spaces, to consist only of line breaks\n oldifs=$IFS\n IFS=\"\n\"\n\n for i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n setPlistValue \"${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\" \"${plist}\"\n done\n\n # restore the original internal field separator value\n IFS=$oldifs\n else\n echo \"warning: A Info.plist build output file was not found (${plist})\"\n fi\ndone\n\necho \"info: <- RNFB build script finished\"\n"; - }; - D91BC49ED9E5B6C37CAABCC6 /* [CP] Copy Pods Resources */ = { + 2FF33D22F22E13C0294AF784 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-resources.sh", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAAutomationActions.plist", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageBannerContentView.xib", "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageBannerView.xib", @@ -689,10 +625,10 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash/Pods-ExpensifyCash-resources.sh\"\n"; showEnvVarsInLog = 0; }; - DC5669E1DEB80DD839FDB293 /* [CP] Embed Pods Frameworks */ = { + 508FBBA985FA02D6C17543EF /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -714,6 +650,70 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ExpensifyCash-ExpensifyCashTests/Pods-ExpensifyCash-ExpensifyCashTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + 8DFA5A00696B687F79C95016 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ExpensifyCash-ExpensifyCashTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 98C853189A534B46B0295A00 /* [CP-User] [RNFB] Core Configuration */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + name = "[CP-User] [RNFB] Core Configuration"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\n_MAX_LOOKUPS=2;\n_SEARCH_RESULT=''\n_RN_ROOT_EXISTS=''\n_CURRENT_LOOKUPS=1\n_JSON_ROOT=\"'react-native'\"\n_JSON_FILE_NAME='firebase.json'\n_JSON_OUTPUT_BASE64='e30=' # { }\n_CURRENT_SEARCH_DIR=${PROJECT_DIR}\n_PLIST_BUDDY=/usr/libexec/PlistBuddy\n_TARGET_PLIST=\"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\"\n_DSYM_PLIST=\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"\n\n# plist arrays\n_PLIST_ENTRY_KEYS=()\n_PLIST_ENTRY_TYPES=()\n_PLIST_ENTRY_VALUES=()\n\nfunction setPlistValue {\n echo \"info: setting plist entry '$1' of type '$2' in file '$4'\"\n ${_PLIST_BUDDY} -c \"Add :$1 $2 '$3'\" $4 || echo \"info: '$1' already exists\"\n}\n\nfunction getFirebaseJsonKeyValue () {\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$1'); puts output[$_JSON_ROOT]['$2']\"\n else\n echo \"\"\n fi;\n}\n\nfunction jsonBoolToYesNo () {\n if [[ $1 == \"false\" ]]; then\n echo \"NO\"\n elif [[ $1 == \"true\" ]]; then\n echo \"YES\"\n else echo \"NO\"\n fi\n}\n\necho \"info: -> RNFB build script started\"\necho \"info: 1) Locating ${_JSON_FILE_NAME} file:\"\n\nif [[ -z ${_CURRENT_SEARCH_DIR} ]]; then\n _CURRENT_SEARCH_DIR=$(pwd)\nfi;\n\nwhile true; do\n _CURRENT_SEARCH_DIR=$(dirname \"$_CURRENT_SEARCH_DIR\")\n if [[ \"$_CURRENT_SEARCH_DIR\" == \"/\" ]] || [[ ${_CURRENT_LOOKUPS} -gt ${_MAX_LOOKUPS} ]]; then break; fi;\n echo \"info: ($_CURRENT_LOOKUPS of $_MAX_LOOKUPS) Searching in '$_CURRENT_SEARCH_DIR' for a ${_JSON_FILE_NAME} file.\"\n _SEARCH_RESULT=$(find \"$_CURRENT_SEARCH_DIR\" -maxdepth 2 -name ${_JSON_FILE_NAME} -print | head -n 1)\n if [[ ${_SEARCH_RESULT} ]]; then\n echo \"info: ${_JSON_FILE_NAME} found at $_SEARCH_RESULT\"\n break;\n fi;\n _CURRENT_LOOKUPS=$((_CURRENT_LOOKUPS+1))\ndone\n\nif [[ ${_SEARCH_RESULT} ]]; then\n _JSON_OUTPUT_RAW=$(cat \"${_SEARCH_RESULT}\")\n _RN_ROOT_EXISTS=$(ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$_JSON_OUTPUT_RAW'); puts output[$_JSON_ROOT]\" || echo '')\n\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n _JSON_OUTPUT_BASE64=$(python -c 'import json,sys,base64;print(base64.b64encode(json.dumps(json.loads(open('\"'${_SEARCH_RESULT}'\"').read())['${_JSON_ROOT}'])))' || echo \"e30=\")\n fi\n\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n\n # config.messaging_auto_init_enabled\n _MESSAGING_AUTO_INIT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"messaging_auto_init_enabled\")\n if [[ $_MESSAGING_AUTO_INIT ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseMessagingAutoInitEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_MESSAGING_AUTO_INIT\")\")\n fi\n\n # config.crashlytics_disable_auto_disabler - undocumented for now - mainly for debugging, document if becomes useful\n _CRASHLYTICS_AUTO_DISABLE_ENABLED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"crashlytics_disable_auto_disabler\")\n if [[ $_CRASHLYTICS_AUTO_DISABLE_ENABLED == \"true\" ]]; then\n echo \"Disabled Crashlytics auto disabler.\" # do nothing\n else\n _PLIST_ENTRY_KEYS+=(\"FirebaseCrashlyticsCollectionEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"NO\")\n fi\n\n # config.admob_delay_app_measurement_init\n _ADMOB_DELAY_APP_MEASUREMENT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_delay_app_measurement_init\")\n if [[ $_ADMOB_DELAY_APP_MEASUREMENT == \"true\" ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADDelayAppMeasurementInit\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"YES\")\n fi\n\n # config.admob_ios_app_id\n _ADMOB_IOS_APP_ID=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_ios_app_id\")\n if [[ $_ADMOB_IOS_APP_ID ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADApplicationIdentifier\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_ADMOB_IOS_APP_ID\")\n fi\nelse\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n echo \"warning: A firebase.json file was not found, whilst this file is optional it is recommended to include it to configure firebase services in React Native Firebase.\"\nfi;\n\necho \"info: 2) Injecting Info.plist entries: \"\n\n# Log out the keys we're adding\nfor i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n echo \" -> $i) ${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\"\ndone\n\nfor plist in \"${_TARGET_PLIST}\" \"${_DSYM_PLIST}\" ; do\n if [[ -f \"${plist}\" ]]; then\n\n # paths with spaces break the call to setPlistValue. temporarily modify\n # the shell internal field separator variable (IFS), which normally\n # includes spaces, to consist only of line breaks\n oldifs=$IFS\n IFS=\"\n\"\n\n for i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n setPlistValue \"${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\" \"${plist}\"\n done\n\n # restore the original internal field separator value\n IFS=$oldifs\n else\n echo \"warning: A Info.plist build output file was not found (${plist})\"\n fi\ndone\n\necho \"info: <- RNFB build script finished\"\n"; + }; + 9ADAD62C841619370715F04D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ExpensifyCash-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E0A3A156B5B4C0811DDF7822 /* [CP-User] [RNFB] Crashlytics Configuration */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + name = "[CP-User] [RNFB] Crashlytics Configuration"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\nif [[ ${PODS_ROOT} ]]; then\n echo \"info: Exec FirebaseCrashlytics Run from Pods\"\n \"${PODS_ROOT}/FirebaseCrashlytics/run\"\nelse\n echo \"info: Exec FirebaseCrashlytics Run from framework\"\n \"${PROJECT_DIR}/FirebaseCrashlytics.framework/run\"\nfi\n"; + }; FD10A7F022414F080027D42C /* Start Packager */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -769,7 +769,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B82386231652D749850CFC70 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */; + baseConfigurationReference = 8505C557B697659B3983EF08 /* Pods-ExpensifyCash-ExpensifyCashTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -794,7 +794,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D111222CBD2088E51A5BB624 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */; + baseConfigurationReference = A9454D0E01D17128C0732883 /* Pods-ExpensifyCash-ExpensifyCashTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -817,7 +817,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 40EE174FE0E5010DA25F3180 /* Pods-ExpensifyCash.debug.xcconfig */; + baseConfigurationReference = 6F9F2F6F4E0F0090A238B760 /* Pods-ExpensifyCash.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -850,7 +850,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5E0275D64694B453A3EE297D /* Pods-ExpensifyCash.release.xcconfig */; + baseConfigurationReference = 51191C9E80935A80099F67B4 /* Pods-ExpensifyCash.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 8f4aa1dc3ac5..e2e566a3d416 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -444,6 +444,8 @@ PODS: - React-Core - RNCPicker (1.9.11): - React-Core + - RNCPushNotificationIOS (1.8.0): + - React-Core - RNFBAnalytics (7.6.8): - Firebase/Analytics (~> 6.34.0) - React-Core @@ -568,6 +570,7 @@ DEPENDENCIES: - "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)" - "RNCMaskedView (from `../node_modules/@react-native-masked-view/masked-view`)" - "RNCPicker (from `../node_modules/@react-native-picker/picker`)" + - "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)" - "RNFBAnalytics (from `../node_modules/@react-native-firebase/analytics`)" - "RNFBApp (from `../node_modules/@react-native-firebase/app`)" - "RNFBCrashlytics (from `../node_modules/@react-native-firebase/crashlytics`)" @@ -701,6 +704,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-masked-view/masked-view" RNCPicker: :path: "../node_modules/@react-native-picker/picker" + RNCPushNotificationIOS: + :path: "../node_modules/@react-native-community/push-notification-ios" RNFBAnalytics: :path: "../node_modules/@react-native-firebase/analytics" RNFBApp: @@ -794,6 +799,7 @@ SPEC CHECKSUMS: RNCClipboard: 5e299c6df8e0c98f3d7416b86ae563d3a9f768a3 RNCMaskedView: 138134c4d8a9421b4f2bf39055a79aa05c2d47b1 RNCPicker: 6780c753e9e674065db90d9c965920516402579d + RNCPushNotificationIOS: 5b1cf9ad2aaa107ecb92d5d2d7005ba521b2b97a RNFBAnalytics: 2dc4dd9e2445faffca041b10447a23a71dcdabf8 RNFBApp: 7eacc7da7ab19f96c05e434017d44a9f09410da8 RNFBCrashlytics: 4870c14cf8833053b6b5648911abefe1923854d2 diff --git a/package-lock.json b/package-lock.json index 1e8dd875c11d..f22ace5355a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5791,6 +5791,14 @@ "resolved": "https://registry.npmjs.org/@react-native-community/progress-view/-/progress-view-1.2.3.tgz", "integrity": "sha512-CW7eOhxduIxA723aZlKMOnBEz1o5Cjo5ibMNsf81TcjNqtsamRHm8jFS98za7t5P7XdhM0MhzkbaS90cwOlN+Q==" }, + "@react-native-community/push-notification-ios": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@react-native-community/push-notification-ios/-/push-notification-ios-1.8.0.tgz", + "integrity": "sha512-vxvkeampafjmtDoQBN8Q4azP21l6cMX93+OQZemyIWZmG++OjCVDQVitobf/kWLm5zyGwdylejbpMGo75qo7rA==", + "requires": { + "invariant": "^2.2.4" + } + }, "@react-native-firebase/analytics": { "version": "7.6.8", "resolved": "https://registry.npmjs.org/@react-native-firebase/analytics/-/analytics-7.6.8.tgz", @@ -33948,6 +33956,11 @@ "tsc": "^1.20150623.0" } }, + "react-native-push-notification": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/react-native-push-notification/-/react-native-push-notification-7.3.1.tgz", + "integrity": "sha512-5kSKPvDU23uZRmzgKTsGhbwGNvB2tidu1VnInBHP53ZD0VEPSBl5fbpuTfHH98ED+Gp1SCcT2/e6bJWkIspKvg==" + }, "react-native-reanimated": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.1.0.tgz", From a40503a38a18b796adff02fb90d2b3684ce580b8 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Fri, 18 Jun 2021 12:25:35 -0700 Subject: [PATCH 13/17] Get onNotification callback working --- .../LocalNotificationService/index.native.js | 4 +++- src/libs/actions/Report.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js b/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js index 522924dcdcd5..622910972b93 100644 --- a/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js +++ b/src/libs/Notification/LocalNotification/LocalNotificationService/index.native.js @@ -25,7 +25,9 @@ let currentlyProcessingNotification = null; let onNotification = () => {}; let channelInitialized = false; -PushNotification.configure({onNotification}); +PushNotification.configure({ + onNotification: e => onNotification(e), +}); /** * Get the local notification channel (required for Android) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index ce05c41675b7..33771e765e2f 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -616,7 +616,7 @@ function updateReportWithNewAction(reportID, reportAction, notificationPreferenc console.debug('[LOCAL_NOTIFICATION] Creating notification'); LocalNotification.showCommentNotification({ reportAction, - onClick: () => { + onPress: () => { // Navigate to this report onClick Navigation.navigate(ROUTES.getReportRoute(reportID)); }, From 441db415d697f3925fe17cf1f8309c3f9928caf1 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Wed, 23 Jun 2021 16:22:06 -0700 Subject: [PATCH 14/17] Save draft state for debugging --- ios/ExpensifyCash.xcodeproj/project.pbxproj | 18 ++++++------- package-lock.json | 5 ++++ package.json | 3 ++- .../Notification/LocalNotification/common.js | 2 +- .../PushNotification/index.native.js | 25 ++++++++++++------- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/ios/ExpensifyCash.xcodeproj/project.pbxproj b/ios/ExpensifyCash.xcodeproj/project.pbxproj index 19419898d1d7..48975cbfc9ed 100644 --- a/ios/ExpensifyCash.xcodeproj/project.pbxproj +++ b/ios/ExpensifyCash.xcodeproj/project.pbxproj @@ -278,7 +278,7 @@ 13B07F861A680F5B00A75B9A = { DevelopmentTeam = 368M544MTT; LastSwiftMigration = 1230; - ProvisioningStyle = Manual; + ProvisioningStyle = Automatic; }; }; }; @@ -822,10 +822,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = ExpensifyCash/Chat.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 3; - DEVELOPMENT_TEAM = 368M544MTT; + DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = NO; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; INFOPLIST_FILE = ExpensifyCash/Info.plist; @@ -839,7 +839,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.chat.expensify.chat; PRODUCT_NAME = Expensify.cash; - PROVISIONING_PROFILE_SPECIFIER = chat_expensify_appstore; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "ExpensifyCash-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -855,10 +855,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = ExpensifyCash/Chat.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 3; - DEVELOPMENT_TEAM = 368M544MTT; + DEVELOPMENT_TEAM = ""; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; INFOPLIST_FILE = ExpensifyCash/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; @@ -871,7 +871,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.chat.expensify.chat; PRODUCT_NAME = Expensify.cash; - PROVISIONING_PROFILE_SPECIFIER = chat_expensify_appstore; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "ExpensifyCash-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/package-lock.json b/package-lock.json index f22ace5355a4..755f7f17d417 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23311,6 +23311,11 @@ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" }, + "ios-deploy": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/ios-deploy/-/ios-deploy-1.11.4.tgz", + "integrity": "sha512-NZ96/s7klyWySKTI8rTU+vXEIxIMrv6K+7j5VMcqUVShaAUdDX+Ov4nVdSStYOAGFVpl8q56SpAwjEDIvBrswQ==" + }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", diff --git a/package.json b/package.json index 06048dcada62..29427f114b20 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "expensify-common": "^1.0.1", "file-loader": "^6.0.0", "html-entities": "^1.3.1", + "ios-deploy": "^1.11.4", "lodash": "4.17.21", "metro-config": "^0.64.0", "moment": "^2.27.0", @@ -85,8 +86,8 @@ "react-native-permissions": "^3.0.1", "react-native-picker-select": "8.0.4", "react-native-plaid-link-sdk": "^7.0.5", - "react-native-reanimated": "^2.1.0", "react-native-push-notification": "^7.3.1", + "react-native-reanimated": "^2.1.0", "react-native-render-html": "^6.0.0-alpha.10", "react-native-safe-area-context": "^3.1.4", "react-native-screens": "^3.0.0", diff --git a/src/libs/Notification/LocalNotification/common.js b/src/libs/Notification/LocalNotification/common.js index 344c831eddc7..f63a026bdc0c 100644 --- a/src/libs/Notification/LocalNotification/common.js +++ b/src/libs/Notification/LocalNotification/common.js @@ -15,5 +15,5 @@ function showCommentNotification({reportAction, onPress}) { } export default { - showCommentNotification, + showCommentNotification: () => {}, }; diff --git a/src/libs/Notification/PushNotification/index.native.js b/src/libs/Notification/PushNotification/index.native.js index bdb2565a2ff2..c2f01c48c1ff 100644 --- a/src/libs/Notification/PushNotification/index.native.js +++ b/src/libs/Notification/PushNotification/index.native.js @@ -3,6 +3,7 @@ import {AppState} from 'react-native'; import {UrbanAirship, EventType} from 'urbanairship-react-native'; import lodashGet from 'lodash/get'; import NotificationType from './NotificationType'; +import Log from '../../Log'; const notificationEventActionMap = {}; @@ -32,15 +33,6 @@ function pushNotificationEventCallback(eventType, notification) { return; } - // If a push notification is received while the app is in foreground, - // we'll assume pusher is connected so we'll ignore is and not fetch the same data twice. - // However, we will allow NotificationResponse events through, so that tapping on a foreground notification - // will take you to the relevant report. - if (AppState.currentState === 'active') { - console.debug('[PUSH_NOTIFICATION] Push received while app is in foreground, not executing any callback.'); - return; - } - if (!payload.type) { console.debug('[PUSH_NOTIFICATION] No type value provided in payload, not executing any callback.'); return; @@ -63,6 +55,7 @@ function pushNotificationEventCallback(eventType, notification) { * @param {String|Number} accountID */ function register(accountID) { + // TODO: fix this conditional - getNamedUser returns a promise if (UrbanAirship.getNamedUser() === accountID.toString()) { // No need to register again for this accountID. return; @@ -83,12 +76,26 @@ function register(accountID) { // Setup event listeners UrbanAirship.addListener(EventType.PushReceived, (notification) => { + console.debug('RORY_DEBUG PushReceived callback executed'); + Log.info('[PUSH_CLIENT][RORY_DEBUG] PushReceived callback executed', true, {}); + + // If a push notification is received while the app is in foreground, + // we'll assume pusher is connected so we'll ignore is and not fetch the same data twice. + // However, we will allow NotificationResponse events through, so that tapping on a foreground notification + // will take you to the relevant report. + if (AppState.currentState === 'active') { + console.debug('[PUSH_NOTIFICATION] Push received while app is in foreground, not executing any callback.'); + return; + } + pushNotificationEventCallback(EventType.PushReceived, notification); }); // Note: the NotificationResponse event has a nested PushReceived event, // so event.notification refers to the same thing as notification above ^ UrbanAirship.addListener(EventType.NotificationResponse, (event) => { + console.debug('RORY_DEBUG NotificationResponse callback executed'); + Log.info('[PUSH_CLIENT][RORY_DEBUG] PushReceived callback executed', true, {}); pushNotificationEventCallback(EventType.NotificationResponse, event.notification); }); } From a2d69374be9c6275297e582195bc5c0b045c7367 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Mon, 28 Jun 2021 19:21:22 -0700 Subject: [PATCH 15/17] Fix registration callback promise --- .../PushNotification/index.native.js | 78 +++++++++---------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/src/libs/Notification/PushNotification/index.native.js b/src/libs/Notification/PushNotification/index.native.js index c2f01c48c1ff..616ef5afd1aa 100644 --- a/src/libs/Notification/PushNotification/index.native.js +++ b/src/libs/Notification/PushNotification/index.native.js @@ -3,7 +3,6 @@ import {AppState} from 'react-native'; import {UrbanAirship, EventType} from 'urbanairship-react-native'; import lodashGet from 'lodash/get'; import NotificationType from './NotificationType'; -import Log from '../../Log'; const notificationEventActionMap = {}; @@ -55,49 +54,48 @@ function pushNotificationEventCallback(eventType, notification) { * @param {String|Number} accountID */ function register(accountID) { - // TODO: fix this conditional - getNamedUser returns a promise - if (UrbanAirship.getNamedUser() === accountID.toString()) { - // No need to register again for this accountID. - return; - } - - // Get permissions to display push notifications (prompts user on iOS, but not Android) - UrbanAirship.enableUserPushNotifications() - .then((isEnabled) => { - if (!isEnabled) { + Promise.all([ + UrbanAirship.getNamedUser(), + UrbanAirship.enableUserPushNotifications(), + ]) + .then(([namedUser, arePushNotificationsEnabled]) => { + if (!arePushNotificationsEnabled) { console.debug('[PUSH_NOTIFICATIONS] User has disabled visible push notifications for this app.'); } - }); - // Register this device as a named user in AirshipAPI. - // Regardless of the user's opt-in status, we still want to receive silent push notifications. - console.debug(`[PUSH_NOTIFICATIONS] Subscribing to notifications for account ID ${accountID}`); - UrbanAirship.setNamedUser(accountID.toString()); - - // Setup event listeners - UrbanAirship.addListener(EventType.PushReceived, (notification) => { - console.debug('RORY_DEBUG PushReceived callback executed'); - Log.info('[PUSH_CLIENT][RORY_DEBUG] PushReceived callback executed', true, {}); - - // If a push notification is received while the app is in foreground, - // we'll assume pusher is connected so we'll ignore is and not fetch the same data twice. - // However, we will allow NotificationResponse events through, so that tapping on a foreground notification - // will take you to the relevant report. - if (AppState.currentState === 'active') { - console.debug('[PUSH_NOTIFICATION] Push received while app is in foreground, not executing any callback.'); - return; - } - - pushNotificationEventCallback(EventType.PushReceived, notification); - }); + if (namedUser === accountID.toString()) { + console.debug('[PUSH_NOTIFICATIONS] This user is already registered for push notifications.'); + } else { + // Register this device as a named user in AirshipAPI. + // Regardless of the user's opt-in status, we still want to receive silent push notifications. + console.debug(`[PUSH_NOTIFICATIONS] Subscribing to notifications for account ID ${accountID}`); + UrbanAirship.setNamedUser(accountID.toString()); + } - // Note: the NotificationResponse event has a nested PushReceived event, - // so event.notification refers to the same thing as notification above ^ - UrbanAirship.addListener(EventType.NotificationResponse, (event) => { - console.debug('RORY_DEBUG NotificationResponse callback executed'); - Log.info('[PUSH_CLIENT][RORY_DEBUG] PushReceived callback executed', true, {}); - pushNotificationEventCallback(EventType.NotificationResponse, event.notification); - }); + // Setup event listeners + UrbanAirship.addListener(EventType.PushReceived, (notification) => { + console.debug('RORY_DEBUG PushReceived callback executed'); + + // If a push notification is received while the app is in foreground, + // we'll assume pusher is connected so we'll ignore is and not fetch the same data twice. + // However, we allow NotificationResponse events through, so that tapping on a foreground notification + // will take you to the relevant report. + if (AppState.currentState === 'active') { + // eslint-disable-next-line max-len + console.debug('[PUSH_NOTIFICATION] Push received while app is in foreground, not executing any callback.'); + return; + } + + pushNotificationEventCallback(EventType.PushReceived, notification); + }); + + // Note: the NotificationResponse event has a nested PushReceived event, + // so event.notification refers to the same thing as notification above ^ + UrbanAirship.addListener(EventType.NotificationResponse, (event) => { + console.debug('RORY_DEBUG NotificationResponse callback executed'); + pushNotificationEventCallback(EventType.NotificationResponse, event.notification); + }); + }); } /** From d7ed1efeed33f83cdea759fd99d679208ae5b3c2 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Mon, 28 Jun 2021 19:23:51 -0700 Subject: [PATCH 16/17] Remove debug logs --- src/libs/Notification/PushNotification/index.native.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libs/Notification/PushNotification/index.native.js b/src/libs/Notification/PushNotification/index.native.js index e48d3d3dcdc8..789819c0a822 100644 --- a/src/libs/Notification/PushNotification/index.native.js +++ b/src/libs/Notification/PushNotification/index.native.js @@ -74,8 +74,6 @@ function register(accountID) { // Setup event listeners UrbanAirship.addListener(EventType.PushReceived, (notification) => { - console.debug('RORY_DEBUG PushReceived callback executed'); - // If a push notification is received while the app is in foreground, // we'll assume pusher is connected so we'll ignore is and not fetch the same data twice. if (AppState.currentState === 'active') { @@ -90,7 +88,6 @@ function register(accountID) { // Note: the NotificationResponse event has a nested PushReceived event, // so event.notification refers to the same thing as notification above ^ UrbanAirship.addListener(EventType.NotificationResponse, (event) => { - console.debug('RORY_DEBUG NotificationResponse callback executed'); pushNotificationEventCallback(EventType.NotificationResponse, event.notification); }); }); From 6bf9df63b7623a73b9642cd1ab7f790e3a242c68 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Fri, 2 Jul 2021 15:36:47 -0700 Subject: [PATCH 17/17] Commit working draft to save for later --- android/app/build.gradle | 14 +++-- android/app/src/main/AndroidManifest.xml | 3 +- .../src/main/assets/airshipconfig.properties | 6 +- package-lock.json | 6 +- package.json | 2 +- src/CONST.js | 6 ++ src/Expensify.js | 31 +-------- .../PushNotification/index.native.js | 45 +++++++------ src/libs/actions/Report.js | 16 ++++- src/pages/ReportDetailsPage.js | 7 ++- src/setup/index.desktop.js | 19 ------ src/setup/index.native.js | 4 -- src/setup/index.website.js | 63 ------------------- 13 files changed, 69 insertions(+), 153 deletions(-) delete mode 100644 src/setup/index.desktop.js delete mode 100644 src/setup/index.native.js delete mode 100644 src/setup/index.website.js diff --git a/android/app/build.gradle b/android/app/build.gradle index 5d2c429a6b75..0f6ed20eb937 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -161,11 +161,11 @@ android { } signingConfigs { release { - if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) { - storeFile file(MYAPP_UPLOAD_STORE_FILE) - storePassword MYAPP_UPLOAD_STORE_PASSWORD - keyAlias MYAPP_UPLOAD_KEY_ALIAS - keyPassword MYAPP_UPLOAD_KEY_PASSWORD + if (project.hasProperty('RORY_TEST_KEYSTORE_FILE')) { + storeFile file(RORY_TEST_KEYSTORE_FILE) + storePassword RORY_TEST_STORE_PASSWORD + keyAlias RORY_TEST_KEY_ALIAS + keyPassword RORY_TEST_KEY_PASSWORD } } debug { @@ -200,6 +200,10 @@ android { } } + + lintOptions { + checkReleaseBuilds false + } } dependencies { diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 95162a30af5a..0b51d3987505 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -22,7 +22,8 @@ android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" - android:theme="@style/AppTheme"> + android:theme="@style/AppTheme" + android:debuggable="true"> { - listenToStorageEvents(onStorageEvent); - }, -}); -Onyx.registerLogger(({level, message}) => { - if (level === 'alert') { - Log.alert(message, 0, {}, false); - } else { - Log.client(message); - } -}); - const propTypes = { /* Onyx Props */ diff --git a/src/libs/Notification/PushNotification/index.native.js b/src/libs/Notification/PushNotification/index.native.js index 789819c0a822..c78dc7435451 100644 --- a/src/libs/Notification/PushNotification/index.native.js +++ b/src/libs/Notification/PushNotification/index.native.js @@ -48,6 +48,31 @@ function pushNotificationEventCallback(eventType, notification) { action(payload); } +/** + * Register push notification callbacks. This is separate from namedUser registration because it needs to be executed + * from a headless JS process, outside of any react lifecycle. + */ +function init() { + // Setup event listeners + UrbanAirship.addListener(EventType.PushReceived, (notification) => { + // If a push notification is received while the app is in foreground, + // we'll assume pusher is connected so we'll ignore is and not fetch the same data twice. + if (AppState.currentState === 'active') { + // eslint-disable-next-line max-len + console.debug('[PUSH_NOTIFICATION] Push received while app is in foreground, not executing any callback.'); + return; + } + + pushNotificationEventCallback(EventType.PushReceived, notification); + }); + + // Note: the NotificationResponse event has a nested PushReceived event, + // so event.notification refers to the same thing as notification above ^ + UrbanAirship.addListener(EventType.NotificationResponse, (event) => { + pushNotificationEventCallback(EventType.NotificationResponse, event.notification); + }); +} + /** * Register this device for push notifications for the given accountID. * @@ -71,25 +96,6 @@ function register(accountID) { console.debug(`[PUSH_NOTIFICATIONS] Subscribing to notifications for account ID ${accountID}`); UrbanAirship.setNamedUser(accountID.toString()); } - - // Setup event listeners - UrbanAirship.addListener(EventType.PushReceived, (notification) => { - // If a push notification is received while the app is in foreground, - // we'll assume pusher is connected so we'll ignore is and not fetch the same data twice. - if (AppState.currentState === 'active') { - // eslint-disable-next-line max-len - console.debug('[PUSH_NOTIFICATION] Push received while app is in foreground, not executing any callback.'); - return; - } - - pushNotificationEventCallback(EventType.PushReceived, notification); - }); - - // Note: the NotificationResponse event has a nested PushReceived event, - // so event.notification refers to the same thing as notification above ^ - UrbanAirship.addListener(EventType.NotificationResponse, (event) => { - pushNotificationEventCallback(EventType.NotificationResponse, event.notification); - }); }); } @@ -144,6 +150,7 @@ function onSelected(notificationType, callback) { } export default { + init, register, deregister, onReceived, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index e3527ade776b..35904c5d2926 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -514,9 +514,13 @@ function updateReportActionMessage(reportID, sequenceNumber, message) { * * @param {Number} reportID * @param {Object} reportAction - * @param {String} notificationPreference On what cadence the user would like to be notified + * @param {String} [notificationPreference] On what cadence the user would like to be notified */ -function updateReportWithNewAction(reportID, reportAction, notificationPreference) { +function updateReportWithNewAction( + reportID, + reportAction, + notificationPreference = CONST.NOTIFICATION_PREFERENCE.ALWAYS, +) { const newMaxSequenceNumber = reportAction.sequenceNumber; const isFromCurrentUser = reportAction.actorAccountID === currentUserAccountID; const initialLastReadSequenceNumber = lastReadSequenceNumbers[reportID] || 0; @@ -715,9 +719,14 @@ function subscribeToUserEvents() { {error, pusherChannelName, eventName: Pusher.TYPE.REPORT_TOGGLE_PINNED}, ); }); +} +/** + * Setup reportComment push notification callbacks. + */ +function subscribeToReportCommentPushNotifications() { PushNotification.onReceived(PushNotification.TYPE.REPORT_COMMENT, ({reportID, reportAction}) => { - Log.info('[Report] Handled event sent by Airship', true, {reportID}); + Log.info('[RORY_DEBUG][Report] Handled event sent by Airship', true, {reportID}); updateReportWithNewAction(reportID, reportAction); }); @@ -1293,6 +1302,7 @@ export { setNewMarkerPosition, subscribeToReportTypingEvents, subscribeToUserEvents, + subscribeToReportCommentPushNotifications, unsubscribeFromReportChannel, saveReportComment, broadcastUserIsTyping, diff --git a/src/pages/ReportDetailsPage.js b/src/pages/ReportDetailsPage.js index 01c7ff98d9fe..16d5fefec4e9 100644 --- a/src/pages/ReportDetailsPage.js +++ b/src/pages/ReportDetailsPage.js @@ -21,6 +21,7 @@ import {updateNotificationPreference} from '../libs/actions/Report'; import {Users} from '../components/Icon/Expensicons'; import ROUTES from '../ROUTES'; import MenuItem from '../components/MenuItem'; +import CONST from '../CONST'; const propTypes = { ...withLocalizePropTypes, @@ -72,16 +73,16 @@ class ReportDetailsPage extends Component { this.notificationPreferencesOptions = { default: { - value: 'always', + value: CONST.NOTIFICATION_PREFERENCE.ALWAYS, label: props.translate('reportDetailsPage.always'), }, daily: { - value: 'daily', + value: CONST.NOTIFICATION_PREFERENCE.DAILY, label: props.translate('reportDetailsPage.daily'), }, mute: { - value: 'mute', + value: CONST.NOTIFICATION_PREFERENCE.MUTE, label: props.translate('reportDetailsPage.mute'), }, }; diff --git a/src/setup/index.desktop.js b/src/setup/index.desktop.js deleted file mode 100644 index 67c07723fd64..000000000000 --- a/src/setup/index.desktop.js +++ /dev/null @@ -1,19 +0,0 @@ -import {AppRegistry} from 'react-native'; -import {ipcRenderer} from 'electron'; -import Config from '../CONFIG'; -import LocalNotification from '../libs/Notification/LocalNotification'; -import DateUtils from '../libs/DateUtils'; - - -export default function () { - AppRegistry.runApplication(Config.APP_NAME, { - rootTag: document.getElementById('root'), - }); - - ipcRenderer.on('update-downloaded', () => { - LocalNotification.showUpdateAvailableNotification(); - }); - - // Start current date updater - DateUtils.startCurrentDateUpdater(); -} diff --git a/src/setup/index.native.js b/src/setup/index.native.js deleted file mode 100644 index 20469e3101ec..000000000000 --- a/src/setup/index.native.js +++ /dev/null @@ -1,4 +0,0 @@ -// No additional setup required for native platforms -export default function () { - return null; -} diff --git a/src/setup/index.website.js b/src/setup/index.website.js deleted file mode 100644 index a5c603188451..000000000000 --- a/src/setup/index.website.js +++ /dev/null @@ -1,63 +0,0 @@ -import {AppRegistry} from 'react-native'; -import checkForUpdates from '../libs/checkForUpdates'; -import Config from '../CONFIG'; -import HttpUtils from '../libs/HttpUtils'; -import DateUtils from '../libs/DateUtils'; -import {version as currentVersion} from '../../package.json'; -import Visibility from '../libs/Visibility'; - -/** - * Download the latest app version from the server, and if it is different than the current one, - * then refresh. If the page is visibile, prompt the user to refresh. - * - */ -function webUpdate() { - HttpUtils.download('version.json') - .then(({version}) => { - if (version !== currentVersion) { - if (!Visibility.isVisible()) { - // Page is hidden, refresh immediately - window.location.reload(true); - return; - } - - // Prompt user to refresh the page - if (window.confirm('Refresh the page to get the latest updates!')) { - window.location.reload(true); - } - } - }); -} - -/** - * Create an object whose shape reflects the callbacks used in checkForUpdates. - * - * @returns {Object} - */ -const webUpdater = () => ({ - init: () => { - // We want to check for updates and refresh the page if necessary when the app is backgrounded. - // That way, it will auto-update silently when they minimize the page, - // and we don't bug the user any more than necessary :) - window.addEventListener('visibilitychange', () => { - if (!Visibility.isVisible()) { - webUpdate(); - } - }); - }, - update: () => webUpdate(), -}); - -export default function () { - AppRegistry.runApplication(Config.APP_NAME, { - rootTag: document.getElementById('root'), - }); - - // When app loads, get current version (production only) - if (Config.IS_IN_PRODUCTION) { - checkForUpdates(webUpdater()); - } - - // Start current date updater - DateUtils.startCurrentDateUpdater(); -}